@@ -6,6 +6,7 @@
*/
var jitsu = require ( '../../jitsu' ) ,
util = require ( 'util' ) ,
dateformat = require ( 'dateformat' ) ,
logs = exports ,
utile = jitsu . common ;
@@ -15,69 +16,102 @@ logs.usage = [
'The default number of lines to show is 10' ,
'' ,
'Example usages:' ,
'jitsu logs all' ,
'jitsu logs all <number of lines to show>' ,
'jitsu logs tail' ,
'jitsu logs app <app name>' ,
'jitsu logs app <app name> <number of lines to show>'
] ;
//
// ### function all (callback)
// #### @callback {function } Continuation to pass control to when complete.
// Queries the log API and retrieves the logs for all of the user's apps
// ### function tail (appName, callback)
// #### @appName {string} the application to get the logs for
// #### @callback {function } Continuation to pass control when complete.
// Queries the log API using live streaming
//
logs . all = function ( amount , callback ) {
logs . tail = function ( appName , callback ) {
//
// This is defined so that it can get called once all the arguments are
// sorted out.
//
//
// Allows arbitrary amount of arguments
//
if ( arguments . length ) {
var args = utile . args ( arguments ) ;
callback = args . callback ;
amount = args [ 0 ] || null ;
appName = args [ 0 ] || null ;
}
if ( ! amount ) {
amount = 10 ;
}
function tail ( appName , callback ) {
jitsu . apps . view ( appName , function ( err ) {
if ( err ) {
return err . statusCode === 404
? callback ( new Error ( 'Application not found.' ) , true )
: callback ( err ) ;
}
jitsu . logs . byUser ( jitsu . config . get ( 'username' ) , amount , function ( err , apps ) {
if ( err ) {
return callback ( err ) ;
}
var amount = 10 ;
jitsu . logs . byApp ( appName , amount , function ( err , results ) {
if ( err ) {
return callback ( err ) ;
}
if ( apps . length === 0 ) {
jitsu . log . warn ( 'No logs for ' + jitsu . config . get ( 'username' ) . magenta + ' from timespan' ) ;
return callback ( ) ;
}
jitsu . log . info ( 'Listing logs for ' + appName . magenta ) ;
function sortLength ( lname , rname ) {
var llength = apps [ lname ] . data . length ,
rlength = apps [ rname ] . data . length ;
putLogs ( results , appName , amount ) ;
if ( llength === rlength ) {
return 0 ;
}
jitsu . logs . live ( appName , function ( err , socket ) {
if ( err ) return callback ( err ) ;
return llength > rlength ? 1 : - 1 ;
}
socket . on ( 'data' , printLog ) ;
socket . on ( 'error' , function ( err ) {
return callback ( err ) ;
} ) ;
} ) ;
} ) ;
} ) ;
}
Object . keys ( apps ) . sort ( sortLength ) . forEach ( function ( app ) {
console . log ( 'App: ' . grey + app . magenta ) ;
putLogs ( apps [ app ] , app , amount , true ) ;
function getAppName ( callback ) {
jitsu . package . read ( process . cwd ( ) , function ( err , pkg ) {
if ( ! err ) {
jitsu . log . info ( 'Attempting to load logs for ' + ( process . cwd ( ) + '/package.json' ) . grey ) ;
return callback ( null , pkg . name ) ;
}
callback ( err ) ;
} ) ;
}
callback ( ) ;
} ) ;
if ( ! appName ) {
getAppName ( function ( err , name ) {
if ( err ) {
jitsu . commands . list ( function ( ) {
jitsu . log . info ( 'Which application to view ' + 'logs' . magenta + ' for?' ) ;
jitsu . prompt . get ( [ "app name" ] , function ( err , result ) {
if ( err ) {
jitsu . log . error ( 'Prompt error:' ) ;
return callback ( err ) ;
}
appName = result [ "app name" ] ;
tail ( appName , callback ) ;
} ) ;
} )
} else {
tail ( name , callback ) ;
}
} ) ;
} else {
tail ( appName , callback ) ;
}
} ;
logs . all . usage = [
'Print the logs from all applications. The default number of' ,
'lines to show is 10.' ,
'jits logs all <number of lines to show>' ,
logs . tail . usage = [
'The `jitsu logs tail` command will display logs in a live mode' ,
'jitsu logs tail <app name>' ,
'' ,
'Example usage :' ,
'jitsu logs all ' ,
'jitsu logs all 5 '
'Example usages :' ,
'jitsu logs tail ' ,
'jitsu logs tail app '
] ;
//
@@ -116,6 +150,7 @@ logs.app = function (appName, amount, callback) {
}
jitsu . log . info ( 'Listing logs for ' + appName . magenta ) ;
putLogs ( results , appName , amount ) ;
callback ( ) ;
} ) ;
@@ -132,7 +167,7 @@ logs.app = function (appName, amount, callback) {
} ) ;
}
amount = amount || 100 ;
amount = amount || 10 ;
if ( ! appName ) {
getAppName ( function ( err , name ) {
@@ -175,7 +210,7 @@ logs.app.usage = [
// #### @showApp {boolean} Value indicating if the app name should be output.
// Parses, formats, and outputs the specified `results` to the user.
//
function putLogs ( results , appName , amount , showApp ) { //TODO: utilize amount and showApp
function putLogs ( results , appName ) {
//
// Allows arbitrary amount of arguments
//
@@ -192,31 +227,32 @@ function putLogs (results, appName, amount, showApp) { //TODO: utilize amount an
appName = appName . split ( '/' ) [ 1 ] ;
}
results . data = results . data . filter ( function ( item ) {
return item . json && item . json . hasOwnProperty ( 'message' ) ;
} ) ;
if ( results . data . length === 0 ) {
if ( ! results || results . length === 0 ) {
return jitsu . log . warn ( 'No logs for ' + appName . magenta + ' in specified timespan' ) ;
}
var logLength = jitsu . config . get ( 'loglength' ) ,
logged = 0 ;
function sort ( first , second ) {
return new Date ( first . timestamp ) - new Date ( second . timestamp ) ;
}
results . reverse ( ) . forEach ( printLog ) ;
}
results . data . sort ( sort ) . forEach ( function ( datum ) {
if ( datum . json && datum . json . message !== null && datum . json . app !== null && RegExp ( '^' + appName + '$' ) . test ( datum . json . app ) ) {
// '[' + datum.json.app.magenta + ']
datum . json . message . split ( '\n' ) . forEach ( function ( line ) {
var now = new Date ( datum . timestamp ) ;
now = dateformat ( now , "mm/dd HH:MM:ss Z" ) ;
if ( line . length ) {
console . log ( '[' + now . toString ( ) . yellow + '] ' + line ) ;
}
} ) ;
function printLog ( datum ) {
if ( datum . description && datum . description !== null ) {
if ( jitsu . argv . raw ) {
return console . log ( datum ) ;
}
} ) ;
datum . description . split ( '\n' ) . forEach ( function ( line ) {
var now = new Date ( datum . time * 1000 ) ;
now = dateformat ( now , "mm/dd HH:MM:ss Z" ) ;
var type = ( datum . service === 'logs/stderr' ) ? "err" . red : "out" . green ;
if ( line . length ) {
console . log ( util . format ( '[%s][%s] %s' , now . toString ( ) . yellow , type , line ) ) ;
}
} ) ;
}
}