Socket
Socket
Sign inDemoInstall

pino-pretty

Package Overview
Dependencies
Maintainers
4
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pino-pretty - npm Package Compare versions

Comparing version 2.6.0 to 3.0.0-rc.1

lib/colors.js

278

index.js
'use strict'
const chalk = require('chalk')
const dateformat = require('dateformat')
// remove jsonParser once Node 6 is not supported anymore
const jsonParser = require('fast-json-parse')
const jmespath = require('jmespath')
const stringifySafe = require('fast-safe-stringify')
const colors = require('./lib/colors')
const { ERROR_LIKE_KEYS, MESSAGE_KEY } = require('./lib/constants')
const {
isObject,
prettifyErrorLog,
prettifyLevel,
prettifyMessage,
prettifyMetadata,
prettifyObject,
prettifyTime
} = require('./lib/utils')
const CONSTANTS = require('./lib/constants')
const levels = {
default: 'USERLVL',
60: 'FATAL',
50: 'ERROR',
40: 'WARN ',
30: 'INFO ',
20: 'DEBUG',
10: 'TRACE'
const bourne = require('bourne')
const jsonParser = input => {
try {
return { value: bourne.parse(input, { protoAction: 'remove' }) }
} catch (err) {
return { err }
}
}

@@ -25,6 +29,6 @@

crlf: false,
errorLikeObjectKeys: ['err', 'error'],
errorLikeObjectKeys: ERROR_LIKE_KEYS,
errorProps: '',
levelFirst: false,
messageKey: CONSTANTS.MESSAGE_KEY,
messageKey: MESSAGE_KEY,
translateTime: false,

@@ -35,28 +39,2 @@ useMetadata: false,

function isObject (input) {
return Object.prototype.toString.apply(input) === '[object Object]'
}
function isPinoLog (log) {
return log && (log.hasOwnProperty('v') && log.v === 1)
}
function formatTime (epoch, translateTime) {
const instant = new Date(epoch)
if (translateTime === true) {
return dateformat(instant, 'UTC:' + CONSTANTS.DATE_FORMAT)
} else {
const upperFormat = translateTime.toUpperCase()
return (!upperFormat.startsWith('SYS:'))
? dateformat(instant, 'UTC:' + translateTime)
: (upperFormat === 'SYS:STANDARD')
? dateformat(instant, CONSTANTS.DATE_FORMAT)
: dateformat(instant, translateTime.slice(4))
}
}
function nocolor (input) {
return input
}
module.exports = function prettyFactory (options) {

@@ -71,24 +49,3 @@ const opts = Object.assign({}, defaultOptions, options)

const color = {
default: nocolor,
60: nocolor,
50: nocolor,
40: nocolor,
30: nocolor,
20: nocolor,
10: nocolor,
message: nocolor
}
if (opts.colorize) {
const ctx = new chalk.constructor({ enabled: true, level: 3 })
color.default = ctx.white
color[60] = ctx.bgRed
color[50] = ctx.red
color[40] = ctx.yellow
color[30] = ctx.green
color[20] = ctx.blue
color[10] = ctx.grey
color.message = ctx.cyan
}
const colorizer = colors(opts.colorize)
const search = opts.search

@@ -103,3 +60,3 @@

log = parsed.value
if (parsed.err || !isPinoLog(log)) {
if (parsed.err) {
// pass through

@@ -112,2 +69,7 @@ return inputData + EOL

// Short-circuit for spec allowed primitive values.
if ([null, true, false].includes(log)) {
return `${log}\n`
}
if (search && !jmespath.search(log, search)) {

@@ -126,163 +88,65 @@ return

const standardKeys = [
'pid',
'hostname',
'name',
'level',
'time',
'v'
]
const prettifiedLevel = prettifyLevel({ log, colorizer })
const prettifiedMessage = prettifyMessage({ log, messageKey, colorizer })
const prettifiedMetadata = prettifyMetadata({ log })
const prettifiedTime = prettifyTime({ log, translateFormat: opts.translateTime })
if (opts.translateTime) {
log.time = formatTime(log.time, opts.translateTime)
let line = ''
if (opts.levelFirst && prettifiedLevel) {
line = `${prettifiedLevel}`
}
var line = log.time ? `[${log.time}]` : ''
const coloredLevel = levels.hasOwnProperty(log.level)
? color[log.level](levels[log.level])
: color.default(levels.default)
if (opts.levelFirst) {
line = `${coloredLevel} ${line}`
} else {
// If the line is not empty (timestamps are enabled) output it
// with a space after it - otherwise output the empty string
const lineOrEmpty = line && line + ' '
line = `${lineOrEmpty}${coloredLevel}`
if (prettifiedTime && line === '') {
line = `${prettifiedTime}`
} else if (prettifiedTime) {
line = `${line} ${prettifiedTime}`
}
if (log.name || log.pid || log.hostname) {
line += ' ('
if (log.name) {
line += log.name
if (!opts.levelFirst && prettifiedLevel) {
if (line.length > 0) {
line = `${line} ${prettifiedLevel}`
} else {
line = prettifiedLevel
}
}
if (log.name && log.pid) {
line += '/' + log.pid
} else if (log.pid) {
line += log.pid
}
if (prettifiedMetadata) {
line = `${line} ${prettifiedMetadata}:`
}
if (log.hostname) {
if (line.slice(-1) !== '(') {
line += ' '
}
line += 'on ' + log.hostname
}
if (line.endsWith(':') === false && line !== '') {
line += ':'
}
line += ')'
if (prettifiedMessage) {
line = `${line} ${prettifiedMessage}`
}
line += ': '
if (log[messageKey] && typeof log[messageKey] === 'string') {
line += color.message(log[messageKey])
if (line.length > 0) {
line += EOL
}
line += EOL
if (log.type === 'Error' && log.stack) {
const stack = log.stack
line += IDENT + joinLinesWithIndentation(stack) + EOL
let propsForPrint
if (errorProps && errorProps.length > 0) {
// don't need print these props for 'Error' object
const excludedProps = standardKeys.concat([messageKey, 'type', 'stack'])
if (errorProps[0] === '*') {
// print all log props excluding 'excludedProps'
propsForPrint = Object.keys(log).filter((prop) => excludedProps.indexOf(prop) < 0)
} else {
// print props from 'errorProps' only
// but exclude 'excludedProps'
propsForPrint = errorProps.filter((prop) => excludedProps.indexOf(prop) < 0)
}
for (var i = 0; i < propsForPrint.length; i++) {
const key = propsForPrint[i]
if (!log.hasOwnProperty(key)) continue
if (log[key] instanceof Object) {
// call 'filterObjects' with 'excludeStandardKeys' = false
// because nested property might contain property from 'standardKeys'
line += key + ': {' + EOL + filterObjects(log[key], '', errorLikeObjectKeys, false) + '}' + EOL
continue
}
line += key + ': ' + log[key] + EOL
}
}
const prettifiedErrorLog = prettifyErrorLog({
log,
errorLikeKeys: errorLikeObjectKeys,
errorProperties: errorProps,
ident: IDENT,
eol: EOL
})
line += prettifiedErrorLog
} else {
line += filterObjects(log, typeof log[messageKey] === 'string' ? messageKey : undefined, errorLikeObjectKeys)
const skipKeys = typeof log[messageKey] === 'string' ? [messageKey] : undefined
const prettifiedObject = prettifyObject({
input: log,
skipKeys,
errorLikeKeys: errorLikeObjectKeys,
eol: EOL,
ident: IDENT
})
line += prettifiedObject
}
return line
function joinLinesWithIndentation (value) {
const lines = value.split(/\r?\n/)
for (var i = 1; i < lines.length; i++) {
lines[i] = IDENT + lines[i]
}
return lines.join(EOL)
}
function filterObjects (value, messageKey, errorLikeObjectKeys, excludeStandardKeys) {
errorLikeObjectKeys = errorLikeObjectKeys || []
const keys = Object.keys(value)
const filteredKeys = []
if (messageKey) {
filteredKeys.push(messageKey)
}
if (excludeStandardKeys !== false) {
Array.prototype.push.apply(filteredKeys, standardKeys)
}
let result = ''
for (var i = 0; i < keys.length; i += 1) {
if (errorLikeObjectKeys.indexOf(keys[i]) !== -1 && value[keys[i]] !== undefined) {
const lines = stringifySafe(value[keys[i]], null, 2)
if (lines === undefined) continue
const arrayOfLines = (
IDENT + keys[i] + ': ' +
joinLinesWithIndentation(lines) +
EOL
).split('\n')
for (var j = 0; j < arrayOfLines.length; j += 1) {
if (j !== 0) {
result += '\n'
}
const line = arrayOfLines[j]
if (/^\s*"stack"/.test(line)) {
const matches = /^(\s*"stack":)\s*(".*"),?$/.exec(line)
if (matches && matches.length === 3) {
const indentSize = /^\s*/.exec(line)[0].length + 4
const indentation = ' '.repeat(indentSize)
result += matches[1] + '\n' + indentation + JSON.parse(matches[2]).replace(/\n/g, '\n' + indentation)
}
} else {
result += line
}
}
} else if (filteredKeys.indexOf(keys[i]) < 0) {
if (value[keys[i]] !== undefined) {
const lines = stringifySafe(value[keys[i]], null, 2)
if (lines !== undefined) {
result += IDENT + keys[i] + ': ' + joinLinesWithIndentation(lines) + EOL
}
}
}
}
return result
}
}
}

@@ -5,3 +5,36 @@ 'use strict'

DATE_FORMAT: 'yyyy-mm-dd HH:MM:ss.l o',
MESSAGE_KEY: 'msg'
ERROR_LIKE_KEYS: ['err', 'error'],
MESSAGE_KEY: 'msg',
LEVELS: {
default: 'USERLVL',
60: 'FATAL',
50: 'ERROR',
40: 'WARN ',
30: 'INFO ',
20: 'DEBUG',
10: 'TRACE'
},
LEVEL_NAMES: {
fatal: 60,
error: 50,
warn: 40,
info: 30,
debug: 20,
trace: 10
},
// Object keys that probably came from a logger like Pino or Bunyan.
LOGGER_KEYS: [
'pid',
'hostname',
'name',
'level',
'time',
'timestamp',
'v'
]
}
{
"name": "pino-pretty",
"version": "2.6.0",
"version": "3.0.0-rc.1",
"description": "Prettifier for Pino log lines",

@@ -34,5 +34,5 @@ "main": "index.js",

"args": "^5.0.0",
"bourne": "^1.1.2",
"chalk": "^2.3.2",
"dateformat": "^3.0.3",
"fast-json-parse": "^1.0.3",
"fast-safe-stringify": "^2.0.6",

@@ -39,0 +39,0 @@ "jmespath": "^0.15.0",

@@ -182,2 +182,3 @@ 'use strict'

// TODO: 2019-03-30 -- We don't really want the indentation in this case? Or at least some better formatting.
t.test('handles missing time', (t) => {

@@ -187,3 +188,3 @@ t.plan(1)

const formatted = pretty('{"hello":"world"}')
t.is(formatted, '{"hello":"world"}\n')
t.is(formatted, ' hello: "world"\n')
})

@@ -339,7 +340,14 @@

t.test('handles `null` input', (t) => {
t.plan(1)
t.test('handles spec allowed primitives', (t) => {
const pretty = prettyFactory()
const formatted = pretty(null)
let formatted = pretty(null)
t.is(formatted, 'null\n')
formatted = pretty(true)
t.is(formatted, 'true\n')
formatted = pretty(false)
t.is(formatted, 'false\n')
t.end()
})

@@ -354,9 +362,2 @@

t.test('handles `true` input', (t) => {
t.plan(1)
const pretty = prettyFactory()
const formatted = pretty(true)
t.is(formatted, 'true\n')
})
t.test('handles customLogLevel', (t) => {

@@ -527,3 +528,3 @@ t.plan(1)

chunk + '',
`[${epoch}] INFO (${pid} on ${hostname}): \n a: {\n "b": "c"\n }\n n: null\n`
`[${epoch}] INFO (${pid} on ${hostname}):\n a: {\n "b": "c"\n }\n n: null\n`
)

@@ -530,0 +531,0 @@ cb()

@@ -92,3 +92,3 @@ 'use strict'

t.is(lines.length, expected.length + 6)
t.is(lines[0], `[${epoch}] INFO (${pid} on ${hostname}): `)
t.is(lines[0], `[${epoch}] INFO (${pid} on ${hostname}):`)
t.match(lines[1], /\s{4}err: {/)

@@ -124,3 +124,3 @@ t.match(lines[2], /\s{6}"type": "Error",/)

t.is(lines.length, expected.length + 6)
t.is(lines[0], `[${epoch}] INFO (${pid} on ${hostname}): `)
t.is(lines[0], `[${epoch}] INFO (${pid} on ${hostname}):`)
t.match(lines[1], /\s{4}err: {$/)

@@ -155,3 +155,3 @@ t.match(lines[2], /\s{6}"type": "Error",$/)

t.is(lines.length, expected.length + 7)
t.is(lines[0], `[${epoch}] INFO (${pid} on ${hostname}): `)
t.is(lines[0], `[${epoch}] INFO (${pid} on ${hostname}):`)
t.match(lines[1], /\s{4}err: {/)

@@ -158,0 +158,0 @@ t.match(lines[2], /\s{6}"type": "Error",/)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc