You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.1 KiB
157 lines
3.1 KiB
#! /usr/bin/env node |
|
|
|
'use strict' |
|
|
|
var split = require('split2') |
|
var Parse = require('fast-json-parse') |
|
var chalk = require('chalk') |
|
|
|
var levels = { |
|
60: 'FATAL', |
|
50: 'ERROR', |
|
40: 'WARN', |
|
30: 'INFO', |
|
20: 'DEBUG', |
|
10: 'TRACE' |
|
} |
|
|
|
var standardKeys = [ |
|
'pid', |
|
'hostname', |
|
'name', |
|
'level', |
|
'msg', |
|
'time', |
|
'v' |
|
] |
|
|
|
function withSpaces (value) { |
|
var lines = value.split('\n') |
|
for (var i = 1; i < lines.length; i++) { |
|
lines[i] = ' ' + lines[i] |
|
} |
|
return lines.join('\n') |
|
} |
|
|
|
function filter (value) { |
|
var keys = Object.keys(value) |
|
var result = '' |
|
|
|
for (var i = 0; i < keys.length; i++) { |
|
if (standardKeys.indexOf(keys[i]) < 0) { |
|
result += ' ' + keys[i] + ': ' + withSpaces(JSON.stringify(value[keys[i]], null, 2)) + '\n' |
|
} |
|
} |
|
|
|
return result |
|
} |
|
|
|
function isPinoLine (line) { |
|
return line && |
|
line.hasOwnProperty('hostname') && |
|
line.hasOwnProperty('pid') && |
|
(line.hasOwnProperty('v') && line.v === 1) |
|
} |
|
|
|
function pretty (opts) { |
|
var timeTransOnly = opts && opts.timeTransOnly |
|
var formatter = opts && opts.formatter |
|
var levelFirst = opts && opts.levelFirst |
|
|
|
var stream = split(mapLine) |
|
var ctx |
|
var levelColors |
|
|
|
var pipe = stream.pipe |
|
|
|
stream.pipe = function (dest, opts) { |
|
ctx = new chalk.constructor({ |
|
enabled: !!(chalk.supportsColor && dest.isTTY) |
|
}) |
|
|
|
levelColors = { |
|
60: ctx.bgRed, |
|
50: ctx.red, |
|
40: ctx.yellow, |
|
30: ctx.green, |
|
20: ctx.blue, |
|
10: ctx.grey |
|
} |
|
|
|
pipe.call(stream, dest, opts) |
|
} |
|
|
|
return stream |
|
|
|
function mapLine (line) { |
|
var parsed = new Parse(line) |
|
var value = parsed.value |
|
|
|
if (parsed.err || !isPinoLine(value)) { |
|
// pass through |
|
return line + '\n' |
|
} |
|
|
|
if (formatter) { |
|
return opts.formatter(parsed.value) + '\n' |
|
} |
|
|
|
if (timeTransOnly) { |
|
value.time = asISODate(value.time) |
|
return JSON.stringify(value) + '\n' |
|
} |
|
|
|
line = (levelFirst) |
|
? asColoredLevel(value) + ' [' + asISODate(value.time) + ']' |
|
: '[' + asISODate(value.time) + '] ' + asColoredLevel(value) |
|
|
|
line += ' (' |
|
if (value.name) { |
|
line += value.name + '/' |
|
} |
|
line += value.pid + ' on ' + value.hostname + ')' |
|
line += ': ' |
|
if (value.msg) { |
|
line += ctx.cyan(value.msg) |
|
} |
|
line += '\n' |
|
if (value.type === 'Error') { |
|
line += ' ' + withSpaces(value.stack) + '\n' |
|
} else { |
|
line += filter(value) |
|
} |
|
return line |
|
} |
|
|
|
function asISODate (time) { |
|
return new Date(time).toISOString() |
|
} |
|
|
|
function asColoredLevel (value) { |
|
return levelColors[value.level](levels[value.level]) |
|
} |
|
} |
|
|
|
module.exports = pretty |
|
|
|
if (require.main === module) { |
|
if (arg('-h') || arg('--help')) { |
|
usage().pipe(process.stdout) |
|
} else if (arg('-v') || arg('--version')) { |
|
console.log(require('./package.json').version) |
|
} else { |
|
process.stdin.pipe(pretty({ |
|
timeTransOnly: arg('-t'), |
|
levelFirst: arg('-l') |
|
})).pipe(process.stdout) |
|
} |
|
} |
|
|
|
function usage () { |
|
return require('fs') |
|
.createReadStream(require('path').join(__dirname, 'usage.txt')) |
|
} |
|
|
|
function arg (s) { |
|
return !!~process.argv.indexOf(s) |
|
}
|
|
|