Comparing version 3.0.5 to 3.0.6
{ | ||
"name": "pino", | ||
"version": "3.0.5", | ||
"version": "3.0.6", | ||
"description": "super fast, all natural json logger", | ||
@@ -10,3 +10,3 @@ "main": "pino.js", | ||
}, | ||
"files" : [ | ||
"files": [ | ||
"pino.js", | ||
@@ -17,2 +17,3 @@ "browser.js", | ||
"test", | ||
"docs", | ||
"example.js" | ||
@@ -52,14 +53,14 @@ ], | ||
"devDependencies": { | ||
"benchmark": "^2.1.0", | ||
"bole": "^3.0.0", | ||
"bunyan": "^1.6.0", | ||
"debug": "^2.2.0", | ||
"benchmark": "^2.1.2", | ||
"bole": "^3.0.2", | ||
"bunyan": "^1.8.5", | ||
"debug": "^2.5.1", | ||
"fastbench": "^1.0.0", | ||
"flush-write-stream": "^1.0.0", | ||
"flush-write-stream": "^1.0.2", | ||
"fresh-require": "^1.0.3", | ||
"log": "^1.4.0", | ||
"loglevel": "^1.4.0", | ||
"pre-commit": "^1.1.2", | ||
"pre-commit": "^1.2.2", | ||
"pump": "^1.0.1", | ||
"standard": "^8.0.0", | ||
"standard": "^8.6.0", | ||
"steed": "^1.1.3", | ||
@@ -69,3 +70,3 @@ "tap": "^8.0.0", | ||
"through2": "^2.0.1", | ||
"winston": "^2.1.1", | ||
"winston": "^2.3.0", | ||
"zuul": "^3.11.1" | ||
@@ -75,6 +76,5 @@ }, | ||
"chalk": "^1.1.1", | ||
"core-util-is": "^1.0.2", | ||
"fast-json-parse": "^1.0.0", | ||
"fast-safe-stringify": "^1.1.0", | ||
"flatstr": "^1.0.0", | ||
"fast-safe-stringify": "^1.1.3", | ||
"flatstr": "^1.0.4", | ||
"once": "^1.3.3", | ||
@@ -81,0 +81,0 @@ "quick-format-unescaped": "^1.0.0", |
900
README.md
@@ -13,12 +13,6 @@ ![banner](pino-banner.png) | ||
* [Benchmarks](#benchmarks) | ||
* [API](#api) | ||
* [Extreme mode explained](#extreme) | ||
* [How to use Pino with Express](#express) | ||
* [How to use Pino with Hapi](#hapi) | ||
* [How to use Pino with Restify](#restify) | ||
* [How to use Pino with Koa](#koa) | ||
* [How to use Pino with `debug`](#debug) | ||
* [How do I rotate log files?](#rotate) | ||
* [How do I redact sensitive information?](#redact) | ||
* [How to use Transports with Pino](#transports) | ||
* [API](docs/API.md) | ||
* [Extreme mode explained](docs/extreme.md) | ||
* [Pino Howtos](docs/howtos.md) | ||
* [Transports with Pino](docs/transports.md) | ||
* [Pino in the browser](#browser) | ||
@@ -81,4 +75,3 @@ * [Caveats](#caveats) | ||
## Benchmarks | ||
<details> | ||
<summary> As far as we know, it is one of the fastest loggers in town: </summary> | ||
As far as we know, it is one of the fastest loggers in town: | ||
@@ -142,887 +135,7 @@ `pino.info('hello world')`: | ||
`fastTime` mode switched on. | ||
</details> | ||
<a name="cli"></a> | ||
## CLI | ||
<details> | ||
<summary>To use the command line tool, we can install `pino` globally:</summary> | ||
```sh | ||
npm install -g pino | ||
``` | ||
Then we simply pipe a log file through `pino`: | ||
```sh | ||
cat log | pino | ||
``` | ||
There are also two transformer flags.. | ||
`-t` that converts Epoch timestamps to ISO timestamps. | ||
```sh | ||
cat log | pino -t | ||
``` | ||
and `-l` that flips the time and level on the standard output. | ||
```sh | ||
cat log | pino -l | ||
``` | ||
`pino -t` will transform this: | ||
```js | ||
{"pid":14139,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":1457537229339,"v":0} | ||
``` | ||
Into this: | ||
```js | ||
{"pid":14139,"hostname":"MacBook-Pro-3.home","level":30,"msg":"hello world","time":"2016-03-09T15:27:09.339Z","v":0} | ||
``` | ||
`pino -l` will transform this: | ||
```sh | ||
[2016-03-09T15:27:09.339Z] INFO (14139 on MacBook-Pro-3.home): hello world | ||
``` | ||
Into this: | ||
```sh | ||
INFO [2016-03-09T15:27:09.339Z] (14139 on MacBook-Pro-3.home): hello world | ||
``` | ||
</details> | ||
<a name="api"></a> | ||
## API | ||
* <a href="#constructor"><code><b>pino()</b></code></a> | ||
* <a href="#child"><code>logger.<b>child()</b></code></a> | ||
* <a href="#level"><code>logger.<b>level</b></code></a> | ||
* <a href="#fatal"><code>logger.<b>fatal()</b></code></a> | ||
* <a href="#error"><code>logger.<b>error()</b></code></a> | ||
* <a href="#warn"><code>logger.<b>warn()</b></code></a> | ||
* <a href="#info"><code>logger.<b>info()</b></code></a> | ||
* <a href="#debug"><code>logger.<b>debug()</b></code></a> | ||
* <a href="#trace"><code>logger.<b>trace()</b></code></a> | ||
* <a href="#flush"><code>logger.<b>flush()</b></code></a> | ||
* <a href="#addLevel"><code>logger.<b>addLevel(name, lvl)</b></code></a> | ||
* <a href="#levelVal"><code>logger.<b>levelVal</b></code></a> | ||
* <a href="#level-change"><code>logger.on(<b>'level-change'</b>, fn)</code></a> | ||
* <a href="#levelValues"><code>logger.levels.<b>values</b></code> & <code>pino.levels.<b>values</b></code></a> | ||
* <a href="#levelLabels"><code>logger.levels.<b>labels</b></code> & <code>pino.levels.<b>labels</b></code></a> | ||
* <a href="#log_version"><code>pino.<b>LOG_VERSION</b></code> & <code>logger.<b>LOG_VERSION</b></code></a> | ||
* <a href="#reqSerializer"><code>pino.stdSerializers.<b>req</b></code></a> | ||
* <a href="#resSerializer"><code>pino.stdSerializers.<b>res</b></code></a> | ||
* <a href="#errSerializer"><code>pino.stdSerializers.<b>err</b></code></a> | ||
* <a href="#pretty"><code>pino.<b>pretty()</b></code></a> | ||
<a name="constructor"></a> | ||
### 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 | ||
* `timestamp`: Enables or disables the inclusion of a timestamp in the log message. `slowtime` has no effect if this option is set to `false`. Defaults to `true`. | ||
* `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](#cli)). default `false`. | ||
* `extreme`: Enables extreme mode, yields an additional 60% performance (from 250ms down to 100ms per 10000 ops). There are trade-off's should be understood before usage. See [Extreme mode explained](#extreme). default `false` | ||
* `level`: one of `'fatal'`, `'error'`, `'warn'`, `'info`', `'debug'`, `'trace'`; also `'silent'` is supported to disable logging. Any other value defines a custom level and requires supplying a level value via `levelVal`. | ||
* `levelVal`: when defining a custom log level via `level`, set to an integer value to define the new level. Defaults to `undefined`. | ||
* `enabled`: enables logging, defaults to `true`. | ||
`stream` is a Writable stream, defaults to `process.stdout`. | ||
Example: | ||
```js | ||
'use strict' | ||
var pino = require('pino') | ||
var logger = pino({ | ||
name: 'myapp', | ||
safe: true, | ||
serializers: { | ||
req: pino.stdSerializers.req, | ||
res: pino.stdSerializers.res | ||
} | ||
}) | ||
``` | ||
<a name="child"></a> | ||
### logger.child(bindings) | ||
Creates a child logger, setting all key-value pairs in `bindings` as | ||
properties in the log lines. All serializers will be applied to the | ||
given pair. | ||
Example: | ||
```js | ||
logger.child({ a: 'property' }).info('hello child!') | ||
// generates | ||
// {"pid":46497,"hostname":"MacBook-Pro-di-Matteo.local","level":30,"msg":"hello child!","time":1458124707120,"v":0,"a":"property"} | ||
``` | ||
Child loggers use the same output stream as the parent and inherit | ||
the current log level of the parent at the time they are spawned. | ||
From v2.x.x the log level of a child is mutable (whereas in | ||
v1.x.x it was immutable), and can be set independently of the parent. | ||
If a `level` property is present in the object passed to `child` it will | ||
override the child logger level. | ||
For example | ||
``` | ||
var logger = pino() | ||
logger.level = 'error' | ||
logger.info('nope') //does not log | ||
var child = logger.child({foo: 'bar'}) | ||
child.info('nope again') //does not log | ||
child.level = 'info' | ||
child.info('hooray') //will log | ||
logger.info('nope nope nope') //will not log, level is still set to error | ||
logger.child({ foo: 'bar', level: 'debug' }).debug('debug!') | ||
``` | ||
Child loggers inherit the serializers from the parent logger but it is | ||
possible to override them. | ||
For example | ||
``` | ||
var pino = require('./pino') | ||
var customSerializers = { | ||
test: function () { | ||
return 'this is my serializer' | ||
} | ||
} | ||
var child = pino().child({serializers: customSerializers}) | ||
child.info({test: 'should not show up'}) | ||
``` | ||
Will produce the following output: | ||
``` | ||
{"pid":7971,"hostname":"mycomputer.local","level":30,"time":1469488147985,"test":"this is my serializer","v":1} | ||
``` | ||
Also from version 2.x.x we can spawn child loggers from child loggers, for instance | ||
``` | ||
var logger = pino() | ||
var child = logger.child({father: true}) | ||
var childChild = child.child({baby: true}) | ||
``` | ||
Child logger creation is fast: | ||
``` | ||
benchBunyanCreation*10000: 1291.332ms | ||
benchBoleCreation*10000: 1630.542ms | ||
benchPinoCreation*10000: 352.330ms | ||
benchPinoExtremeCreation*10000: 102.282ms | ||
``` | ||
Logging through a child logger has little performance penalty: | ||
``` | ||
benchBunyanChild*10000: 1343.933ms | ||
benchBoleChild*10000: 1605.969ms | ||
benchPinoChild*10000: 334.573ms | ||
benchPinoExtremeChild*10000: 152.792ms | ||
``` | ||
Spawning children from children has negligible overhead: | ||
``` | ||
benchBunyanChildChild*10000: 1397.202ms | ||
benchPinoChildChild*10000: 338.930ms | ||
benchPinoExtremeChildChild*10000: 150.143ms | ||
``` | ||
<a name="level"></a> | ||
### logger.level | ||
Set this property to the desired logging level. | ||
In order of priority, available levels are: | ||
1. <a href="#fatal">`'fatal'`</a> | ||
2. <a href="#error">`'error'`</a> | ||
3. <a href="#warn">`'warn'`</a> | ||
4. <a href="#info">`'info'`</a> | ||
5. <a href="#debug">`'debug'`</a> | ||
6. <a href="#trace">`'trace'`</a> | ||
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. | ||
You can pass `'silent'` to disable logging. | ||
<a name="fatal"></a> | ||
### 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`](https://nodejs.org/api/util.html#util_util_format_format) | ||
<a name="error"></a> | ||
### 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`](https://nodejs.org/api/util.html#util_util_format_format) | ||
<a name="warn"></a> | ||
### 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`](https://nodejs.org/api/util.html#util_util_format_format) | ||
<a name="info"></a> | ||
### 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`](https://nodejs.org/api/util.html#util_util_format_format) | ||
<a name="debug"></a> | ||
### 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`](https://nodejs.org/api/util.html#util_util_format_format) | ||
<a name="trace"></a> | ||
### 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`](https://nodejs.org/api/util.html#util_util_format_format) | ||
<a name="flush"></a> | ||
### logger.flush() | ||
Flushes the content of the buffer in [extreme mode](#extreme). It has no effect if | ||
extreme mode is not enabled. | ||
<a name="addLevel"></a> | ||
### logger.addLevel(name, lvl) | ||
Defines a new level on the logger instance. | ||
Returns `true` on success and `false` if there was a conflict (level name or number already exists). | ||
Example: | ||
```js | ||
var pino = require('pino') | ||
var log = pino() | ||
log.addLevel('myLevel', 35) | ||
log.level = 'myLevel' | ||
log.myLevel('a message') | ||
``` | ||
Notice that `addLevel` does *not* change the current level of the logger. | ||
If you need a custom level at construction, you can supply the `level` and `levelVal` options: | ||
```js | ||
var pino = require('pino') | ||
var log = pino({level: 'myLevel', levelVal: 35}) | ||
log.myLevel('a message') | ||
``` | ||
Notice that the level is set to the custom level on construction, i.e. `log.level` does not need to be set. | ||
<a name="levelVal"></a> | ||
### logger.levelVal | ||
Returns the integer value for the logger instance's logging level. | ||
<a name="level-change"></a> | ||
### logger.on('level-change', fn) | ||
Registers a listener function that is triggered when the level is changed. | ||
The listener is passed four arguments: `levelLabel`, `levelValue`, `previousLevelLabel`, `previousLevelValue`. | ||
**Note:** When browserified, this functionality will only be available if the `events` module has been required else where (e.g. if you're using streams in the browser). This allows for a trade-off between bundle size and functionality. | ||
```js | ||
var listener = function (lvl, val, prevLvl, prevVal) { | ||
console.log(lvl, val, prevLvl, prevVal) | ||
} | ||
logger.on('level-change', listener) | ||
logger.level = 'trace' // trigger console message | ||
logger.removeListener('level-change', listener) | ||
logger.level = 'info' // no message, since listener was removed | ||
``` | ||
<a name="levelValues"></a> | ||
### logger.levels.values & pino.levels.values | ||
Returns the mappings of level names to their respective internal number | ||
representation. For example: | ||
```js | ||
pino.levels.values.error === 50 // true | ||
``` | ||
<a name="levelLabels"></a> | ||
### logger.levels.labels & pino.levels.labels | ||
Returns the mappings of level internal level numbers to their string | ||
representations. For example: | ||
```js | ||
pino.levels.labels[50] === 'error' // true | ||
``` | ||
<a name="log_version"></a> | ||
### logger.LOG_VERSION & pino.LOG_VERSION | ||
Read only. Holds the current log format version (as output in the `v` property of each log record). | ||
<a name="reqSerializer"></a> | ||
### pino.stdSerializers.req | ||
Generates a JSONifiable object from the HTTP `request` object passed to | ||
the `createServer` callback of Node's HTTP server. | ||
It returns an object in the form: | ||
```js | ||
{ | ||
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 | ||
} | ||
} | ||
``` | ||
<a name="resSerializer"></a> | ||
### pino.stdSerializers.res | ||
Generates a JSONifiable object from the HTTP `response` object passed to | ||
the `createServer` callback of Node's HTTP server. | ||
It returns an object in the form: | ||
```js | ||
{ | ||
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' | ||
} | ||
} | ||
``` | ||
<a name="errSerializer"></a> | ||
### pino.stdSerializers.err | ||
Serializes an `Error` object if passed in as an property. | ||
```js | ||
{ | ||
"pid": 40510, | ||
"hostname": "MBP-di-Matteo", | ||
"level": 50, | ||
"msg": "an error", | ||
"time": 1459433282301, | ||
"v": 1, | ||
"type": "Error", | ||
"stack": "Error: an error\n at Object.<anonymous> (/Users/matteo/Repositories/pino/example.js:16:7)\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:313:12)\n at Function.Module.runMain (module.js:467:10)\n at startup (node.js:136:18)\n at node.js:963:3" | ||
} | ||
``` | ||
<a name="pretty"></a> | ||
### pino.pretty([opts]) | ||
Returns a transform stream that formats JSON output into pretty print | ||
output as per the [cli](#cli) tool. | ||
Options: | ||
* `timeTransOnly`, if set to `true`, it will only covert the unix timestamp to | ||
ISO 8601 date format, and reserialize the JSON (equivalent to `pino -t`). | ||
* `formatter`, a custom function to format the line, is passed the JSON | ||
object as an argument and should return a string value | ||
You can use the pretty transformer internally, like so: | ||
```js | ||
'use strict' | ||
var pino = require('pino') | ||
var pretty = pino.pretty() | ||
pretty.pipe(process.stdout) | ||
var log = pino({ | ||
name: 'app', | ||
safe: true | ||
}, pretty) | ||
log.child({ widget: 'foo' }).info('hello') | ||
log.child({ widget: 'bar' }).warn('hello 2') | ||
``` | ||
<a name="extreme"></a> | ||
## Extreme mode explained | ||
<details> | ||
<summary>In essence, Extreme mode enables extreme performance:</summary> | ||
It works by buffering log messages and writing them in larger chunks. | ||
This has a couple of important caveats: | ||
* 4KB of spare RAM will be needed for logging | ||
* As opposed to the default mode, there is not a one-to-one relationship between calls to logging methods (e.g. `logger.info`) and writes to a log file (or log stream) | ||
* There is a possibility of the most recently buffered log messages being lost (up to 4KB of logs) | ||
* For instance, a powercut will mean up to 4KB of buffered logs will be lost | ||
* A sigkill (or other untrappable signal) will probably result in the same | ||
* If writing to a stream other than `process.stdout` or `process.stderr`, there is a slight possibility of lost logs or even partially written logs if the OS buffers don't have enough space, or something else is being written to the stream (or maybe some other reason we've not thought of) | ||
* If you supply an alternate stream to the constructor, then that stream must support synchronous writes so that it can be properly flushed on exit. This means the stream must expose its file descriptor via `stream.fd` or `stream._handle.fd`. Usually they have to be native (from core) stream, meaning a TCP/unix socket, a file, or stdout/sderr. If your stream is invalid an `error` event will be emitted on the returned logger, e.g.: | ||
```js | ||
var stream = require('stream') | ||
var pino = require('pino') | ||
var logger = pino({extreme: true}, new stream.Writable({write: function (chunk) { | ||
// do something with chunk | ||
}})) | ||
logger.on('error', function (err) { | ||
console.error('pino logger cannot flush on exit due to provided output stream') | ||
process.exit(1) | ||
}) | ||
``` | ||
So in summary, only use extreme mode if you're doing an extreme amount of logging, and you're happy in some scenarios to lose the most recent logs. | ||
</details> | ||
<a name="express"></a> | ||
## How to use Pino with Express | ||
<details> | ||
<summary>We've got you covered:</summary> | ||
```sh | ||
npm install --save express-pino-logger | ||
``` | ||
```js | ||
var app = require('express')() | ||
var pino = require('express-pino-logger')() | ||
app.use(pino) | ||
app.get('/', function (req, res) { | ||
req.log.info('something') | ||
res.send('hello world') | ||
}) | ||
app.listen(3000) | ||
``` | ||
See the [express-pino-logger readme](http://npm.im/express-pino-logger) for more info. | ||
</details> | ||
<a name="hapi"></a> | ||
## How to use Pino with Hapi | ||
<details> | ||
<summary>We've got you covered:</summary> | ||
```sh | ||
npm install --save hapi-pino | ||
``` | ||
```js | ||
'use strict' | ||
const Hapi = require('hapi') | ||
const server = new Hapi.Server() | ||
server.connection({ port: 3000 }) | ||
server.route({ | ||
method: 'GET', | ||
path: '/', | ||
handler: function (request, reply) { | ||
request.logger.info('In handler %s', request.path) | ||
return reply('hello world') | ||
} | ||
}) | ||
server.register(require('hapi-pino'), (err) => { | ||
if (err) { | ||
console.error(err) | ||
process.exit(1) | ||
} | ||
server.logger().info('another way for accessing it') | ||
// Start the server | ||
server.start((err) => { | ||
if (err) { | ||
console.error(err) | ||
process.exit(1) | ||
} | ||
}) | ||
}) | ||
``` | ||
See the [hapi-pino readme](http://npm.im/hapi-pino) for more info. | ||
</details> | ||
<a name="restify"></a> | ||
## How to use Pino with Restify | ||
<details> | ||
<summary>We've got you covered:</summary> | ||
```sh | ||
npm install --save restify-pino-logger | ||
``` | ||
```js | ||
var server = require('restify').createServer({name: 'server'}) | ||
var pino = require('restify-pino-logger')() | ||
server.use(pino) | ||
server.get('/', function (req, res) { | ||
req.log.info('something') | ||
res.send('hello world') | ||
}) | ||
server.listen(3000) | ||
``` | ||
See the [restify-pino-logger readme](http://npm.im/restify-pino-logger) for more info. | ||
</details> | ||
<a name="koa"></a> | ||
## How to use Pino with koa | ||
<details> | ||
<summary>We've got you covered:</summary> | ||
### Koa v1 | ||
```sh | ||
npm install --save koa-pino-logger@1 | ||
``` | ||
```js | ||
var app = require('koa')() | ||
var pino = require('koa-pino-logger')() | ||
app.use(pino) | ||
app.use(function * () { | ||
this.log.info('something else') | ||
this.body = 'hello world' | ||
}) | ||
app.listen(3000) | ||
``` | ||
See the [koa-pino-logger v1 readme](https://github.com/pinojs/koa-pino-logger/tree/v1) for more info. | ||
### Koa v2 | ||
```sh | ||
npm install --save koa-pino-logger@2 | ||
``` | ||
```js | ||
var Koa = require('koa') | ||
var app = new Koa() | ||
var pino = require('koa-pino-logger')() | ||
app.use(pino) | ||
app.use((ctx) => { | ||
ctx.log.info('something else') | ||
ctx.body = 'hello world' | ||
}) | ||
app.listen(3000) | ||
``` | ||
See the [koa-pino-logger v2 readme](https://github.com/pinojs/koa-pino-logger/tree/v2) for more info. | ||
</details> | ||
<a name="debug"></a> | ||
## How to use Pino with debug | ||
<details> | ||
<summary> Capture debug logs in JSON format, at 10x-20x the speed: </summary> | ||
The popular [`debug`](http://npm.im/debug) which | ||
used in many modules accross the ecosystem. | ||
The [`pino-debug`](http://github.com/pinojs/pino-debug) | ||
can captures calls to the `debug` loggers and run them | ||
through `pino` instead. This results in a 10x (20x in extreme mode) | ||
performance improvement, while logging out more information, in the | ||
usual JSON format. | ||
The quick start way to enable this is simply to install [`pino-debug`](http://github.com/pinojs/pino-debug) | ||
and preload it with the `-r` flag, enabling any `debug` logs with the | ||
`DEBUG` environment variable: | ||
```sh | ||
$ npm i --save pino-debug | ||
$ DEBUG=* node -r pino-debug app.js | ||
``` | ||
[`pino-debug`](http://github.com/pinojs/pino-debug) also offers fine grain control to map specific `debug` | ||
namespaces to `pino` log levels. See [`pino-debug`](http://github.com/pinojs/pino-debug) | ||
for more. | ||
</details> | ||
<a name="rotate"></a> | ||
## How do I rotate log files? | ||
<details> | ||
<summary>Use a separate tool for log rotation:</summary> | ||
We recommend [logrotate](https://github.com/logrotate/logrotate) | ||
Consider we output our logs to `/var/log/myapp.log` like so: | ||
``` | ||
> node server.js > /var/log/myapp.log | ||
``` | ||
We would rotate our log files with logrotate, by adding the following to `/etc/logrotate.d/myapp`: | ||
``` | ||
/var/log/myapp.log { | ||
su root | ||
daily | ||
rotate 7 | ||
delaycompress | ||
compress | ||
notifempty | ||
missingok | ||
copytruncate | ||
} | ||
``` | ||
</details> | ||
<a name="redact"></a> | ||
## How do I redact sensitive information?? | ||
<details> | ||
<summary> Use [pino-noir](http://npm.im/pino-noir) for performant log redaction: </summary> | ||
Install and require [pino-noir](http://npm.im/pino-noir), | ||
initialize with the key paths you wish to redact and pass the | ||
resulting instance in through the `serializers` option | ||
```js | ||
var noir = require('pino-noir') | ||
var pino = require('pino')({ | ||
serializers: noir(['key', 'path.to.key']) | ||
}) | ||
pino.info({ | ||
key: 'will be redacted', | ||
path: { | ||
to: {key: 'sensitive', another: 'thing'} | ||
}, | ||
more: 'stuff' | ||
}) | ||
// {"pid":7306,"hostname":"x","level":30,"time":1475519922198,"key":"[Redacted]","path":{"to":{"key":"[Redacted]","another":"thing"}},"more":"stuff","v":1} | ||
``` | ||
If you have other serializers simply extend: | ||
```js | ||
var noir = require('pino-noir') | ||
var pino = require('pino')({ | ||
serializers: Object.assign( | ||
noir(['key', 'path.to.key']), | ||
{myCustomSerializer: () => {}} | ||
}) | ||
``` | ||
</details> | ||
<a name="transports"></a> | ||
## How to use Transports with Pino | ||
<details> | ||
<summary>Create a separate process and pipe to it:</summary> | ||
For example: | ||
```js | ||
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, split(JSON.parse), myTransport) | ||
``` | ||
```sh | ||
node my-app-which-logs-stuff-to-stdout.js | node my-transport-process.js | ||
``` | ||
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! | ||
<a name="pino-elasticsearch"></a> | ||
### pino-elasticsearch | ||
[pino-elasticsearch][pino-elasticsearch] uploads the log lines in bulk | ||
to [Elasticsearch][elasticsearch], to be displayed in [Kibana][kibana]. | ||
It is extremely simple to use and setup | ||
```sh | ||
$ node yourapp.js | pino-elasticsearch | ||
``` | ||
Assuming Elasticsearch is running on localhost. | ||
If you wish to connect to an external elasticsearch instance (recommended for production): | ||
* Check that you defined `network.host` in your `elasticsearch.yml` configuration file. See [elasticsearch Network Settings documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html#common-network-settings) for more details. | ||
* Launch: | ||
```sh | ||
$ node yourapp.js | pino-elasticsearch --host 192.168.1.42 | ||
``` | ||
Assuming Elasticsearch is running on `192.168.1.42`. | ||
Then, head to your | ||
Kibana instance, and [create an index pattern](https://www.elastic.co/guide/en/kibana/current/setup.html) on `'pino'`, | ||
the default for `pino-elasticsearch`. | ||
[pino-elasticsearch]: https://github.com/pinojs/pino-elasticsearch | ||
<a name="pino-socket"></a> | ||
### pino-socket | ||
[pino-socket][pino-socket] is a transport that will forward logs to a IPv4 | ||
UDP or TCP socket. | ||
As an example, use `socat` to fake a listener: | ||
```sh | ||
$ socat -v udp4-recvfrom:6000,fork exec:'/bin/cat' | ||
``` | ||
And then run an application that uses `pino` for logging: | ||
```sh | ||
$ node yourapp.js | pino-socket -p 6000 | ||
``` | ||
You should see the logs from your application on both consoles. | ||
<a name="pino-syslog"></a> | ||
### pino-syslog | ||
[pino-syslog][pino-syslog] is a transport, really a "transform," that converts | ||
*pino's* logs to [RFC3164][rfc3164] compatible log messages. *pino-syslog* does not | ||
forward the logs anywhere, it merely re-writes the messages to `stdout`. But | ||
in combination with *pino-socket*, you can relay logs to a syslog server: | ||
```sh | ||
$ node yourapp.js | pino-syslog | pino-socket -a syslog.example.com | ||
``` | ||
Example output for the "hello world" log: | ||
``` | ||
<134>Apr 1 16:44:58 MacBook-Pro-3 none[94473]: {"pid":94473,"hostname":"MacBook-Pro-3","level":30,"msg":"hello world","time":1459529098958,"v":1} | ||
``` | ||
[pino-syslog]: https://www.npmjs.com/package/pino-syslog | ||
[rfc3164]: https://tools.ietf.org/html/rfc3164 | ||
#### Logstash | ||
You can also use [pino-socket][pino-socket] to upload logs to | ||
[Logstash][logstash] via: | ||
``` | ||
$ node yourapp.js | pino-socket -a 127.0.0.1 -p 5000 -m tcp | ||
``` | ||
Assuming your logstash is running on the same host and configured as | ||
follows: | ||
``` | ||
input { | ||
tcp { | ||
port => 5000 | ||
} | ||
} | ||
filter { | ||
json { | ||
source => "message" | ||
} | ||
} | ||
output { | ||
elasticsearch { | ||
hosts => "127.0.0.1:9200" | ||
} | ||
} | ||
``` | ||
See https://www.elastic.co/guide/en/kibana/current/setup.html to learn | ||
how to setup [Kibana][kibana]. | ||
If you are a Docker fan, you can use | ||
https://github.com/deviantony/docker-elk to setup an ELK stack. | ||
[pino-socket]: https://www.npmjs.com/package/pino-socket | ||
<a name="browser"></a> | ||
## Pino in the browser | ||
<summary>Pino is compatible with [`browserify`](http://npm.im) for browser side usage:</summary> | ||
Pino is compatible with [`browserify`](http://npm.im) for browser side usage: | ||
@@ -1081,3 +194,2 @@ This can be useful with isomorphic/universal JavaScript code. | ||
parents and children will end up in log output. | ||
</details> | ||
@@ -1084,0 +196,0 @@ <a name="team"></a> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
97758
7
26
244
3
- Removedcore-util-is@^1.0.2
Updatedfast-safe-stringify@^1.1.3
Updatedflatstr@^1.0.4