JSPM

pino

0.4.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 12702904
  • Score
    100M100P100Q203132F
  • License MIT

fast and simple logger

Package Exports

  • pino

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (pino) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

pino

Extremely fast node.js logger, inspired by Bunyan. It also includes a shell utility to pretty-print its log files.

cli

Install

npm install pino --save

Usage

'use strict'

var pino = require('./')()
var info = pino.info
var error = pino.error

info('hello world')
error('this is at error level')
info('the answer is %d', 42)
info({ obj: 42 }, 'hello world')
info({ obj: 42, b: 2 }, 'hello world')
info({ obj: { aa: 'bbb' } }, 'another')
setImmediate(info, 'after setImmediate')
error(new Error('an error'))

This produces:

{"pid":13087,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1457531561635,"v":0}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":50,"msg":"this is at error level","time":1457531561636,"v":0}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":30,"msg":"the answer is 42","time":1457531561637,"v":0}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1457531561637,"v":0,"obj":42}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1457531561638,"v":0,"obj":42,"b":2}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":30,"msg":"another","time":1457531561638,"v":0,"obj":{"aa":"bbb"}}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":50,"msg":"an error","time":1457531561639,"v":0,"type":"Error","stack":"Error: an error\n    at Object.<anonymous> (/Users/davidclements/z/nearForm/pino/example.js:14:7)\n    at Module._compile (module.js:413:34)\n    at Object.Module._extensions..js (module.js:422:10)\n    at Module.load (module.js:357:32)\n    at Function.Module._load (module.js:314:12)\n    at Function.Module.runMain (module.js:447:10)\n    at startup (node.js:141:18)\n    at node.js:933:3"}
{"pid":13087,"hostname":"MacBook-Pro-3.home","level":30,"msg":"after setImmediate","time":1457531561641,"v":0}

Benchmarks

As far as we know, it is the fastest logger in town:

benchBunyan*10000: 1093.236ms
benchWinston*10000: 1904.147ms
benchBole*10000: 1563.632ms
benchPino*10000: 287.858ms
benchBunyanObj*10000: 1187.016ms
benchWinstonObj*10000: 1990.980ms
benchPinoObj*10000: 366.865ms
benchBoleObj*10000: 1475.934ms
benchBunyan*10000: 1043.486ms
benchWinston*10000: 1801.232ms
benchBole*10000: 1524.136ms
benchPino*10000: 280.797ms
benchBunyanObj*10000: 1188.472ms
benchWinstonObj*10000: 1868.626ms
benchPinoObj*10000: 371.082ms
benchBoleObj*10000: 1496.449ms

## CLI

To use the command line tool, we can install pino globally:

npm install -g pino

Then we simply pipe a log file through pino:

cat log | pino

There's also a transformer flag that converts Epoch timestamps to ISO timestamps.

cat log | pino -t

For instance, pino -t will transform this:

{"pid":14139,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1457537229339,"v":0}

Into this:

{"pid":14139,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":"2016-03-09T15:27:09.339Z","v":0}

## API

pino([opts], [stream])

Returns a new logger. Allowed options are:

  • safe: avoid error causes by circular references in the object tree, default true
  • name: the name of the logger, default undefined
  • serializers: an object containing functions for custom serialization of objects. These functions should return an JSONifiable object and they should never throw
  • slowtime: Outputs ISO time stamps ('2016-03-09T15:18:53.889Z') instead of Epoch time stamps (1457536759176). WARNING: This option carries a 25% performance drop, we recommend using default Epoch timestamps and transforming logs after if required. The pino -t command will do this for you (see CLI)

stream is a Writable stream, defaults to process.stdout.

Example:

'use strict'

var pino = require('pino')
var instance = pino({
  name: 'myapp',
  safe: true,
  serializers: {
    req: pino.stdSerializers.req
    res: pino.stdSerializers.res
  }
}

logger.level

Set this property to the desired logging level.

In order of priority, available levels are:

  1. 'fatal'
  2. 'error'
  3. 'warn'
  4. 'info'
  5. 'debug'
  6. 'trace'

Example: logger.level = 'info'

The logging level is a minimum level. For instance if logger.level is 'info' then all fatal, error, warn, and info logs will be enabled.

logger.fatal([obj], msg, [...])

Log at 'fatal' level the given msg. If the first argument is an object, all its properties will be included in the JSON line. If more args follows msg, these will be used to format msg using util.format

logger.error([obj], msg, [...])

Log at 'error' level the given msg. If the first argument is an object, all its properties will be included in the JSON line. If more args follows msg, these will be used to format msg using util.format

logger.warn([obj], msg, [...])

Log at 'warn' level the given msg. If the first argument is an object, all its properties will be included in the JSON line. If more args follows msg, these will be used to format msg using util.format

logger.info([obj], msg, [...])

Log at 'info' level the given msg. If the first argument is an object, all its properties will be included in the JSON line. If more args follows msg, these will be used to format msg using util.format

logger.debug([obj], msg, [...])

Log at 'debug' level the given msg. If the first argument is an object, all its properties will be included in the JSON line. If more args follows msg, these will be used to format msg using util.format

logger.trace([obj], msg, [...])

Log at 'trace' level the given msg. If the first argument is an object, all its properties will be included in the JSON line. If more args follows msg, these will be used to format msg using util.format

pino.stdSerializers.req

Function to generate a JSONifiable object out of an HTTP request from node HTTP server.

It returns an object in the form:

{
  pid: 93535,
  hostname: 'your host',
  level: 30,
  msg: 'my request',
  time: '2016-03-07T12:21:48.766Z',
  v: 0,
  req: {
    method: 'GET',
    url: '/',
    headers: {
      host: 'localhost:50201',
      connection: 'close'
    },
    remoteAddress: '::ffff:127.0.0.1',
    remotePort: 50202
  }
}

pino.stdSerializers.res

Function to generate a JSONifiable object out of an HTTP response from node HTTP server.

It returns an object in the form:

{
  pid: 93581,
  hostname: 'myhost',
  level: 30,
  msg: 'my response',
  time: '2016-03-07T12:23:18.041Z',
  v: 0,
  res: {
    statusCode: 200,
    header: 'HTTP/1.1 200 OK\r\nDate: Mon, 07 Mar 2016 12:23:18 GMT\r\nConnection: close\r\nContent-Length: 5\r\n\r\n'
  }
}

How do I rotate log files

You should configure logrotate to rotate your log files, and just redirect the standard output of your application to a file, like so:

node server.js > /var/log/myapp.log

In order to rotate your log files, add in /etc/logrotate.d/myapp:

/var/log/myapp.log {
       su root
       daily
       rotate 7
       delaycompress
       compress
       notifempty
       missingok
       copytruncate
}

How to use Transports with Pino

Transports are not part of Pino. There will never be an API for transports, or support for ObjectMode Writable streams. This library is fast because it does way less than the others. We went to great lengths to make sure this library is really fast, and transports will slow things down.

So, how do you do a transport? With Pino, we create a separate process for our transport and pipe to it. It's the Unix philosophy.

Something like:

var split = require('split2')
var pump = require('pump')
var through = require('through2')

var myTransport = through.obj(function (chunk, enc, cb) {
  // do whatever you want here!
  console.log(chunk)
  cb()
}

pump(process.stdin, split2(JSON.parse), myTransport)

Using transports in the same process causes unnecessary load and slows down Node's single threaded event loop.

If you write a transport, let us know and we will add a link here!

Acknowledgements

This project was kindly sponsored by nearForm.

License

MIT