Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
pino-pretty
Advanced tools
The pino-pretty npm package is a module that can be used to format logs produced by Pino, a Node.js logging library. It takes raw log lines in JSON format and transforms them into a more human-readable form. This is particularly useful during development when you need to quickly understand log output.
Pretty Printing
This feature allows you to format your logs in a more readable way, with options such as colorization for different log levels.
const pino = require('pino');
const pretty = require('pino-pretty');
const stream = pretty({ colorize: true });
const logger = pino(stream);
logger.info('This is a pretty-printed log message.');
Custom Log Formatting
Pino-pretty allows for custom log formatting, including options to translate timestamps and ignore certain fields.
const pino = require('pino');
const pretty = require('pino-pretty');
const stream = pretty({
translateTime: 'SYS:standard',
ignore: 'pid,hostname'
});
const logger = pino(stream);
logger.info('Custom formatted log message.');
Integration with Pino Logger
Pino-pretty can be seamlessly integrated with Pino logger to provide pretty-printing capabilities directly within the logger configuration.
const pino = require('pino');
const logger = pino({
prettyPrint: {
colorize: true
}
});
logger.info('Integrated pino-pretty with Pino logger.');
Bunyan is a simple and fast JSON logging library for node.js services. It comes with a CLI tool for pretty-printing bunyan log output. Compared to pino-pretty, Bunyan provides its own logging capabilities, whereas pino-pretty is specifically designed to format Pino logs.
Winston is a multi-transport async logging library for Node.js. It supports custom formatting and multiple logging transports. Unlike pino-pretty, which is focused on pretty-printing, Winston offers a broader set of logging features including transports for logging to various outputs.
Morgan is an HTTP request logger middleware for Node.js. It can format logs in predefined or custom formats. While morgan is used for logging HTTP requests in web applications, pino-pretty is used for general purpose log formatting.
This module provides a basic ndjson formatter to be used in development. If an incoming line looks like it could be a log line from an ndjson logger, in particular the Pino logging library, then it will apply extra formatting by considering things like the log level and timestamp.
A standard Pino log line like:
{"level":30,"time":1522431328992,"msg":"hello world","pid":42,"hostname":"foo","v":1}
Will format to:
[17:35:28.992] INFO (42): hello world
If you landed on this page due to the deprecation of the prettyPrint
option
of pino
, read the Programmatic Integration section.
Using the example script from the Pino module, we can see what the prettified logs will look like:
$ npm install -g pino-pretty
It is recommended to use pino-pretty
with pino
by piping output to the CLI tool:
node app.js | pino-pretty
--colorize
(-c
): Adds terminal color escape sequences to the output.--colorizeObjects
(-C
): Allows suppressing colorization of objects when set to false
. In combination with --singleLine
, this ensures that the end of each line is parsable JSON.--crlf
(-f
): Appends carriage return and line feed, instead of just a line
feed, to the formatted log line.--errorProps
(-e
): When formatting an error object, display this list
of properties. The list should be a comma-separated list of properties Default: ''
.
Do not use this option if logging from pino@7. Support will be removed from future versions.--levelFirst
(-l
): Display the log level name before the logged date and time.--errorLikeObjectKeys
(-k
): Define the log keys that are associated with
error like objects. Default: err,error
.--messageKey
(-m
): Define the key that contains the main log message.
Default: msg
.--levelKey
(--levelKey
): Define the key that contains the level of the log. Nested keys are supported with each property delimited by a dot character (.
).
Keys may be escaped to target property names that contains the delimiter itself:
(--levelKey tags\\.level
).
Default: level
.--levelLabel
(-b
): Output the log level using the specified label.
Default: levelLabel
.--minimumLevel
(-L
): Hide messages below the specified log level. Accepts a number, trace
, debug
, info
, warn
, error
, or fatal
. If any more filtering is required, consider using jq
.--customLevels
(-x
): Override default levels with custom levels, e.g. -x err:99,info:1
--customColors
(-X
): Override default colors with custom colors, e.g. -X err:red,info:blue
--useOnlyCustomProps
(-U
): Only use custom levels and colors (if provided) (default: true); else fallback to default levels and colors, e.g. -U false
--messageFormat
(-o
): Format output of message, e.g. {levelLabel} - {pid} - url:{req.url}
will output message: INFO - 1123 - url:localhost:3000/test
Default: false
--timestampKey
(-a
): Define the key that contains the log timestamp.
Default: time
.--translateTime
(-t
): Translate the epoch time value into a human-readable
date and time string. This flag also can set the format string to apply when
translating the date to a human-readable format. For a list of available pattern
letters, see the dateformat
documentation.
HH:MM:ss.l
in the local timezone.UTC:
prefix to translate time to UTC, e.g. UTC:yyyy-mm-dd HH:MM:ss.l o
.SYS:
prefix to translate time to the local system's time zone. A
shortcut SYS:standard
to translate time to yyyy-mm-dd HH:MM:ss.l o
in
system time zone.--ignore
(-i
): Ignore one or several keys, nested keys are supported with each property delimited by a dot character (.
),
keys may be escaped to target property names that contains the delimiter itself:
(-i time,hostname,req.headers,log\\.domain\\.corp/foo
).
The --ignore
option would be ignored, if both --ignore
and --include
are passed.
Default: hostname
.--include
(-I
): The opposite of --ignore
. Include one or several keys.--hideObject
(-H
): Hide objects from output (but not error object)--singleLine
(-S
): Print each log message on a single line (errors will still be multi-line)--config
: Specify a path to a config file containing the pino-pretty options. pino-pretty will attempt to read from a .pino-prettyrc
in your current directory (process.cwd
) if not specifiedWe recommend against using pino-pretty
in production and highly
recommend installing pino-pretty
as a development dependency.
Install pino-pretty
alongside pino
and set the transport target to 'pino-pretty'
:
const pino = require('pino')
const logger = pino({
transport: {
target: 'pino-pretty'
},
})
logger.info('hi')
The transport option can also have an options object containing pino-pretty
options:
const pino = require('pino')
const logger = pino({
transport: {
target: 'pino-pretty',
options: {
colorize: true
}
}
})
logger.info('hi')
Use it as a stream:
const pino = require('pino')
const pretty = require('pino-pretty')
const logger = pino(pretty())
logger.info('hi')
Options are also supported:
const pino = require('pino')
const pretty = require('pino-pretty')
const stream = pretty({
colorize: true
})
const logger = pino(stream)
logger.info('hi')
See the Options section for all possible options.
If you are using pino-pretty
as a stream and you need to provide options to pino
,
pass the options as the first argument and pino-pretty
as second argument:
const pino = require('pino')
const pretty = require('pino-pretty')
const stream = pretty({
colorize: true
})
const logger = pino({ level: 'info' }, stream)
// Nothing is printed
logger.debug('hi')
Logging with Jest is problematic, as the test framework requires no asynchronous operation to continue after the test has finished. The following is the only supported way to use this module with Jest:
import pino from 'pino'
import pretty from 'pino-pretty'
test('test pino-pretty', () => {
const logger = pino(pretty({ sync: true }));
logger.info('Info');
logger.error('Error');
});
Using the new pino v7+
transports not all
options are serializable, for example if you want to use messageFormat
as a
function you will need to wrap pino-pretty
in a custom module.
Executing main.js
below will log a colorized hello world
message using a
custom function messageFormat
:
// main.js
const pino = require('pino')
const logger = pino({
transport: {
target: './pino-pretty-transport',
options: {
colorize: true
}
},
})
logger.info('world')
// pino-pretty-transport.js
module.exports = opts => require('pino-pretty')({
...opts,
messageFormat: (log, messageKey) => `hello ${log[messageKey]}`
})
This boolean returns whether the currently used TTY supports colorizing the logs.
import pretty from 'pino-pretty'
if (pretty.isColorSupported) {
...
}
The options accepted have keys corresponding to the options described in CLI Arguments:
{
colorize: colorette.isColorSupported, // --colorize
colorizeObjects: true, //--colorizeObjects
crlf: false, // --crlf
errorLikeObjectKeys: ['err', 'error'], // --errorLikeObjectKeys (not required to match custom errorKey with pino >=8.21.0)
errorProps: '', // --errorProps
levelFirst: false, // --levelFirst
messageKey: 'msg', // --messageKey (not required with pino >=8.21.0)
levelKey: 'level', // --levelKey
messageFormat: false, // --messageFormat
timestampKey: 'time', // --timestampKey
translateTime: false, // --translateTime
ignore: 'pid,hostname', // --ignore
include: 'level,time', // --include
hideObject: false, // --hideObject
singleLine: false, // --singleLine
customColors: 'err:red,info:blue', // --customColors
customLevels: 'err:99,info:1', // --customLevels (not required with pino >=8.21.0)
levelLabel: 'levelLabel', // --levelLabel
minimumLevel: 'info', // --minimumLevel
useOnlyCustomProps: true, // --useOnlyCustomProps
// The file or file descriptor (1 is stdout) to write to
destination: 1,
// Alternatively, pass a `sonic-boom` instance (allowing more flexibility):
// destination: new SonicBoom({ dest: 'a/file', mkdir: true })
// You can also configure some SonicBoom options directly
sync: false, // by default we write asynchronously
append: true, // the file is opened with the 'a' flag
mkdir: true, // create the target destination
customPrettifiers: {}
}
The colorize
default follows
colorette.isColorSupported
.
The defaults for sync
, append
, mkdir
inherit from
SonicBoom(opts)
.
customPrettifiers
option provides the ability to add a custom prettify function
for specific log properties. customPrettifiers
is an object, where keys are
log properties that will be prettified and value is the prettify function itself.
For example, if a log line contains a query
property,
you can specify a prettifier for it:
{
customPrettifiers: {
query: prettifyQuery
}
}
//...
const prettifyQuery = value => {
// do some prettify magic
}
All prettifiers use this function signature:
['logObjKey']: (output, keyName, logObj, extras) => string
logObjKey
- name of the key of the property in the log object that should have this function applied to itoutput
- the value of the property in the log objectkeyName
- the name of the property (useful for level
and message
when levelKey
or messageKey
is used)logObj
- the full log object, for contextextras
- an object containing additional data/functions created in the context of this pino-pretty logger or specific to the key (see level
prettifying below)
extras
objects contain colors
which is a Colorette object containing color functions. Colors are enabled based on colorize
provided to pino-pretty or colorette.isColorSupported
if colorize
was not provided.Additionally, customPrettifiers
can be used to format the time
, hostname
,
pid
, name
, caller
and level
outputs AS WELL AS any arbitrary key-value that exists on a given log object.
An example usage of customPrettifiers
using all parameters from the function signature:
{
customPrettifiers: {
// The argument for this function will be the same
// string that's at the start of the log-line by default:
time: timestamp => `🕰 ${timestamp}`,
// The argument for the level-prettifier may vary depending
// on if the levelKey option is used or not.
// By default this will be the same numerics as the Pino default:
level: logLevel => `LEVEL: ${logLevel}`,
// level provides additional data in `extras`:
// * label => derived level label string
// * labelColorized => derived level label string with colorette colors applied based on customColors and whether colors are supported
level: (logLevel, key, log, { label, labelColorized, colors }) => `LEVEL: ${logLevel} LABEL: ${levelLabel} COLORIZED LABEL: ${labelColorized}`,
// other prettifiers can be used for the other keys if needed, for example
hostname: hostname => `MY HOST: ${hostname}`,
pid: pid => pid,
name: (name, key, log, { colors }) => `${colors.blue(name)}`,
caller: (caller, key, log, { colors }) => `${colors.greenBright(caller)}`,
myCustomLogProp: (value, key, log, { colors }) => `My Prop -> ${colors.bold(value)} <--`
}
}
messageFormat
option allows you to customize the message output.
A template string
like this can define the format:
{
messageFormat: '{levelLabel} - {pid} - url:{req.url}'
}
In addition to this, if / end statement blocks can also be specified. Else statements and nested conditions are not supported.
{
messageFormat: '{levelLabel} - {if pid}{pid} - {end}url:{req.url}'
}
This option can also be defined as a function
with this function signature:
{
messageFormat: (log, messageKey, levelLabel, { colors }) => {
// do some log message customization
//
// `colors` is a Colorette object with colors enabled based on `colorize` option
return `This is a ${color.red('colorized')}, custom message: ${log[messageKey]}`;
}
}
Because pino-pretty
uses stdout redirection, in some cases the command may
terminate with an error due to shell limitations.
For example, currently, mingw64 based shells (e.g. Bash as supplied by git for
Windows) are affected and terminate the process with
a stdout is not a tty
error message.
Any PRs are welcomed!
MIT License
FAQs
Prettifier for Pino log lines
The npm package pino-pretty receives a total of 1,600,310 weekly downloads. As such, pino-pretty popularity was classified as popular.
We found that pino-pretty demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.