Skip to content

Commit

Permalink
Merge pull request #462 from nodejitsu/preacher
Browse files Browse the repository at this point in the history
New logs with streaming!
  • Loading branch information
mmalecki committed Aug 16, 2013
2 parents 6b41f25 + 55e158e commit d5292ed
Show file tree
Hide file tree
Showing 5 changed files with 416 additions and 450 deletions.
154 changes: 95 additions & 59 deletions lib/jitsu/commands/logs.js
Expand Up @@ -6,6 +6,7 @@
*/

var jitsu = require('../../jitsu'),
util = require('util'),
dateformat = require('dateformat'),
logs = exports,
utile = jitsu.common;
Expand All @@ -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'
];

//
Expand Down Expand Up @@ -116,6 +150,7 @@ logs.app = function (appName, amount, callback) {
}

jitsu.log.info('Listing logs for ' + appName.magenta);

putLogs(results, appName, amount);
callback();
});
Expand All @@ -132,7 +167,7 @@ logs.app = function (appName, amount, callback) {
});
}

amount = amount || 100;
amount = amount || 10;

if (!appName) {
getAppName(function (err, name) {
Expand Down Expand Up @@ -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
//
Expand All @@ -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));
}
});
}
}
7 changes: 6 additions & 1 deletion lib/jitsu/config.js
Expand Up @@ -59,7 +59,12 @@ var defaults = {
root: process.env.HOME,
timeout: 4 * 60 * 1000,
tmproot: path.join(process.env.HOME, '.jitsu/tmp'),
userconfig: '.jitsuconf'
userconfig: '.jitsuconf',
logs: {
host: "logs.nodejitsu.com",
port: 443,
protocol: "https"
}
};

Object.defineProperty(defaults, 'remoteUri', {
Expand Down
4 changes: 2 additions & 2 deletions lib/jitsu/package.js
Expand Up @@ -304,7 +304,7 @@ package.write = function (pkg, dir, create, callback) {
policeDependencies(pkg);

jitsu.inspect.putObject(pkg, 2);

return jitsu.argv.release
? doWrite(null, true)
: jitsu.prompt.confirm('Is this ' + 'ok?'.green.bold, { default: 'yes'}, doWrite);
Expand Down Expand Up @@ -619,7 +619,7 @@ package.properties = function (dir) {
unique: false,
message: 'engines',
conform: semver.validRange,
default: '0.8.x'
default: '0.10.x'
}
];
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -30,7 +30,7 @@
"fstream-npm": "0.1.4",
"ladder": "0.0.0",
"npm": "1.3.4",
"nodejitsu-api": "0.4.7",
"nodejitsu-api": "0.5.0",
"opener": "1.3.x",
"pkginfo": "0.3.0",
"progress": "0.1.0",
Expand Down

0 comments on commit d5292ed

Please sign in to comment.