Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 95 additions & 59 deletions lib/jitsu/commands/logs.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading