Comparing version 6.1.1 to 6.2.0
@@ -14,2 +14,3 @@ # API | ||
* [logger.fatal()](#fatal) | ||
* [logger.silent()](#silent) | ||
* [logger.child()](#child) | ||
@@ -147,2 +148,3 @@ * [logger.bindings()](#bindings) | ||
<a id="logmethod"></a> | ||
##### `logMethod` | ||
@@ -488,17 +490,34 @@ | ||
```js | ||
logger.info('hello', 'world') | ||
// {"level":30,"time":1531257618044,"msg":"hello world","pid":55956,"hostname":"x"} | ||
logger.info('%o hello %s', {worldly: 1}, 'world') | ||
// {"level":30,"time":1531257826880,"msg":"{\"worldly\":1} hello world","pid":55956,"hostname":"x"} | ||
``` | ||
Since pino v6, we do not automatically concatenate and cast to string | ||
consecutive parameters: | ||
```js | ||
logger.info('hello', {worldly: 1}) | ||
// {"level":30,"time":1531257797727,"msg":"hello {\"worldly\":1}","pid":55956,"hostname":"x"} | ||
logger.info('hello', 'world') | ||
// {"level":30,"time":1531257618044,"msg":"hello","pid":55956,"hostname":"x"} | ||
// world is missing | ||
``` | ||
However, it's possible to inject a hook to modify this behavior: | ||
```js | ||
logger.info('%o hello', {worldly: 1}) | ||
// {"level":30,"time":1531257826880,"msg":"{\"worldly\":1} hello","pid":55956,"hostname":"x"} | ||
const pinoOptions = { | ||
hooks: { logMethod } | ||
} | ||
function logMethod (args, method) { | ||
if (args.length === 2) { | ||
args[0] = `${args[0]} %j` | ||
} | ||
method.apply(this, args) | ||
} | ||
const logger = pino(pinoOptions) | ||
``` | ||
* See [`message` log method parameter](#message) | ||
* See [`logMethod` hook](#logmethod) | ||
@@ -566,3 +585,7 @@ <a id="trace"></a> | ||
<a id="silent"><a> | ||
### `logger.silent()` | ||
Noop function. | ||
<a id="child"></a> | ||
@@ -676,3 +699,3 @@ ### `logger.child(bindings) => logger` | ||
The `silent` logging level is a specialized level which will disable all logging, | ||
there is no `silent` log method. | ||
the `silent` log method is a noop function. | ||
@@ -679,0 +702,0 @@ <a id="islevelenabled"></a> |
@@ -9,2 +9,3 @@ # Help | ||
* [Transports and systemd](#transport-systemd) | ||
* [Log to different streams](#multi-stream) | ||
* [Duplicate keys](#dupe-keys) | ||
@@ -160,2 +161,28 @@ * [Log levels as labels instead of numbers](#level-string) | ||
<a id="multi-stream"></a> | ||
## Log to different streams | ||
Pino's default log destination is the singular destination of `stdout`. While | ||
not recommended for performance reasons, multiple destinations can be targeted | ||
by using [`pino-multi-stream`](https://github.com/pinojs/pino-multi-stream). | ||
In this example we use `stderr` for `error` level logs and `stdout` as default | ||
for all other levels (e.g. `debug`, `info`, and `warn`). | ||
```js | ||
const pino = require('pino') | ||
const { multistream } = require('pino-multi-stream') | ||
var streams = [ | ||
{level: 'debug', stream: process.stdout}, | ||
{level: 'error', stream: process.stderr}, | ||
{level: 'fatal', stream: process.stderr} | ||
] | ||
const logger = pino({ | ||
name: 'my-app', | ||
level: 'info', | ||
}, multistream(streams)) | ||
``` | ||
<a id="dupe-keys"></a> | ||
@@ -162,0 +189,0 @@ ## How Pino handles duplicate keys |
@@ -166,2 +166,3 @@ 'use strict' | ||
stream.lastObj = obj | ||
stream.lastMsg = msg | ||
stream.lastTime = t.slice(this[timeSliceIndexSym]) | ||
@@ -168,0 +169,0 @@ stream.lastLogger = this // for child loggers |
@@ -241,8 +241,17 @@ 'use strict' | ||
var lastObj = this.lastObj | ||
var lastMsg = this.lastMsg | ||
var errorProps = null | ||
const formatters = lastLogger[formattersSym] | ||
const formattedObj = formatters.log ? formatters.log(lastObj) : lastObj | ||
const messageKey = lastLogger[messageKeySym] | ||
if (lastMsg && formattedObj && !formattedObj.hasOwnProperty(messageKey)) { | ||
formattedObj[messageKey] = lastMsg | ||
} | ||
const obj = Object.assign({ | ||
level: this.lastLevel, | ||
time | ||
}, lastObj, errorProps) | ||
}, formattedObj, errorProps) | ||
@@ -249,0 +258,0 @@ const serializers = lastLogger[serializersSym] |
{ | ||
"name": "pino", | ||
"version": "6.1.1", | ||
"version": "6.2.0", | ||
"description": "super fast, all natural json logger", | ||
@@ -5,0 +5,0 @@ "main": "pino.js", |
@@ -16,3 +16,4 @@ 'use strict' | ||
buildSafeSonicBoom, | ||
buildFormatters | ||
buildFormatters, | ||
noop | ||
} = require('./lib/tools') | ||
@@ -169,3 +170,4 @@ const { version } = require('./lib/meta') | ||
[formattersSym]: allFormatters, | ||
[hooksSym]: hooks | ||
[hooksSym]: hooks, | ||
silent: noop | ||
}) | ||
@@ -172,0 +174,0 @@ Object.setPrototypeOf(instance, proto) |
@@ -501,1 +501,53 @@ 'use strict' | ||
}) | ||
test('calling silent method on logger instance', async ({ fail }) => { | ||
const instance = pino({ level: 'silent' }, sink((result, enc) => { | ||
fail('no data should be logged') | ||
})) | ||
instance.silent('hello world') | ||
}) | ||
test('calling silent method on child logger', async ({ fail }) => { | ||
const child = pino({ level: 'silent' }, sink((result, enc) => { | ||
fail('no data should be logged') | ||
})).child({}) | ||
child.silent('hello world') | ||
}) | ||
test('changing level from info to silent and back to info', async ({ is }) => { | ||
const expected = { | ||
level: 30, | ||
msg: 'hello world' | ||
} | ||
const stream = sink() | ||
const instance = pino({ level: 'info' }, stream) | ||
instance.level = 'silent' | ||
instance.info('hello world') | ||
let result = stream.read() | ||
is(result, null) | ||
instance.level = 'info' | ||
instance.info('hello world') | ||
result = await once(stream, 'data') | ||
check(is, result, expected.level, expected.msg) | ||
}) | ||
test('changing level from info to silent and back to info in child logger', async ({ is }) => { | ||
const expected = { | ||
level: 30, | ||
msg: 'hello world' | ||
} | ||
const stream = sink() | ||
const child = pino({ level: 'info' }, stream).child({}) | ||
child.level = 'silent' | ||
child.info('hello world') | ||
let result = stream.read() | ||
is(result, null) | ||
child.level = 'info' | ||
child.info('hello world') | ||
result = await once(stream, 'data') | ||
check(is, result, expected.level, expected.msg) | ||
}) |
@@ -17,2 +17,3 @@ 'use strict' | ||
is(30, this.lastLevel) | ||
is('a msg', this.lastMsg) | ||
ok(Number(this.lastTime) >= now) | ||
@@ -42,2 +43,3 @@ same(this.lastObj, { hello: 'world', msg: 'a msg' }) | ||
is(30, this.lastLevel) | ||
is('a msg', this.lastMsg) | ||
same(this.lastObj, { from: 'child', msg: 'a msg' }) | ||
@@ -68,2 +70,3 @@ const result = JSON.parse(chunk) | ||
is(30, this.lastLevel) | ||
is('a msg', this.lastMsg) | ||
same({ msg: 'a msg' }, this.lastObj) | ||
@@ -70,0 +73,0 @@ const result = JSON.parse(chunk) |
@@ -115,2 +115,15 @@ 'use strict' | ||
test('applies formatters', async ({ is, isNot }) => { | ||
var actual = '' | ||
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'formatters.js')]) | ||
child.stdout.pipe(writer((s, enc, cb) => { | ||
actual += s | ||
cb() | ||
})) | ||
await once(child, 'close') | ||
isNot(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) | ||
isNot(strip(actual).match(/foo: "formatted_bar"/), null) | ||
}) | ||
test('parses and outputs chindings with serializer', async ({ is, isNot }) => { | ||
@@ -117,0 +130,0 @@ var actual = '' |
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
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
301054
82
7080
28