-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor Log, in a tiny and light way.
- Loading branch information
Showing
3 changed files
with
86 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,78 @@ | ||
// | ||
// Display a file in streaming | ||
// | ||
var fs = require('fs'); | ||
var fs = require('fs'), | ||
chalk = require('chalk'), | ||
spawn = require('child_process').spawn; | ||
|
||
var colors = [ | ||
'\x1B[34m', // blue | ||
'\x1B[36m', // cyan | ||
'\x1B[32m', // green | ||
'\x1B[35m', // magenta | ||
'\x1B[31m', // red | ||
'\x1B[90m', // grey | ||
'\x1B[33m' // yellow | ||
]; | ||
var Log = module.exports = {}; | ||
|
||
var gl_idx = 0; | ||
var db = []; | ||
// Empty line. | ||
var re_blank = /^[\s\r\t]*$/; | ||
|
||
var Log = module.exports = {}; | ||
/** | ||
* Styles of title and content. | ||
* @type {{def: {title: string, content: string}, out: {title: string, content: string}, err: {title: string, content: string}}} | ||
*/ | ||
Log.styles = { | ||
def: {title: 'blue', content: 'grey'}, | ||
out: {title: 'green', content: 'black'}, | ||
err: {title: 'red', content: 'red'} | ||
}; | ||
|
||
/** | ||
* Description | ||
* @method stream | ||
* @param {} path | ||
* @param {} title | ||
* @return | ||
* Tail logs from file stream. | ||
* @param {String|Object} path | ||
* @param {String} title | ||
* @param {Number} lines | ||
* @returns {*} | ||
*/ | ||
Log.stream = function(path, title, read_bytes) { | ||
if (title === undefined) | ||
title = gl_idx; | ||
Log.stream = function(path, title, lines){ | ||
var type = 'def'; | ||
|
||
try { | ||
var currSize = fs.statSync(path).size - (typeof(read_bytes) === 'undefined' ? 1000 : read_bytes); | ||
currSize = currSize > 0 ? currSize : 0; | ||
} catch(e) { | ||
if (e.code == 'ENOENT') | ||
console.log('%s with %s file not found', title, path); | ||
return false; | ||
// Make options in the right position. | ||
if (typeof path == 'object') { | ||
type = !path.type ? 'def' : path.type; | ||
path = path.path; | ||
} | ||
if (typeof title == 'number') { | ||
lines = title; | ||
title = null; | ||
} | ||
lines = lines || 20; | ||
|
||
var odb = db[title] = {color : colors[gl_idx++ % colors.length], l : 0}; | ||
title = '[' + (title || 'PM2') + ']'; | ||
|
||
var _stream = function() { | ||
fs.stat(path, function(err, stat) { | ||
var prevSize = stat.size; | ||
var style = Log.styles[type] || 'blue'; | ||
|
||
if (currSize > prevSize) return true; | ||
// Check file exist or not. | ||
if (!fs.existsSync(path)) { | ||
return console.info(chalk.bold.red(title), chalk.red('Log file "' + path + '" does not exist.')); | ||
} | ||
|
||
var rstream = fs.createReadStream(path, { | ||
encoding : 'utf8', | ||
start : currSize, | ||
end : prevSize | ||
}); | ||
// Tail logs. | ||
var tail = spawn('tail', ['-f', '-n', lines, path], { | ||
// Kill the spawned process by `tail.kill('SIGTERM')`. | ||
killSignal: 'SIGTERM', | ||
stdio : [null, 'pipe', 'pipe'] | ||
}); | ||
|
||
rstream.on('data', function(data) { | ||
print_data(odb, title, data); | ||
}); | ||
// Use utf8 encoding. | ||
tail.stdio.forEach(function(stdio){ | ||
stdio.setEncoding('utf8'); | ||
}); | ||
|
||
currSize = stat.size; | ||
return true; | ||
// stdout. | ||
tail.stdout.on('data', function(data){ | ||
data.split(/\n/).forEach(function(line){ | ||
if (!re_blank.test(line)) { | ||
console.info(chalk.bold[style.title](title), chalk[style.content](line)); | ||
} | ||
}); | ||
}; | ||
|
||
_stream(); | ||
|
||
fs.watch(path, function(ev, filename) { | ||
if (ev == 'rename') | ||
return console.error('Renaming file ?'); | ||
|
||
_stream(); | ||
return true; | ||
}); | ||
}; | ||
|
||
// | ||
// Privates | ||
// | ||
/** | ||
* Description | ||
* @method print_data | ||
* @param {} odb | ||
* @param {} title | ||
* @param {} data | ||
* @return | ||
*/ | ||
function print_data(odb, title, data) { | ||
var lines = data.split('\n'); | ||
|
||
lines.forEach(function(l) { | ||
if (l) | ||
console.log(odb.color + '[%s]\x1B[39m %s', title, l); | ||
// handle error. | ||
tail.stderr.on('data', function(data){ | ||
tail.disconnect(); | ||
console.info(chalk.bold.red(title), chalk.red(data.toString().replace(/\n/, ''))); | ||
}); | ||
} | ||
|
||
return tail; | ||
}; |