diff --git a/lib/tools.js b/lib/tools.js index 069d12a9c..9398257c1 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -179,23 +179,47 @@ function getPrettyStream (opts, prettifier, dest) { } function prettifierMetaWrapper (pretty, dest) { + var warned = false return { [needsMetadataGsym]: true, lastLevel: 0, lastMsg: null, lastObj: null, lastLogger: null, - write (chunk) { + flushSync () { + if (warned) { + return + } + warned = true + 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 var chindings = null + // protection against flushSync being called before logging + // anything + if (!lastLogger) { + return null + } + if (lastLogger.hasOwnProperty(parsedChindingsSym)) { - chindings = this.lastLogger[parsedChindingsSym] + chindings = lastLogger[parsedChindingsSym] } else { - chindings = JSON.parse('{"v":1' + this.lastLogger[chindingsSym] + '}') - this.lastLogger[parsedChindingsSym] = chindings + chindings = JSON.parse('{"v":1' + lastLogger[chindingsSym] + '}') + lastLogger[parsedChindingsSym] = chindings } + return chindings + }, + write (chunk) { + const lastLogger = this.lastLogger + const chindings = this.chindings() + var time = this.lastTime if (time.match(/^\d+/)) { @@ -220,7 +244,7 @@ function prettifierMetaWrapper (pretty, dest) { time }, chindings, lastObj, errorProps) - const serializers = this.lastLogger[serializersSym] + const serializers = lastLogger[serializersSym] const keys = Object.keys(serializers) var key @@ -231,7 +255,7 @@ function prettifierMetaWrapper (pretty, dest) { } } - const stringifiers = this.lastLogger[stringifiersSym] + const stringifiers = lastLogger[stringifiersSym] const redact = stringifiers[redactFmtSym] const formatted = pretty(typeof redact === 'function' ? redact(obj) : obj) @@ -287,8 +311,8 @@ function final (logger, handler) { throw Error('if supplied, the handler parameter should be a function') } const stream = logger[streamSym] - if (!(stream instanceof SonicBoom)) { - throw Error('only compatible with loggers with pino.destination and pino.extreme targets') + if (typeof stream.flushSync !== 'function') { + throw Error('final requires a stream that has a flushSync method, such as pino.destination and pino.extreme') } const finalLogger = new Proxy(logger, { diff --git a/test/final.test.js b/test/final.test.js index 9af04cfef..cb0ec016a 100644 --- a/test/final.test.js +++ b/test/final.test.js @@ -27,7 +27,7 @@ test('throws if the supplied handler is not a function', async ({ throws }) => { test('throws if not supplied logger with pino.destination or pino.extreme instance', async ({ throws, doesNotThrow }) => { throws(() => { pino.final(pino(fs.createWriteStream('/dev/null')), () => {}) - }, Error('only compatible with loggers with pino.destination and pino.extreme')) + }, Error('inal requires a stream that has a flushSync method, such as pino.destination and pino.extreme')) doesNotThrow(() => { pino.final(pino(pino.destination()), () => {}) diff --git a/test/fixtures/pretty/final-return.js b/test/fixtures/pretty/final-return.js new file mode 100644 index 000000000..d2146ea2b --- /dev/null +++ b/test/fixtures/pretty/final-return.js @@ -0,0 +1,7 @@ +global.process = { __proto__: process, pid: 123456 } +Date.now = function () { return 1459875739796 } +require('os').hostname = function () { return 'abcdefghijklmnopqr' } +var pino = require(require.resolve('./../../../')) +var log = pino({ prettyPrint: true }) +log.info('h') +pino.final(log).info('after') diff --git a/test/fixtures/pretty/final.js b/test/fixtures/pretty/final.js new file mode 100644 index 000000000..1bf07c13b --- /dev/null +++ b/test/fixtures/pretty/final.js @@ -0,0 +1,9 @@ +global.process = { __proto__: process, pid: 123456 } +Date.now = function () { return 1459875739796 } +require('os').hostname = function () { return 'abcdefghijklmnopqr' } +var pino = require(require.resolve('./../../../')) +var log = pino({ prettyPrint: true }) +log.info('h') +process.once('beforeExit', pino.final(log, (_, logger) => { + logger.info('beforeExit') +})) diff --git a/test/pretty.test.js b/test/pretty.test.js index 8905fc222..6c888dd04 100644 --- a/test/pretty.test.js +++ b/test/pretty.test.js @@ -202,3 +202,29 @@ test('errors with props', async ({ isNot }) => { isNot(actual.match(/errno: 1/), null) isNot(actual.match(/.*error-props\.js.*/), null) }) + +test('final works with pretty', async ({ isNot }) => { + var actual = '' + const child = fork(join(__dirname, 'fixtures', 'pretty', 'final.js'), { silent: true }) + + child.stdout.pipe(writer((s, enc, cb) => { + actual += s + cb() + })) + await once(child, 'close') + isNot(actual.match(/WARN \(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null) + isNot(actual.match(/INFO \(123456 on abcdefghijklmnopqr\): beforeExit/), null) +}) + +test('returning ', async ({ isNot }) => { + var actual = '' + const child = fork(join(__dirname, 'fixtures', 'pretty', 'final-return.js'), { silent: true }) + + child.stdout.pipe(writer((s, enc, cb) => { + actual += s + cb() + })) + await once(child, 'close') + isNot(actual.match(/WARN \(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null) + isNot(actual.match(/INFO \(123456 on abcdefghijklmnopqr\): after/), null) +})