Comparing version 3.4.0 to 4.0.0
@@ -58,2 +58,7 @@ # Table of Contents | ||
configurations. This may be set to a configuration object as outlined in [pino.pretty](#pretty). Default: `false`. | ||
* `onTerminated` (function): this function will be invoked during process shutdown when `extreme` is set to `true`. | ||
The signature of the function is `onTerminated(eventName, err)`. If you do not specify a function, Pino will | ||
invoke `process.exit(0)` when no error has occurred, and `process.exit(1)` otherwise. If you do specify a function, | ||
it is up to you to terminate the process; you **must** perform only synchronous operations at this point. | ||
See [Extreme mode explained](extreme.md) for more detail. | ||
* `enabled` (boolean): enables logging. Default: `true` | ||
@@ -60,0 +65,0 @@ + `stream` (Writable): a writable stream where the logs will be written. |
@@ -40,4 +40,26 @@ # Extreme Mode | ||
``` | ||
* Pino will register handlers for the following process events/signals so that | ||
Pino can flush the extreme mode buffer: | ||
+ `beforeExit` | ||
+ `exit` | ||
+ `uncaughtException` | ||
+ `SIGHUP` | ||
+ `SIGINT` | ||
+ `SIGQUIT` | ||
+ `SIGTERM` | ||
In all of these cases, except `SIGHUP`, the process is in a state that it | ||
*must* terminate. Thus, if you do not register an `onTerminated` function when | ||
constructing your Pino instance (see [pino#constructor](API.md#constructor)), | ||
then Pino will invoke `process.exit(0)` when no error has occurred, or | ||
`process.exit(1)` otherwise. If you do supply an `onTerminated` function, it | ||
is left up to you to fully terminate the process. | ||
In the case of `SIGHUP`, we will look to see if any other handlers are | ||
registered for the event. If not, we will proceed as we do with all other | ||
signals. If there are more handlers registered than just our own, we will | ||
simply flush the extreme mode buffer. | ||
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. |
# Transports | ||
A transport in most logging libraries is something that runs in-process to | ||
perform some operation with the finalized log line. For example, a tranport | ||
perform some operation with the finalized log line. For example, a transport | ||
might send the log line to a standard syslog server after processing the log | ||
@@ -6,0 +6,0 @@ line and reformatting it. |
'use strict' | ||
var once = require('once') | ||
module.exports = function (pinoInstance, internalExtremeHandler) { | ||
function theWorldIsBurning (err) { | ||
runInternalHandler() | ||
handlers.handledOnTerminate = true | ||
pinoInstance.onTerminated(this.name, err) | ||
} | ||
function onExit (fn) { | ||
var oneFn = once(fn) | ||
process.on('beforeExit', handle('beforeExit')) | ||
process.on('exit', handle('exit')) | ||
process.on('uncaughtException', handle('uncaughtException', 1)) | ||
process.on('SIGHUP', handle('SIGHUP', 129)) | ||
process.on('SIGINT', handle('SIGINT', 130)) | ||
process.on('SIGQUIT', handle('SIGQUIT', 131)) | ||
process.on('SIGTERM', handle('SIGTERM', 143)) | ||
function handle (evt, code) { | ||
onExit.passCode = function (code) { | ||
if (oneFn.value) { oneFn = once(fn) } | ||
oneFn(code, evt) | ||
function hup (err) { | ||
if (process.listenerCount('SIGHUP') === 1) { | ||
return theWorldIsBurning.call({name: 'SIGHUP'}, err) | ||
} | ||
onExit.insertCode = function () { | ||
if (oneFn.value) { oneFn = once(fn) } | ||
oneFn(code, evt) | ||
} | ||
return (code === undefined) ? onExit.passCode : onExit.insertCode | ||
pinoInstance.flush() | ||
} | ||
} | ||
module.exports = { | ||
onExit: onExit | ||
function runInternalHandler () { | ||
if (handlers.handledOnTerminate) return | ||
internalExtremeHandler() | ||
} | ||
var handlers = { | ||
beforeExit: theWorldIsBurning.bind({name: 'beforeExit'}), | ||
exit: theWorldIsBurning.bind({name: 'exit'}), | ||
uncaughtException: theWorldIsBurning.bind({name: 'uncaughtException'}), | ||
SIGHUP: hup, | ||
SIGINT: theWorldIsBurning.bind({name: 'SIGINT'}), | ||
SIGQUIT: theWorldIsBurning.bind({name: 'SIGQUIT'}), | ||
SIGTERM: theWorldIsBurning.bind({name: 'SIGTERM'}) | ||
} | ||
Object.keys(handlers).forEach(function (k) { | ||
process.on(k, handlers[k]) | ||
}) | ||
return handlers | ||
} |
@@ -33,2 +33,3 @@ 'use strict' | ||
this.formatOpts = opts.formatOpts | ||
this.onTerminated = opts.onTerminated | ||
@@ -35,0 +36,0 @@ if (opts.level && opts.levelVal) { |
{ | ||
"name": "pino", | ||
"version": "3.4.0", | ||
"version": "4.0.0", | ||
"description": "super fast, all natural json logger", | ||
@@ -70,3 +70,3 @@ "main": "pino.js", | ||
"steed": "^1.1.3", | ||
"tap": "^9.0.0", | ||
"tap": "^10.0.0", | ||
"tape": "^4.6.2", | ||
@@ -82,3 +82,2 @@ "through2": "^2.0.1", | ||
"flatstr": "^1.0.4", | ||
"once": "^1.3.3", | ||
"pump": "^1.0.2", | ||
@@ -85,0 +84,0 @@ "quick-format-unescaped": "^1.0.0", |
54
pino.js
@@ -26,2 +26,6 @@ 'use strict' | ||
prettyPrint: false, | ||
onTerminated: function (eventName, err) { | ||
if (err) return process.exit(1) | ||
process.exit(0) | ||
}, | ||
enabled: true | ||
@@ -63,32 +67,28 @@ } | ||
var logger = new Pino(iopts, istream) | ||
if (iopts.cache) { | ||
// setImmediate is causing a very weird crash: | ||
// Assertion failed: (cb_v->IsFunction()), function MakeCallback... | ||
// but setTimeout isn't *shrug* | ||
setTimeout(function () { | ||
if (!tools.streamIsBlockable(istream)) { | ||
logger.emit('error', new Error('stream must have a file descriptor in extreme mode')) | ||
} | ||
}, 100) | ||
var settleTries = 0 | ||
function waitForFDSettle () { | ||
var isBlockable = tools.streamIsBlockable(istream) | ||
if (isBlockable === false && settleTries > 10) { | ||
return logger.emit('error', Error('stream must have a file descriptor in extreme mode')) | ||
} else if (isBlockable === true) { | ||
return events(logger, extremeModeExitHandler) | ||
} | ||
settleTries += 1 | ||
setTimeout(waitForFDSettle, 100) | ||
} | ||
events.onExit(function (code, evt) { | ||
var buf = iopts.cache.buf | ||
if (buf) { | ||
// We need to block the process exit long enough to flush the buffer | ||
// to the destination stream. We do that by forcing a synchronous | ||
// write directly to the stream's file descriptor. | ||
var fd = (istream.fd) ? istream.fd : istream._handle.fd | ||
fs.writeSync(fd, buf) | ||
} | ||
if (!process._events[evt] || process._events[evt].length < 2 || !process._events[evt].filter(function (f) { | ||
return f + '' !== events.onExit.passCode + '' && f + '' !== events.onExit.insertCode + '' | ||
}).length) { | ||
process.exit(code) | ||
} else { | ||
return 'no exit' | ||
} | ||
}) | ||
function extremeModeExitHandler () { | ||
var buf = iopts.cache.buf | ||
if (buf) { | ||
// We need to block the process exit long enough to flush the buffer | ||
// to the destination stream. We do that by forcing a synchronous | ||
// write directly to the stream's file descriptor. | ||
var fd = (istream.fd) ? istream.fd : istream._handle.fd | ||
fs.writeSync(fd, buf) | ||
} | ||
} | ||
var logger = new Pino(iopts, istream) | ||
if (iopts.cache) setTimeout(waitForFDSettle, 100) | ||
return logger | ||
@@ -95,0 +95,0 @@ } |
@@ -13,6 +13,6 @@ ![banner](pino-banner.png) | ||
* [Benchmarks](#benchmarks) | ||
* [API](docs/API.md) | ||
* [Extreme mode explained](docs/extreme.md) | ||
* [Pino Howtos](docs/howtos.md) | ||
* [Transports with Pino](docs/transports.md) | ||
* [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) | ||
@@ -19,0 +19,0 @@ * [Caveats](#caveats) |
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
116236
7
41
2667
16
5
- Removedonce@^1.3.3