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

#! /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)
}