Comparing version 7.11.0 to 8.0.0
@@ -181,2 +181,20 @@ # API | ||
As of pino 7.x, when the `mixin` is used with the [`nestedKey` option](#opt-nestedkey), | ||
the object returned from the `mixin` method will also be nested. Prior versions would mix | ||
this object into the root. | ||
```js | ||
const logger = pino({ | ||
nestedKey: 'payload', | ||
mixin() { | ||
return { requestId: requestId.currentId() } | ||
} | ||
}) | ||
logger.info({ | ||
description: 'Ok' | ||
}, 'Message 1') | ||
// {"level":30,"time":1591195061437,"pid":16012,"hostname":"x","payload":{"requestId":"dfe9a9014b","description":"Ok"},"msg":"Message 1"} | ||
``` | ||
<a id="opt-mixin-merge-strategy"></a> | ||
@@ -444,23 +462,2 @@ #### `mixinMergeStrategy` (Function): | ||
<a id=prettyPrint></a> | ||
#### `prettyPrint` (Boolean | Object) | ||
Default: `false` | ||
__DEPRECATED: look at [pino-pretty documentation](https://github.com/pinojs/pino-pretty) | ||
for alternatives__. Using a [`transport`](#transport) is also an option.__ | ||
Enables pretty printing log logs. This is intended for non-production | ||
configurations. This may be set to a configuration object as outlined in the | ||
[`pino-pretty` documentation](https://github.com/pinojs/pino-pretty). | ||
The options object may additionally contain a `prettifier` property to define | ||
which prettifier module to use. When not present, `prettifier` defaults to | ||
`'pino-pretty'`. Regardless of the value, the specified prettifier module | ||
must be installed as a separate dependency: | ||
```sh | ||
npm install pino-pretty | ||
``` | ||
#### `browser` (Object) | ||
@@ -988,3 +985,3 @@ | ||
* `previousLevelLabel` – the prior level string, e.g `info` | ||
* `previousLevelValue` – the prior level numbebr, e.g `30` | ||
* `previousLevelValue` – the prior level number, e.g `30` | ||
@@ -1027,3 +1024,3 @@ ```js | ||
Create a Pino Destination instance: a stream-like object with | ||
significantly more throughput (over 30%) than a standard Node.js stream. | ||
significantly more throughput than a standard Node.js stream. | ||
@@ -1037,4 +1034,8 @@ ```js | ||
minLength: 4096, // Buffer before writing | ||
sync: false // Asynchronous logging | ||
sync: false // Asynchronous logging, the default | ||
})) | ||
const logger4 = pino(pino.destination({ | ||
dest: './my-file2', | ||
sync: true // Synchronous logging | ||
})) | ||
``` | ||
@@ -1338,3 +1339,3 @@ | ||
Returns a cloned object of the current instance but with the the provided `level`. | ||
Returns a cloned object of the current instance but with the provided `level`. | ||
@@ -1341,0 +1342,0 @@ ### `StreamEntry` |
# Asynchronous Logging | ||
In essence, asynchronous logging enables even faster performance by Pino. | ||
In essence, asynchronous logging enables the minimum overhead of Pino. | ||
Asynchronous logging works by buffering log messages and writing them in larger chunks. | ||
In Pino's standard mode of operation log messages are directly written to the | ||
output stream as the messages are generated with a _blocking_ operation. | ||
Asynchronous logging works by buffering | ||
log messages and writing them in larger chunks. | ||
```js | ||
@@ -19,2 +15,6 @@ const pino = require('pino') | ||
It's always possible to turn on synchronous logging by passing `sync: true`. | ||
In this mode of operation log messages are directly written to the | ||
output stream, as the messages are generated with a _blocking_ operation. | ||
* See [`pino.destination`](/docs/api.md#pino-destination) | ||
@@ -25,65 +25,6 @@ * `pino.destination` is implemented on [`sonic-boom` ⇗](https://github.com/mcollina/sonic-boom). | ||
On AWS Lambda we recommend to call `dest.flushSync()` at the end | ||
Asynchronous logging is disabled by default on AWS Lambda, or any other environment | ||
that modifies `process.stdout`. If forcefully turned on, we recommend to call `dest.flushSync()` at the end | ||
of each function execution to avoid losing data. | ||
## Usage | ||
The `pino.destination({ sync: false })` method will provide an asynchronous destination. | ||
```js | ||
const pino = require('pino') | ||
const dest = pino.destination({ sync: false }) // logs to stdout with no args | ||
const logger = pino(dest) | ||
``` | ||
<a id='log-loss-prevention'></a> | ||
## Prevent log loss in Node v12 | ||
In Node.js v14+, streams created by `pino.destination()` are automatically | ||
flushed whenever the process exits. | ||
In Node v12, `pino.final()` can be used to prevent log loss. Here is an example: | ||
```js | ||
const pino = require('pino') | ||
const dest = pino.destination({ sync: false }) | ||
const logger = pino(dest) | ||
// asynchronously flush every 10 seconds to keep the buffer empty | ||
// in periods of low activity | ||
setInterval(function () { | ||
logger.flush() | ||
}, 10000).unref() | ||
// use pino.final to create a special logger that | ||
// guarantees final tick writes | ||
const handler = pino.final(logger, (err, finalLogger, evt) => { | ||
finalLogger.info(`${evt} caught`) | ||
if (err) finalLogger.error(err, 'error caused exit') | ||
process.exit(err ? 1 : 0) | ||
}) | ||
// catch all the ways node might exit | ||
process.on('beforeExit', () => handler(null, 'beforeExit')) | ||
process.on('exit', () => handler(null, 'exit')) | ||
process.on('uncaughtException', (err) => handler(err, 'uncaughtException')) | ||
process.on('SIGINT', () => handler(null, 'SIGINT')) | ||
process.on('SIGQUIT', () => handler(null, 'SIGQUIT')) | ||
process.on('SIGTERM', () => handler(null, 'SIGTERM')) | ||
``` | ||
The above code will register handlers for the following process events/signals so that | ||
pino can flush the asynchronous logger buffer: | ||
+ `beforeExit` | ||
+ `exit` | ||
+ `uncaughtException` | ||
+ `SIGINT` | ||
+ `SIGQUIT` | ||
+ `SIGTERM` | ||
In all of these cases, except `SIGHUP`, the process is in a state that it | ||
*must* terminate. Note that the handler has a `process.exit(1)` at the end. | ||
* See also [`pino.final` api](/docs/api.md#pino-final) | ||
## Caveats | ||
@@ -97,5 +38,2 @@ | ||
in case of a system failure, e.g. a power cut. | ||
* In Node v14+, Pino will register handlers for the `exit` and `beforeExit` handler so that | ||
the stream is flushed automatically. This is implemented with the usage of | ||
[`on-exit-leak-free`](https://github.com/mcollina/on-exit-leak-free). | ||
@@ -102,0 +40,0 @@ See also: |
@@ -0,17 +1,18 @@ | ||
# Benchmarks | ||
The following values show the time spent to call each function 100000 times. | ||
`pino.info('hello world')`: | ||
``` | ||
BASIC benchmark averages | ||
Bunyan average: 662.904ms | ||
Winston average: 564.752ms | ||
Bole average: 301.894ms | ||
Debug average: 361.052ms | ||
LogLevel average: 330.394ms | ||
Pino average: 246.336ms | ||
PinoAsync average: 129.507ms | ||
PinoNodeStream average: 276.479ms | ||
Bunyan average: 377.434ms | ||
Winston average: 270.249ms | ||
Bole average: 172.690ms | ||
Debug average: 220.527ms | ||
LogLevel average: 222.802ms | ||
Pino average: 114.801ms | ||
PinoMinLength average: 70.968ms | ||
PinoNodeStream average: 159.192ms | ||
``` | ||
@@ -22,10 +23,12 @@ | ||
``` | ||
OBJECT benchmark averages | ||
BunyanObj average: 678.477ms | ||
WinstonObj average: 563.154ms | ||
BoleObj average: 364.748ms | ||
LogLevelObject average: 627.196ms | ||
PinoObj average: 237.543ms | ||
PinoAsyncObj average: 125.532ms | ||
PinoNodeStreamObj average: 310.614ms | ||
BunyanObj average: 410.379ms | ||
WinstonObj average: 273.120ms | ||
BoleObj average: 185.069ms | ||
LogLevelObject average: 433.425ms | ||
PinoObj average: 119.315ms | ||
PinoMinLengthObj average: 76.968ms | ||
PinoNodeStreamObj average: 164.268ms | ||
``` | ||
@@ -36,10 +39,12 @@ | ||
``` | ||
DEEPOBJECT benchmark averages | ||
BunyanDeepObj average: 1838.970ms | ||
WinstonDeepObj average: 3173.947ms | ||
BoleDeepObj average: 2888.894ms | ||
LogLevelDeepObj average: 7426.592ms | ||
PinoDeepObj average: 3074.177ms | ||
PinoAsyncDeepObj average: 2987.925ms | ||
PinoNodeStreamDeepObj average: 3459.883ms | ||
DEEP-OBJECT benchmark averages | ||
BunyanDeepObj average: 1.839ms | ||
WinstonDeepObj average: 5.604ms | ||
BoleDeepObj average: 3.422ms | ||
LogLevelDeepObj average: 11.716ms | ||
PinoDeepObj average: 2.256ms | ||
PinoMinLengthDeepObj average: 2.240ms | ||
PinoNodeStreamDeepObj average: 2.595ms | ||
``` | ||
@@ -49,13 +54,5 @@ | ||
``` | ||
BunyanInterpolateExtra average: 971.019ms | ||
WinstonInterpolateExtra average: 535.009ms | ||
BoleInterpolateExtra average: 575.668ms | ||
PinoInterpolateExtra average: 332.099ms | ||
PinoAsyncInterpolateExtra average: 209.552ms | ||
PinoNodeStreamInterpolateExtra average: 413.195ms | ||
``` | ||
For a fair comparison, [LogLevel](http://npm.im/loglevel) was extended | ||
to include a timestamp and [bole](http://npm.im/bole) had | ||
`fastTime` mode switched on. | ||
For a fair comparison, [LogLevel](https://npm.im/loglevel) was extended | ||
to include a timestamp and [bole](https://npm.im/bole) had | ||
`fastTime` mode switched on. |
@@ -15,3 +15,3 @@ # Bundling | ||
The variable is a object whose keys are identifier for the files and the the values are the paths of files relative to the currently bundle files. | ||
The variable is a object whose keys are identifier for the files and the values are the paths of files relative to the currently bundle files. | ||
@@ -18,0 +18,0 @@ Example: |
@@ -72,4 +72,5 @@ # Pino Ecosystem | ||
+ [`cls-proxify`](https://github.com/keenondrums/cls-proxify): integration of pino and [CLS](https://github.com/jeff-lewis/cls-hooked). Useful for creating dynamically configured child loggers (e.g. with added trace ID) for each request. | ||
+ [`pino-tiny`](https://github.com/holmok/pino-tiny): a tiny (and exentsible?) little log formatter for pino. | ||
+ [`pino-tiny`](https://github.com/holmok/pino-tiny): a tiny (and extensible?) little log formatter for pino. | ||
+ [`pino-dev`](https://github.com/dnjstrom/pino-dev): simple prettifier for pino with built-in support for common ecosystem packages. | ||
+ [`@newrelic/pino-enricher`](https://github.com/newrelic/newrelic-node-log-extensions/blob/main/packages/pino-log-enricher): a log customization to add New Relic context to use [Logs In Context](https://docs.newrelic.com/docs/logs/logs-context/logs-in-context/) | ||
+ [`pino-lambda`](https://github.com/FormidableLabs/pino-lambda): log transport for cloudwatch support inside aws-lambda |
@@ -13,3 +13,3 @@ # Help | ||
* [Unicode and Windows terminal](#windows) | ||
* [Mapping Pino Log Levels to Google Cloud Logging (Stackdriver) Serverity Levels](#stackdriver) | ||
* [Mapping Pino Log Levels to Google Cloud Logging (Stackdriver) Severity Levels](#stackdriver) | ||
* [Avoid Message Conflict](#avoid-message-conflict) | ||
@@ -205,3 +205,3 @@ * [Exit logging](#exit-logging) | ||
<a id="stackdriver"></a> | ||
## Mapping Pino Log Levels to Google Cloud Logging (Stackdriver) Serverity Levels | ||
## Mapping Pino Log Levels to Google Cloud Logging (Stackdriver) Severity Levels | ||
@@ -211,3 +211,3 @@ Google Cloud Logging uses `severity` levels instead log levels. As a result, all logs may show as INFO | ||
log data is present inside a `message` key instead of the default `msg` key that Pino uses. Use a technique | ||
similar to the one below to retain log levels in Google Clould Logging | ||
similar to the one below to retain log levels in Google Cloud Logging | ||
@@ -214,0 +214,0 @@ ```js |
@@ -6,3 +6,3 @@ # Redaction | ||
To redact sensitive information, supply paths to keys that hold sensitive data | ||
using the `redact` option. Note that paths which contain hypens need to use | ||
using the `redact` option. Note that paths which contain hyphens need to use | ||
brackets in order to access the hyphenated property: | ||
@@ -9,0 +9,0 @@ |
@@ -381,2 +381,3 @@ # Transports | ||
+ [pino-loki](#pino-loki) | ||
+ [pino-seq-transport](#pino-seq-transport) | ||
@@ -597,3 +598,3 @@ ### Legacy | ||
Worker : | ||
Worker : | ||
```js | ||
@@ -687,2 +688,20 @@ const pino = require('pino') | ||
<a id="pino-seq-transport"></a> | ||
### pino-seq-transport | ||
[pino-seq-transport][pino-seq-transport] is a Pino v7+ compatible transport to forward log events to [Seq][Seq] | ||
from a dedicated worker: | ||
```js | ||
const pino = require('pino') | ||
const transport = pino.transport({ | ||
target: '@autotelic/pino-seq-transport', | ||
options: { serverUrl: 'http://localhost:5341' } | ||
}) | ||
pino(transport) | ||
``` | ||
[pino-seq-transport]: https://github.com/autotelic/pino-seq-transport | ||
[Seq]: https://datalust.co/seq | ||
<a id="pino-socket"></a> | ||
@@ -689,0 +708,0 @@ ### pino-socket |
@@ -6,6 +6,4 @@ 'use strict' | ||
const warnName = 'PinoWarning' | ||
// const warnName = 'PinoWarning' | ||
warning.create(warnName, 'PINODEP008', 'prettyPrint is deprecated, look at https://github.com/pinojs/pino-pretty for alternatives.') | ||
warning.create(warnName, 'PINODEP009', 'The use of pino.final is discouraged in Node.js v14+ and not required. It will be removed in the next major version') | ||
// warning.create(warnName, 'PINODEP010', 'A new deprecation') |
@@ -12,3 +12,2 @@ 'use strict' | ||
const chindingsSym = Symbol('pino.chindings') | ||
const parsedChindingsSym = Symbol('pino.parsedChindings') | ||
@@ -49,3 +48,2 @@ const asJsonSym = Symbol('pino.asJson') | ||
chindingsSym, | ||
parsedChindingsSym, | ||
asJsonSym, | ||
@@ -52,0 +50,0 @@ writeSym, |
238
lib/tools.js
@@ -8,7 +8,6 @@ 'use strict' | ||
const SonicBoom = require('sonic-boom') | ||
const warning = require('./deprecations') | ||
const onExit = require('on-exit-leak-free') | ||
const { | ||
lsCacheSym, | ||
chindingsSym, | ||
parsedChindingsSym, | ||
writeSym, | ||
@@ -22,5 +21,2 @@ serializersSym, | ||
wildcardFirstSym, | ||
needsMetadataGsym, | ||
redactFmtSym, | ||
streamSym, | ||
nestedKeySym, | ||
@@ -215,119 +211,2 @@ formattersSym, | ||
function getPrettyStream (opts, prettifier, dest, instance) { | ||
if (prettifier && typeof prettifier === 'function') { | ||
prettifier = prettifier.bind(instance) | ||
return prettifierMetaWrapper(prettifier(opts), dest, opts) | ||
} | ||
try { | ||
const prettyFactory = require('pino-pretty').prettyFactory | ||
prettyFactory.asMetaWrapper = prettifierMetaWrapper | ||
return prettifierMetaWrapper(prettyFactory(opts), dest, opts) | ||
} catch (e) { | ||
if (e.message.startsWith("Cannot find module 'pino-pretty'")) { | ||
throw Error('Missing `pino-pretty` module: `pino-pretty` must be installed separately') | ||
}; | ||
throw e | ||
} | ||
} | ||
function prettifierMetaWrapper (pretty, dest, opts) { | ||
opts = Object.assign({ suppressFlushSyncWarning: false }, opts) | ||
let warned = false | ||
return { | ||
[needsMetadataGsym]: true, | ||
lastLevel: 0, | ||
lastMsg: null, | ||
lastObj: null, | ||
lastLogger: null, | ||
flushSync () { | ||
if (opts.suppressFlushSyncWarning || warned) { | ||
return | ||
} | ||
warned = true | ||
setMetadataProps(dest, this) | ||
dest.write(pretty(Object.assign({ | ||
level: 40, // warn | ||
msg: 'pino.final with prettyPrint does not support flushing', | ||
time: Date.now() | ||
}, this.chindings()))) | ||
}, | ||
chindings () { | ||
const lastLogger = this.lastLogger | ||
let chindings = null | ||
// protection against flushSync being called before logging | ||
// anything | ||
if (!lastLogger) { | ||
return null | ||
} | ||
if (lastLogger.hasOwnProperty(parsedChindingsSym)) { | ||
chindings = lastLogger[parsedChindingsSym] | ||
} else { | ||
chindings = JSON.parse('{' + lastLogger[chindingsSym].substr(1) + '}') | ||
lastLogger[parsedChindingsSym] = chindings | ||
} | ||
return chindings | ||
}, | ||
write (chunk) { | ||
const lastLogger = this.lastLogger | ||
const chindings = this.chindings() | ||
let time = this.lastTime | ||
/* istanbul ignore next */ | ||
if (typeof time === 'number') { | ||
// do nothing! | ||
} else if (time.match(/^\d+/)) { | ||
time = parseInt(time) | ||
} else { | ||
time = time.slice(1, -1) | ||
} | ||
const lastObj = this.lastObj | ||
const lastMsg = this.lastMsg | ||
const errorProps = null | ||
const formatters = lastLogger[formattersSym] | ||
const formattedObj = formatters.log ? formatters.log(lastObj) : lastObj | ||
const messageKey = lastLogger[messageKeySym] | ||
if (lastMsg && formattedObj && !Object.prototype.hasOwnProperty.call(formattedObj, messageKey)) { | ||
formattedObj[messageKey] = lastMsg | ||
} | ||
const obj = Object.assign({ | ||
level: this.lastLevel, | ||
time | ||
}, formattedObj, errorProps) | ||
const serializers = lastLogger[serializersSym] | ||
const keys = Object.keys(serializers) | ||
for (var i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
if (obj[key] !== undefined) { | ||
obj[key] = serializers[key](obj[key]) | ||
} | ||
} | ||
for (const key in chindings) { | ||
if (!obj.hasOwnProperty(key)) { | ||
obj[key] = chindings[key] | ||
} | ||
} | ||
const stringifiers = lastLogger[stringifiersSym] | ||
const redact = stringifiers[redactFmtSym] | ||
const formatted = pretty(typeof redact === 'function' ? redact(obj) : obj) | ||
if (formatted === undefined) return | ||
setMetadataProps(dest, this) | ||
dest.write(formatted) | ||
} | ||
} | ||
} | ||
function hasBeenTampered (stream) { | ||
@@ -342,3 +221,7 @@ return stream.write !== stream.constructor.prototype.write | ||
if (!opts.sync && isMainThread) { | ||
setupOnExit(stream) | ||
onExit.register(stream, autoEnd) | ||
stream.on('close', function () { | ||
onExit.unregister(stream) | ||
}) | ||
} | ||
@@ -348,3 +231,4 @@ return stream | ||
function filterBrokenPipe (err) { | ||
// TODO verify on Windows | ||
// Impossible to replicate across all operating systems | ||
/* istanbul ignore next */ | ||
if (err.code === 'EPIPE') { | ||
@@ -365,16 +249,2 @@ // If we get EPIPE, we should stop logging here | ||
function setupOnExit (stream) { | ||
/* istanbul ignore next */ | ||
if (global.WeakRef && global.WeakMap && global.FinalizationRegistry) { | ||
// This is leak free, it does not leave event handlers | ||
const onExit = require('on-exit-leak-free') | ||
onExit.register(stream, autoEnd) | ||
stream.on('close', function () { | ||
onExit.unregister(stream) | ||
}) | ||
} | ||
} | ||
function autoEnd (stream, eventName) { | ||
@@ -394,2 +264,4 @@ // This check is needed only on some platforms | ||
} else { | ||
// For some reason istanbul is not detecting this, but it's there | ||
/* istanbul ignore next */ | ||
// We do not have an event loop, so flush synchronously | ||
@@ -404,3 +276,3 @@ stream.flushSync() | ||
if (typeof opts === 'string') { | ||
stream = buildSafeSonicBoom({ dest: opts, sync: true }) | ||
stream = buildSafeSonicBoom({ dest: opts }) | ||
opts = {} | ||
@@ -411,3 +283,3 @@ } else if (typeof stream === 'string') { | ||
} | ||
stream = buildSafeSonicBoom({ dest: stream, sync: true }) | ||
stream = buildSafeSonicBoom({ dest: stream }) | ||
} else if (opts instanceof SonicBoom || opts.writable || opts._writableState) { | ||
@@ -434,24 +306,15 @@ stream = opts | ||
if (opts.prettyPrint) { | ||
throw new Error('prettyPrint option is no longer supported, see the pino-pretty package (https://github.com/pinojs/pino-pretty)') | ||
} | ||
if ('onTerminated' in opts) { | ||
throw Error('The onTerminated option has been removed, use pino.final instead') | ||
} | ||
if ('changeLevelName' in opts) { | ||
process.emitWarning( | ||
'The changeLevelName option is deprecated and will be removed in v7. Use levelKey instead.', | ||
{ code: 'changeLevelName_deprecation' } | ||
) | ||
opts.levelKey = opts.changeLevelName | ||
delete opts.changeLevelName | ||
} | ||
const { enabled, prettyPrint, prettifier, messageKey } = opts | ||
const { enabled } = opts | ||
if (enabled === false) opts.level = 'silent' | ||
stream = stream || process.stdout | ||
if (stream === process.stdout && stream.fd >= 0 && !hasBeenTampered(stream)) { | ||
stream = buildSafeSonicBoom({ fd: stream.fd, sync: true }) | ||
stream = buildSafeSonicBoom({ fd: stream.fd }) | ||
} | ||
if (prettyPrint) { | ||
warning.emit('PINODEP008') | ||
const prettyOpts = Object.assign({ messageKey }, prettyPrint) | ||
stream = getPrettyStream(prettyOpts, prettifier, stream, instance) | ||
} | ||
return { opts, stream } | ||
@@ -461,55 +324,2 @@ } | ||
function final (logger, handler) { | ||
const major = Number(process.versions.node.split('.')[0]) | ||
if (major >= 14) warning.emit('PINODEP009') | ||
if (typeof logger === 'undefined' || typeof logger.child !== 'function') { | ||
throw Error('expected a pino logger instance') | ||
} | ||
const hasHandler = (typeof handler !== 'undefined') | ||
if (hasHandler && typeof handler !== 'function') { | ||
throw Error('if supplied, the handler parameter should be a function') | ||
} | ||
const stream = logger[streamSym] | ||
if (typeof stream.flushSync !== 'function') { | ||
throw Error('final requires a stream that has a flushSync method, such as pino.destination') | ||
} | ||
const finalLogger = new Proxy(logger, { | ||
get: (logger, key) => { | ||
if (key in logger.levels.values) { | ||
return (...args) => { | ||
logger[key](...args) | ||
stream.flushSync() | ||
} | ||
} | ||
return logger[key] | ||
} | ||
}) | ||
if (!hasHandler) { | ||
try { | ||
stream.flushSync() | ||
} catch { | ||
// it's too late to wait for the stream to be ready | ||
// because this is a final tick scenario. | ||
// in practice there shouldn't be a situation where it isn't | ||
// however, swallow the error just in case (and for easier testing) | ||
} | ||
return finalLogger | ||
} | ||
return (err = null, ...args) => { | ||
try { | ||
stream.flushSync() | ||
} catch (e) { | ||
// it's too late to wait for the stream to be ready | ||
// because this is a final tick scenario. | ||
// in practice there shouldn't be a situation where it isn't | ||
// however, swallow the error just in case (and for easier testing) | ||
} | ||
return handler(err, finalLogger, ...args) | ||
} | ||
} | ||
function stringify (obj, stringifySafeFn) { | ||
@@ -536,12 +346,2 @@ try { | ||
function setMetadataProps (dest, that) { | ||
if (dest[needsMetadataGsym] === true) { | ||
dest.lastLevel = that.lastLevel | ||
dest.lastMsg = that.lastMsg | ||
dest.lastObj = that.lastObj | ||
dest.lastTime = that.lastTime | ||
dest.lastLogger = that.lastLogger | ||
} | ||
} | ||
/** | ||
@@ -566,3 +366,2 @@ * Convert a string integer file descriptor to a proper native integer | ||
buildSafeSonicBoom, | ||
getPrettyStream, | ||
asChindings, | ||
@@ -572,3 +371,2 @@ asJson, | ||
createArgsNormalizer, | ||
final, | ||
stringify, | ||
@@ -575,0 +373,0 @@ buildFormatters, |
@@ -10,2 +10,3 @@ 'use strict' | ||
/* istanbul ignore next */ | ||
if (global.WeakRef && global.WeakMap && global.FinalizationRegistry) { | ||
@@ -64,2 +65,3 @@ // This require MUST be top level otherwise the transport would | ||
function onExit () { | ||
/* istanbul ignore next */ | ||
if (stream.closed) { | ||
@@ -66,0 +68,0 @@ return |
{ | ||
"name": "pino", | ||
"version": "7.11.0", | ||
"version": "8.0.0", | ||
"description": "super fast, all natural json logger", | ||
@@ -88,6 +88,6 @@ "main": "pino.js", | ||
"import-fresh": "^3.2.1", | ||
"jest": "^27.3.1", | ||
"jest": "^28.1.0", | ||
"log": "^6.0.0", | ||
"loglevel": "^1.6.7", | ||
"pino-pretty": "^v7.6.0", | ||
"pino-pretty": "^v7.6.1", | ||
"pre-commit": "^1.2.2", | ||
@@ -106,3 +106,3 @@ "proxyquire": "^2.1.3", | ||
"tsd": "^0.20.0", | ||
"typescript": "^4.4.4", | ||
"typescript": "^4.5.2", | ||
"winston": "^3.3.3" | ||
@@ -113,11 +113,11 @@ }, | ||
"fast-redact": "^3.0.0", | ||
"on-exit-leak-free": "^0.2.0", | ||
"on-exit-leak-free": "^1.0.0", | ||
"pino-abstract-transport": "v0.5.0", | ||
"pino-std-serializers": "^4.0.0", | ||
"process-warning": "^1.0.0", | ||
"pino-std-serializers": "^5.0.0", | ||
"process-warning": "^2.0.0", | ||
"quick-format-unescaped": "^4.0.3", | ||
"real-require": "^0.1.0", | ||
"safe-stable-stringify": "^2.1.0", | ||
"sonic-boom": "^2.2.1", | ||
"thread-stream": "^0.15.1" | ||
"sonic-boom": "^3.0.0", | ||
"thread-stream": "^1.0.0" | ||
}, | ||
@@ -124,0 +124,0 @@ "tsd": { |
@@ -108,3 +108,4 @@ // Type definitions for pino 7.0 | ||
/** | ||
* Overwrites the bindings of this logger instance. | ||
* Adds to the bindings of this logger instance. | ||
* Note: Does not overwrite bindings. Can potentially result in duplicate keys in log lines. | ||
* | ||
@@ -111,0 +112,0 @@ * @param bindings: an object of key-value pairs to include in log lines as properties. |
@@ -15,3 +15,2 @@ 'use strict' | ||
asChindings, | ||
final, | ||
buildSafeSonicBoom, | ||
@@ -56,3 +55,2 @@ buildFormatters, | ||
enabled: true, | ||
prettyPrint: false, | ||
base: { pid, hostname }, | ||
@@ -197,3 +195,3 @@ serializers: Object.assign(Object.create(null), { | ||
} else { | ||
return buildSafeSonicBoom({ dest: normalizeDestFileDescriptor(dest), minLength: 0, sync: true }) | ||
return buildSafeSonicBoom({ dest: normalizeDestFileDescriptor(dest), minLength: 0 }) | ||
} | ||
@@ -205,3 +203,2 @@ } | ||
module.exports.final = final | ||
module.exports.levels = mappings() | ||
@@ -208,0 +205,0 @@ module.exports.stdSerializers = serializers |
@@ -720,1 +720,9 @@ 'use strict' | ||
}) | ||
test('throws if prettyPrint is passed in as an option', async (t) => { | ||
t.throws(() => { | ||
pino({ | ||
prettyPrint: true | ||
}) | ||
}, new Error('prettyPrint option is no longer supported, see the pino-pretty package (https://github.com/pinojs/pino-pretty)')) | ||
}) |
@@ -30,3 +30,3 @@ 'use strict' | ||
plan(3) | ||
const stream = pino.destination() | ||
const stream = pino.destination({ sync: true }) | ||
@@ -33,0 +33,0 @@ // side effect of the pino constructor is that it will set an |
@@ -254,42 +254,1 @@ 'use strict' | ||
}) | ||
test('custom levels accessible in prettifier function', async ({ plan, same }) => { | ||
plan(1) | ||
const logger = pino({ | ||
prettyPrint: true, | ||
prettifier: function prettifierFactory () { | ||
const instance = this | ||
return function () { | ||
same(instance.levels, { | ||
labels: { | ||
10: 'trace', | ||
20: 'debug', | ||
30: 'info', | ||
35: 'foo', | ||
40: 'warn', | ||
45: 'bar', | ||
50: 'error', | ||
60: 'fatal' | ||
}, | ||
values: { | ||
trace: 10, | ||
debug: 20, | ||
info: 30, | ||
warn: 40, | ||
error: 50, | ||
fatal: 60, | ||
foo: 35, | ||
bar: 45 | ||
} | ||
}) | ||
} | ||
}, | ||
customLevels: { | ||
foo: 35, | ||
bar: 45 | ||
}, | ||
changeLevelName: 'priority' | ||
}) | ||
logger.foo('test') | ||
}) |
@@ -153,18 +153,2 @@ 'use strict' | ||
test('stack is rendered as any other property if it\'s not a string', t => { | ||
t.plan(3) | ||
const err = new Error('myerror') | ||
err.stack = null | ||
const instance = pino(sink(function (chunk, enc, cb) { | ||
t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()') | ||
delete chunk.time | ||
t.equal(chunk.err.hasOwnProperty('stack'), true) | ||
t.equal(chunk.err.stack, null) | ||
cb() | ||
})) | ||
instance.level = name | ||
instance[name](err) | ||
}) | ||
test('correctly ignores toString on errors', async ({ same }) => { | ||
@@ -171,0 +155,0 @@ const err = new Error('myerror') |
@@ -40,5 +40,3 @@ 'use strict' | ||
const hasWeak = !!global.WeakRef | ||
test('sync false does not log everything when calling process.exit(0)', { skip: hasWeak }, async ({ equal }) => { | ||
test('sync false logs everything when calling process.exit(0)', async ({ not }) => { | ||
let actual = '' | ||
@@ -54,17 +52,2 @@ const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'syncfalse-exit.js')]) | ||
equal(actual.match(/hello/), null) | ||
equal(actual.match(/world/), null) | ||
}) | ||
test('sync false logs everything when calling process.exit(0)', { skip: !hasWeak }, async ({ not }) => { | ||
let actual = '' | ||
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'syncfalse-exit.js')]) | ||
child.stdout.pipe(writer((s, enc, cb) => { | ||
actual += s | ||
cb() | ||
})) | ||
await once(child, 'close') | ||
not(actual.match(/hello/), null) | ||
@@ -71,0 +54,0 @@ not(actual.match(/world/), null) |
@@ -6,2 +6,2 @@ global.process = { __proto__: process, pid: 123456 } | ||
const asyncLogger = pino(pino.destination({ sync: false })).child({ hello: 'world' }) | ||
pino.final(asyncLogger, (_, logger) => logger.info('h'))() | ||
asyncLogger.info('h') |
@@ -6,2 +6,2 @@ global.process = { __proto__: process, pid: 123456 } | ||
const asyncLogger = pino(pino.destination({ minLength: 4096, sync: false })) | ||
pino.final(asyncLogger, (_, logger) => logger.info('h'))() | ||
asyncLogger.info('h') |
@@ -259,3 +259,3 @@ 'use strict' | ||
test('levelVal ovverides level', function (t) { | ||
test('levelVal overrides level', function (t) { | ||
let messageCount = 0 | ||
@@ -545,17 +545,13 @@ const stream = writeStream(function (data, enc, cb) { | ||
const destination = pino.destination({ dest: tmp, sync: false, minLength: 4096 }) | ||
const log = pino({ level: 'info' }, multistream([{ level: 'info', stream: destination }])) | ||
const stream = multistream([{ level: 'info', stream: destination }]) | ||
const log = pino({ level: 'info' }, stream) | ||
destination.on('ready', () => { | ||
log.info('foo') | ||
log.info('bar') | ||
t.equal(readFileSync(tmp, { encoding: 'utf-8' }).split('\n').length - 1, 0) | ||
pino.final(log, (err, finalLogger) => { | ||
if (err) { | ||
t.fail() | ||
return t.end() | ||
} | ||
t.equal(readFileSync(tmp, { encoding: 'utf-8' }).split('\n').length - 1, 2) | ||
finalLogger.info('biz') | ||
t.equal(readFileSync(tmp, { encoding: 'utf-8' }).split('\n').length - 1, 3) | ||
t.end() | ||
})() | ||
stream.flushSync() | ||
t.equal(readFileSync(tmp, { encoding: 'utf-8' }).split('\n').length - 1, 2) | ||
log.info('biz') | ||
stream.flushSync() | ||
t.equal(readFileSync(tmp, { encoding: 'utf-8' }).split('\n').length - 1, 3) | ||
t.end() | ||
}) | ||
@@ -562,0 +558,0 @@ }) |
@@ -735,3 +735,3 @@ 'use strict' | ||
test('supports leading bracket notation (single-segment path, wilcard)', async ({ equal }) => { | ||
test('supports leading bracket notation (single-segment path, wildcard)', async ({ equal }) => { | ||
const stream = sink() | ||
@@ -738,0 +738,0 @@ const instance = pino({ redact: ['[*]'] }, stream) |
@@ -22,3 +22,3 @@ 'use strict' | ||
try { | ||
await execa('sync') // Wait for the file to be writen to disk | ||
await execa('sync') // Wait for the file to be written to disk | ||
} catch { | ||
@@ -25,0 +25,0 @@ // Just a fallback, this should be unreachable |
@@ -13,3 +13,3 @@ 'use strict' | ||
test('pino.transport with destination overriden by bundler', async ({ same, teardown }) => { | ||
test('pino.transport with destination overridden by bundler', async ({ same, teardown }) => { | ||
globalThis.__bundlerPathsOverrides = { | ||
@@ -40,3 +40,3 @@ foobar: join(__dirname, '..', 'fixtures', 'to-file-transport.js') | ||
test('pino.transport with worker destination overriden by bundler', async ({ same, teardown }) => { | ||
test('pino.transport with worker destination overridden by bundler', async ({ same, teardown }) => { | ||
globalThis.__bundlerPathsOverrides = { | ||
@@ -71,3 +71,3 @@ 'pino-worker': join(__dirname, '..', '..', 'lib/worker.js') | ||
test('pino.transport with worker-pipeline destination overriden by bundler', async ({ same, teardown }) => { | ||
test('pino.transport with worker-pipeline destination overridden by bundler', async ({ same, teardown }) => { | ||
globalThis.__bundlerPathsOverrides = { | ||
@@ -74,0 +74,0 @@ 'pino-pipeline-worker': join(__dirname, '..', '..', 'lib/worker-pipeline.js') |
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
35
456459
141
10988
+ Addedon-exit-leak-free@1.0.0(transitive)
+ Addedpino-std-serializers@5.6.0(transitive)
+ Addedprocess-warning@2.3.2(transitive)
+ Addedsonic-boom@3.8.1(transitive)
+ Addedthread-stream@1.0.1(transitive)
- Removedon-exit-leak-free@0.2.0(transitive)
- Removedpino-std-serializers@4.0.0(transitive)
- Removedprocess-warning@1.0.0(transitive)
- Removedsonic-boom@2.8.0(transitive)
- Removedthread-stream@0.15.2(transitive)
Updatedon-exit-leak-free@^1.0.0
Updatedpino-std-serializers@^5.0.0
Updatedprocess-warning@^2.0.0
Updatedsonic-boom@^3.0.0
Updatedthread-stream@^1.0.0