Security News
RubyGems.org Adds New Maintainer Role
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.
Pino is a very low overhead Node.js logger, which is inspired by Bunyan. It is designed to be as minimal as possible and to perform logging tasks with a very small performance overhead. Pino provides a simple to use API for structured logging and can be easily integrated with different transports for log processing.
Basic Logging
This feature allows you to perform basic logging tasks, such as logging informational messages.
const pino = require('pino');
const logger = pino();
logger.info('Hello, this is an info message!');
Logging with Different Levels
Pino allows you to log messages with different severity levels, such as error, warn, and debug.
const logger = pino();
logger.error('This is an error message');
logger.warn('This is a warning message');
logger.debug('This is a debug message');
Child Loggers
You can create child loggers from a parent logger, which can inherit the configuration of the parent and can also have additional properties.
const parentLogger = pino();
const childLogger = parentLogger.child({ a: 'property' });
childLogger.info('Hello from child logger');
Custom Serializers
Pino allows you to define custom serializers for logging objects in a specific way.
const logger = pino({
serializers: {
req: (req) => ({ method: req.method, url: req.url })
}
});
logger.info({ req: requestObject }, 'Request log message');
Pretty Printing
For development purposes, Pino can be combined with the 'pino-pretty' module to format logs in a more readable way.
const pino = require('pino');
const pretty = require('pino-pretty');
const logger = pino(pretty());
logger.info('This will be pretty printed');
Winston is a multi-transport async logging library for Node.js. It is designed to be a simple and universal logging library with support for multiple transports. Compared to Pino, Winston is more feature-rich and configurable but can be heavier on performance.
Bunyan is a simple and fast JSON logging library for Node.js services. Like Pino, it is inspired by the Unix philosophy and focuses on structured logging. Bunyan is more similar to Pino in terms of philosophy, but Pino claims to be faster and more efficient.
Log4js is a logging framework for Node.js, which provides flexible configuration and supports multiple appenders. It is similar to the Log4j library for Java. Compared to Pino, Log4js offers more traditional logging features but may not be as performance-optimized.
Extremely fast node.js logger, inspired by Bunyan. It also includes a shell utility to pretty-print its log files.
npm install pino --save
If you need support for Node.js v0.12 or v0.10, please install the latest 2.x release using the legacy
tag:
npm install pino@legacy --save
Documentation for the legacy version 2.x is available on the v2.x.x
branch.
'use strict'
var pino = require('pino')()
pino.info('hello world')
pino.error('this is at error level')
pino.info('the answer is %d', 42)
pino.info({ obj: 42 }, 'hello world')
pino.info({ obj: 42, b: 2 }, 'hello world')
pino.info({ obj: { aa: 'bbb' } }, 'another')
setImmediate(function () {
pino.info('after setImmediate')
})
pino.error(new Error('an error'))
var child = pino.child({ a: 'property' })
child.info('hello child!')
var childsChild = child.child({ another: 'property' })
childsChild.info('hello baby..')
This produces:
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1459529098958,"v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":50,"msg":"this is at error level","time":1459529098959,"v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"the answer is 42","time":1459529098960,"v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1459529098960,"obj":42,"v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1459529098960,"obj":42,"b":2,"v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"another","time":1459529098960,"obj":{"aa":"bbb"},"v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":50,"msg":"an error","time":1459529098961,"type":"Error","stack":"Error: an error\n at Object.<anonymous> (/Users/davidclements/z/nearForm/pino/example.js:14:12)\n at Module._compile (module.js:435:26)\n at Object.Module._extensions..js (module.js:442:10)\n at Module.load (module.js:356:32)\n at Function.Module._load (module.js:311:12)\n at Function.Module.runMain (module.js:467:10)\n at startup (node.js:136:18)\n at node.js:963:3","v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello child!","time":1459529098962,"a":"property","v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello baby..","time":1459529098962,"another":"property","a":"property","v":1}
{"pid":94473,"hostname":"MacBook-Pro-3.home","level":30,"msg":"after setImmediate","time":1459529098963,"v":1}
As far as we know, it is one of the fastest loggers in town:
pino.info('hello world')
:
benchBunyan*10000: 1355.229ms
benchWinston*10000: 2226.117ms
benchBole*10000: 291.727ms
benchDebug*10000: 445.291ms
benchLogLevel*10000: 322.181ms
benchPino*10000: 269.109ms
benchPinoExtreme*10000: 102.239ms
pino.info({'hello': 'world'})
:
benchBunyanObj*10000: 1464.568ms
benchWinstonObj*10000: 2177.602ms
benchBoleObj*10000: 322.105ms
benchLogLevelObject*10000: 1443.148ms
benchPinoObj*10000: 309.564ms
benchPinoUnsafeObj*10000: 301.308ms
benchPinoExtremeObj*10000: 130.343ms
benchPinoUnsafeExtremeObj*10000: 131.322ms
pino.info(aBigDeeplyNestedObject)
:
benchBunyanDeepObj*10000: 8749.174ms
benchWinstonDeepObj*10000: 17761.409ms
benchBoleDeepObj*10000: 5252.563ms
benchLogLevelDeepObj*10000: 43518.525ms
benchPinoDeepObj*10000: 5124.361ms
benchPinoUnsafeDeepObj*10000: 3539.253ms
benchPinoExtremeDeepObj*10000: 5138.457ms
benchPinoUnsafeExtremeDeepObj*10000: 3480.270ms
pino.info('hello %s %j %d', 'world', {obj: true}, 4, {another: 'obj'})
:
benchDebugInterpolateExtra*10000: 640.001ms
benchBunyanInterpolateExtra*10000: 2888.825ms
benchWinstonInterpolateExtra*10000: 2616.285ms
benchBoleInterpolateExtra*10000: 1313.470ms
benchLogLevelInterpolateExtra*10000: 1487.610ms
benchPinoInterpolateExtra*10000: 486.367ms
benchPinoUnsafeInterpolateExtra*10000: 457.778ms
benchPinoExtremeInterpolateExtra*10000: 314.635ms
benchPinoUnsafeExtremeInterpolateExtra*10000: 294.915ms
In many cases, pino is over 6x faster than alternatives.
For a fair comparison, LogLevel was extended
to include a timestamp and bole had
fastTime
mode switched on.
Pino is compatible with browserify
for browser side usage:
This can be useful with isomorphic/universal JavaScript code.
By default, in the browser,
pino
uses corresponding Log4j console
methods (console.error
, console.warn
, console.info
, console.debug
, console.trace
) and uses console.error
for any fatal
level logs.
Pino can be passed a browser
object in the options object,
which can have a write
property or an asObject
property.
asObject
(Boolean)var pino = require('pino')({browser: {asObject: true}})
The asObject
option will create a pino-like log object instead of
passing all arguments to a console method, for instance:
pino.info('hi') // creates and logs {msg: 'hi', level: 30, time: <ts>}
When write
is set, asObject
will always be true
.
write
(Function | Object)Instead of passing log messages to console.log
they can be passed to
a supplied function.
If write
is set to a single function, all logging objects are passed
to this function.
var pino = require('pino')({browser: {write: (o) => {
// do something with o
}}})
If write
is an object, it can have methods that correspond to the
levels. When a message is logged at a given level, the corresponding
method is called. If a method isn't present, the logging falls back
to using the console
.
var pino = require('pino')({browser: {write: {
info: function (o) {
//process info log object
},
error: function (o) {
//process error log object
}
}}})
There's some fine points to be aware of, which are a result of worthwhile trade-offs:
The logger functions (e.g. pino.info
) can take a maximum of 11 arguments.
If you need more than that to write a log entry, you're probably doing it wrong.
It's possible for naming conflicts to arise between child loggers and children of child loggers.
This isn't as bad as it sounds, even if you do use the same keys between parent and child loggers Pino resolves the conflict in the sanest way.
For example, consider the following:
var pino = require('pino')
var fs = require('fs')
pino(fs.createWriteStream('./my-log'))
.child({a: 'property'})
.child({a: 'prop'})
.info('howdy')
$ cat my-log
{"pid":95469,"hostname":"MacBook-Pro-3.home","level":30,"msg":"howdy","time":1459534114473,"a":"property","a":"prop","v":1}
Notice how there's two key's named a
in the JSON output. The sub-childs properties
appear after the parent child properties. This means if we run our logs through pino -t
(or convert them to objects in any other way) we'll end up with one a
property whose value corresponds to the lowest child in the hierarchy:
$ cat my-log | pino -t
{"pid":95469,"hostname":"MacBook-Pro-3.home","level":30,"msg":"howdy","time":"2016-04-01T18:08:34.473Z","a":"prop","v":1}
This equates to the same log output that Bunyan supplies.
One of Pino's performance tricks is to avoid building objects and stringifying them, so we're building strings instead. This is why duplicate keys between parents and children will end up in log output.
https://www.npmjs.com/~matteo.collina
https://twitter.com/matteocollina
https://github.com/davidmarkclements
https://www.npmjs.com/~davidmarkclements
https://twitter.com/davidmarkclem
https://www.npmjs.com/~jsumners
https://twitter.com/jsumners79
You'll find an active group of Pino users in the #pino channel on Freenode, including some of the contributors to this project.
Pino is an OPEN Open Source Project. This means that:
Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
See the CONTRIBUTING.md file for more details.
This project was kindly sponsored by nearForm.
Logo and identity designed by Beibhinn Murphy O'Brien: https://www.behance.net/BeibhinnMurphyOBrien.
Licensed under MIT.
FAQs
super fast, all natural json logger
The npm package pino receives a total of 462,218 weekly downloads. As such, pino popularity was classified as popular.
We found that pino demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 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
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.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.