SIGN IN SIGN UP
Unitech / pm2 UNCLAIMED

Node.js Production Process Manager with a built-in Load Balancer.

0 0 698 JavaScript
2015-06-11 14:44:21 +02:00
var fs = require('fs'),
2015-06-12 12:31:46 +02:00
util = require('util'),
2015-06-11 14:44:21 +02:00
chalk = require('chalk'),
CLI = require('./CLI.js'),
moment = require('moment');
2013-05-21 18:27:49 +08:00
2015-06-10 17:23:25 +02:00
var Log = module.exports = {};
2014-12-04 21:48:05 +08:00
2014-06-13 16:11:43 +02:00
/**
2014-12-04 18:02:31 +08:00
* Tail logs from file stream.
2015-06-10 17:23:25 +02:00
* @param {Object} apps_list
2014-12-04 18:02:31 +08:00
* @param {Number} lines
2015-06-10 17:23:25 +02:00
* @param {Boolean} raw
* @param {Function} callback
* @return
2014-06-13 16:11:43 +02:00
*/
2015-06-09 11:23:32 +02:00
2015-06-10 17:23:25 +02:00
Log.tail = function(apps_list, lines, raw, callback) {
2015-06-10 19:13:35 +02:00
if (lines === 0 || apps_list.length === 0)
return callback && callback();
var count = 0;
2015-06-19 13:43:08 +02:00
var getLastLines = function (filename, lines, callback) {
var chunk = '';
2015-08-24 16:10:50 +02:00
var size = Math.max(0, fs.statSync(filename).size - (lines * 200));
2015-06-19 13:43:08 +02:00
var fd = fs.createReadStream(filename, {start : size});
fd.on('data', function(data) { chunk += data.toString(); });
fd.on('end', function() {
chunk = chunk.split('\n').slice(-(lines+1));
chunk.pop();
callback(chunk);
});
};
apps_list.sort(function(a, b) {
return (fs.existsSync(a.path) ? fs.statSync(a.path).mtime.valueOf() : 0) -
(fs.existsSync(b.path) ? fs.statSync(b.path).mtime.valueOf() : 0);
});
2015-06-10 19:13:35 +02:00
apps_list.forEach(function(app, index) {
if (fs.existsSync(app.path || '')) {
2015-06-19 13:47:20 +02:00
getLastLines(app.path, lines, function(output) {
output.forEach(function(out) {
if (!raw) {
if (app.type === 'out') process.stdout.write(chalk.bold['green'](app.app_name + ' (out): '));
else if (app.type === 'err') process.stdout.write(chalk.bold['red'](app.app_name + ' (err): '));
else process.stdout.write(chalk.bold['blue']('PM2:') + ' ');
}
console.log(out);
2015-06-10 19:13:35 +02:00
});
2015-06-19 13:47:20 +02:00
if (output.length)
process.stdout.write('\n');
++count;
if (count === apps_list.length)
callback && callback();
2015-06-10 17:23:25 +02:00
});
2015-06-10 19:13:35 +02:00
}
2015-06-19 13:43:08 +02:00
else {
++count;
if (count === apps_list.length)
callback && callback();
}
2013-05-21 18:27:49 +08:00
});
2014-12-04 18:02:31 +08:00
};
2015-06-08 19:03:38 +02:00
2015-06-10 19:13:35 +02:00
/**
* Stream logs in realtime from the bus eventemitter.
* @param {String} id
* @param {Boolean} raw
* @return
*/
2015-06-29 15:47:00 +02:00
Log.stream = function(id, raw, timestamp, exclusive) {
2015-06-11 11:40:26 +02:00
2015-06-12 12:31:46 +02:00
if (!raw)
console.log(chalk['inverse'](util.format.call(this, '[PM2] Streaming realtime logs for [%s] process%s', id, id === 'all' ? 'es' : '', '\n')));
2015-06-10 17:23:25 +02:00
CLI.launchBus(function(err, bus) {
2015-06-10 13:07:41 +02:00
2015-06-10 17:23:25 +02:00
bus.on('log:*', function(type, data) {
2015-06-29 15:47:00 +02:00
if (id !== 'all'
&& data.process.name != id
&& data.process.pm_id != id)
2015-06-26 18:42:29 +02:00
return;
2015-06-29 15:47:00 +02:00
if ((type === 'out' && exclusive === 'err')
|| (type === 'err' && exclusive === 'out')
|| (type === 'PM2' && exclusive !== false))
2015-06-10 19:13:35 +02:00
return;
2015-06-10 17:23:25 +02:00
var name = data.process.name + '-' + data.process.pm_id;
2015-06-10 13:07:41 +02:00
2015-06-10 17:23:25 +02:00
if (!raw) {
2015-06-11 15:19:48 +02:00
if (timestamp) process.stdout.write(chalk['dim'](chalk['inverse'](chalk.bold['grey'](moment().format(timestamp) + ' '))));
if (type === 'out') process.stdout.write(chalk['inverse'](chalk.bold['green'](name)) + ' ');
else if (type === 'err') process.stdout.write(chalk['inverse'](chalk.bold['red'](name)) + ' ');
2015-06-11 14:44:21 +02:00
else if (!raw && (id === 'all' || id === 'PM2')) process.stdout.write(chalk['inverse'](chalk.bold['blue']('PM2')) + ' ');
2015-06-10 17:23:25 +02:00
}
if (type === 'PM2' && raw)
return;
2015-06-26 12:40:23 +02:00
process.stdout.write(data.data ? util.format(data.data) : '');
2015-06-10 17:23:25 +02:00
});
2015-06-10 13:07:41 +02:00
2015-06-10 17:23:25 +02:00
});
2015-06-10 13:07:41 +02:00
2015-06-10 17:23:25 +02:00
};