diff --git a/lib/transport.js b/lib/transport.js index 0ef0283c6..e15ef7eb4 100644 --- a/lib/transport.js +++ b/lib/transport.js @@ -4,37 +4,17 @@ const { createRequire } = require('module') const getCallers = require('./caller') const { join, isAbsolute } = require('path') const sleep = require('atomic-sleep') - -let onExit - -/* istanbul ignore next */ -if (global.WeakRef && global.WeakMap && global.FinalizationRegistry) { - // This require MUST be top level otherwise the transport would - // not work from within Jest as it hijacks require. - onExit = require('on-exit-leak-free') -} - +const onExit = require('on-exit-leak-free') const ThreadStream = require('thread-stream') function setupOnExit (stream) { - /* istanbul ignore next */ - if (onExit) { - // This is leak free, it does not leave event handlers - onExit.register(stream, autoEnd) + // This is leak free, it does not leave event handlers + onExit.register(stream, autoEnd) + onExit.registerBeforeExit(stream, flush) - stream.on('close', function () { - onExit.unregister(stream) - }) - } else { - const fn = autoEnd.bind(null, stream) - process.once('beforeExit', fn) - process.once('exit', fn) - - stream.on('close', function () { - process.removeListener('beforeExit', fn) - process.removeListener('exit', fn) - }) - } + stream.on('close', function () { + onExit.unregister(stream) + }) } function buildStream (filename, workerData, workerOpts) { @@ -86,6 +66,10 @@ function autoEnd (stream) { }) } +function flush (stream) { + stream.flushSync() +} + function transport (fullOptions) { const { pipeline, targets, levels, options = {}, worker = {}, caller = getCallers() } = fullOptions diff --git a/package.json b/package.json index 654ac11f8..442283b02 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", - "on-exit-leak-free": "^1.0.0", + "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "v0.5.0", "pino-std-serializers": "^5.0.0", "process-warning": "^2.0.0", diff --git a/test/exit.test.js b/test/exit.test.js index 114265f81..b373ddb7f 100644 --- a/test/exit.test.js +++ b/test/exit.test.js @@ -66,3 +66,12 @@ test('sync false logs everything when calling flushSync', async ({ not }) => { not(actual.match(/hello/), null) not(actual.match(/world/), null) }) + +test('transports exits gracefully when logging in exit', async ({ equal }) => { + const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'transport-with-on-exit.js')]) + child.stdout.resume() + + const code = await once(child, 'close') + + equal(code, 0) +}) diff --git a/test/fixtures/transport-with-on-exit.js b/test/fixtures/transport-with-on-exit.js new file mode 100644 index 000000000..655a17395 --- /dev/null +++ b/test/fixtures/transport-with-on-exit.js @@ -0,0 +1,12 @@ +'use strict' +const pino = require('../..') +const log = pino({ + transport: { + target: 'pino/file', + options: { destination: 1 } + } +}) +log.info('hello world!') +process.on('exit', (code) => { + log.info('Exiting peacefully') +})