UNPKG

3.59 kBMarkdownView Raw
1# Asynchronous Logging
2
3In essence, asynchronous logging enables even faster performance by Pino.
4
5In Pino's standard mode of operation log messages are directly written to the
6output stream as the messages are generated with a _blocking_ operation.
7Asynchronous logging works by buffering
8log messages and writing them in larger chunks.
9
10## Caveats
11
12This has a couple of important caveats:
13
14* 4KB of spare RAM will be needed for logging
15* As opposed to the default mode, there is not a one-to-one relationship between
16 calls to logging methods (e.g. `logger.info`) and writes to a log file
17* There is a possibility of the most recently buffered log messages being lost
18 (up to 4KB of logs)
19 * For instance, a power cut will mean up to 4KB of buffered logs will be lost
20
21So in summary, only use extreme mode when performing an extreme amount of
22logging and it is acceptable to potentially lose the most recent logs.
23
24* Pino will register handlers for the following process events/signals so that
25 Pino can flush the extreme mode buffer:
26
27 + `beforeExit`
28 + `exit`
29 + `uncaughtException`
30 + `SIGHUP`
31 + `SIGINT`
32 + `SIGQUIT`
33 + `SIGTERM`
34
35 In all of these cases, except `SIGHUP`, the process is in a state that it
36 *must* terminate. Thus, if an `onTerminated` function isn't registered when
37 constructing a Pino instance (see [pino#constructor](api.md#constructor)),
38 then Pino will invoke `process.exit(0)` when no error has occurred, or
39 `process.exit(1)` otherwise. If an `onTerminated` function is supplied, it
40 is the responsibility of the `onTerminated` function to manually exit the process.
41
42 In the case of `SIGHUP`, we will look to see if any other handlers are
43 registered for the event. If not, we will proceed as we do with all other
44 signals. If there are more handlers registered than just our own, we will
45 simply flush the asynchronous logging buffer.
46
47### AWS Lambda
48
49On AWS Lambda we recommend to call `dest.flushSync()` at the end
50of each function execution to avoid losing data.
51
52## Usage
53
54The `pino.destination({ sync: false })` method will provide an asynchronous destination.
55
56```js
57const pino = require('pino')
58const dest = pino.destination({ sync: false }) // logs to stdout with no args
59const logger = pino(dest)
60```
61
62<a id='log-loss-prevention'></a>
63## Log loss prevention
64
65The following strategy can be used to minimize log loss:
66
67```js
68const pino = require('pino')
69const dest = pino.destination({ sync: false })
70const logger = pino(dest)
71
72// asynchronously flush every 10 seconds to keep the buffer empty
73// in periods of low activity
74setInterval(function () {
75 logger.flush()
76}, 10000).unref()
77
78// use pino.final to create a special logger that
79// guarantees final tick writes
80const handler = pino.final(logger, (err, finalLogger, evt) => {
81 finalLogger.info(`${evt} caught`)
82 if (err) finalLogger.error(err, 'error caused exit')
83 process.exit(err ? 1 : 0)
84})
85// catch all the ways node might exit
86process.on('beforeExit', () => handler(null, 'beforeExit'))
87process.on('exit', () => handler(null, 'exit'))
88process.on('uncaughtException', (err) => handler(err, 'uncaughtException'))
89process.on('SIGINT', () => handler(null, 'SIGINT'))
90process.on('SIGQUIT', () => handler(null, 'SIGQUIT'))
91process.on('SIGTERM', () => handler(null, 'SIGTERM'))
92```
93
94An extreme destination is an instance of
95[`SonicBoom`](https://github.com/mcollina/sonic-boom) with `4096`
96buffering.
97
98
99* See [`pino.destination` api](/docs/api.md#pino-destination)
100* See [`pino.final` api](/docs/api.md#pino-final)
101* See [`destination` parameter](/docs/api.md#destination)