From ff1546b8bb3b471fdbacffbe8bac8b6af0496e19 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Wed, 1 Jun 2022 00:25:55 +0200 Subject: [PATCH] Remove deprecated API and options in v7 option. (#1249) * Remove prettyPrint option. 100% code coverage back. * Remove pino.final * Fix jsdom TS issue * Restore lost error * Add link to pino-pretty * Update Node.js in workflows Co-authored-by: Igor Savin --- .github/workflows/bench.yml | 4 +- .github/workflows/ci.yml | 2 +- .github/workflows/package-manager-ci.yml | 6 +- docs/api.md | 21 - lib/deprecations.js | 6 +- lib/symbols.js | 2 - lib/tools.js | 232 +---------- lib/transport.js | 2 + package.json | 4 +- pino.js | 3 - test/basic.test.js | 8 + test/custom-levels.test.js | 41 -- test/exit.test.js | 19 +- test/final.test.js | 237 ----------- test/fixtures/pretty/basic.js | 6 - test/fixtures/pretty/child-with-serializer.js | 17 - .../pretty/child-with-updated-chindings.js | 8 - test/fixtures/pretty/child.js | 8 - test/fixtures/pretty/custom-time-label.js | 9 - test/fixtures/pretty/custom-time.js | 9 - test/fixtures/pretty/dateformat.js | 10 - test/fixtures/pretty/error-props.js | 9 - test/fixtures/pretty/error.js | 7 - test/fixtures/pretty/final-no-log-before.js | 8 - test/fixtures/pretty/final-return.js | 7 - test/fixtures/pretty/final.js | 9 - test/fixtures/pretty/formatters.js | 13 - test/fixtures/pretty/level-first.js | 6 - test/fixtures/pretty/no-time.js | 9 - test/fixtures/pretty/obj-msg-prop.js | 6 - test/fixtures/pretty/pretty-factory.js | 6 - test/fixtures/pretty/redact.js | 9 - test/fixtures/pretty/serializers.js | 17 - test/fixtures/pretty/skipped-output.js | 13 - .../pretty/suppress-flush-sync-warning.js | 7 - test/fixtures/syncfalse-child.js | 2 +- test/fixtures/syncfalse.js | 2 +- test/multistream.test.js | 20 +- test/pretty.test.js | 392 ------------------ 39 files changed, 46 insertions(+), 1150 deletions(-) delete mode 100644 test/final.test.js delete mode 100644 test/fixtures/pretty/basic.js delete mode 100644 test/fixtures/pretty/child-with-serializer.js delete mode 100644 test/fixtures/pretty/child-with-updated-chindings.js delete mode 100644 test/fixtures/pretty/child.js delete mode 100644 test/fixtures/pretty/custom-time-label.js delete mode 100644 test/fixtures/pretty/custom-time.js delete mode 100644 test/fixtures/pretty/dateformat.js delete mode 100644 test/fixtures/pretty/error-props.js delete mode 100644 test/fixtures/pretty/error.js delete mode 100644 test/fixtures/pretty/final-no-log-before.js delete mode 100644 test/fixtures/pretty/final-return.js delete mode 100644 test/fixtures/pretty/final.js delete mode 100644 test/fixtures/pretty/formatters.js delete mode 100644 test/fixtures/pretty/level-first.js delete mode 100644 test/fixtures/pretty/no-time.js delete mode 100644 test/fixtures/pretty/obj-msg-prop.js delete mode 100644 test/fixtures/pretty/pretty-factory.js delete mode 100644 test/fixtures/pretty/redact.js delete mode 100644 test/fixtures/pretty/serializers.js delete mode 100644 test/fixtures/pretty/skipped-output.js delete mode 100644 test/fixtures/pretty/suppress-flush-sync-warning.js delete mode 100644 test/pretty.test.js diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 2185374f6..2c794e4bc 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -26,7 +26,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 12 + node-version: 16 - name: Install Modules run: npm i - name: Run Benchmark @@ -46,7 +46,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: 12 + node-version: 16 - name: Install Modules run: npm i - name: Run Benchmark diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52274c2a4..78ca207c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: os: [macOS-latest, windows-latest, ubuntu-latest] - node-version: [12, 14, 16, 17] + node-version: [14, 16, 18] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} diff --git a/.github/workflows/package-manager-ci.yml b/.github/workflows/package-manager-ci.yml index 9fa89e957..e119eb5d9 100644 --- a/.github/workflows/package-manager-ci.yml +++ b/.github/workflows/package-manager-ci.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: os: [windows-latest, ubuntu-latest] - node-version: [14] + node-version: [16] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} @@ -35,7 +35,7 @@ jobs: fail-fast: false matrix: os: [windows-latest, ubuntu-latest] - node-version: [14] + node-version: [16] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} @@ -62,7 +62,7 @@ jobs: fail-fast: false matrix: os: [windows-latest, ubuntu-latest] - node-version: [14] + node-version: [16] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} diff --git a/docs/api.md b/docs/api.md index 9844e09e3..65dcfd240 100644 --- a/docs/api.md +++ b/docs/api.md @@ -440,27 +440,6 @@ logger.info(thing) In this way, logged objects' properties don't conflict with pino's standard logging properties, and searching for logged objects can start from a consistent path. - -#### `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) Browser only, may have `asObject` and `write` keys. This option is separately diff --git a/lib/deprecations.js b/lib/deprecations.js index 3aed8d646..806c5362e 100644 --- a/lib/deprecations.js +++ b/lib/deprecations.js @@ -3,8 +3,6 @@ const warning = require('process-warning')() module.exports = warning -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') diff --git a/lib/symbols.js b/lib/symbols.js index 75195ff07..84ddadb00 100644 --- a/lib/symbols.js +++ b/lib/symbols.js @@ -9,7 +9,6 @@ const mixinSym = Symbol('pino.mixin') const lsCacheSym = Symbol('pino.lsCache') const chindingsSym = Symbol('pino.chindings') -const parsedChindingsSym = Symbol('pino.parsedChindings') const asJsonSym = Symbol('pino.asJson') const writeSym = Symbol('pino.write') @@ -45,7 +44,6 @@ module.exports = { mixinSym, lsCacheSym, chindingsSym, - parsedChindingsSym, asJsonSym, writeSym, serializersSym, diff --git a/lib/tools.js b/lib/tools.js index 3dd5e1880..9f855567c 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -5,11 +5,10 @@ const format = require('quick-format-unescaped') const { mapHttpRequest, mapHttpResponse } = require('pino-std-serializers') const SonicBoom = require('sonic-boom') -const warning = require('./deprecations') +const onExit = require('on-exit-leak-free') const { lsCacheSym, chindingsSym, - parsedChindingsSym, writeSym, serializersSym, formatOptsSym, @@ -18,9 +17,6 @@ const { stringifySym, stringifySafeSym, wildcardFirstSym, - needsMetadataGsym, - redactFmtSym, - streamSym, nestedKeySym, formattersSym, messageKeySym, @@ -210,123 +206,6 @@ function asChindings (instance, bindings) { return data } -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) { return stream.write !== stream.constructor.prototype.write } @@ -336,12 +215,17 @@ function buildSafeSonicBoom (opts) { stream.on('error', filterBrokenPipe) // if we are sync: false, we must flush on exit if (!opts.sync && isMainThread) { - setupOnExit(stream) + onExit.register(stream, autoEnd) + + stream.on('close', function () { + onExit.unregister(stream) + }) } return stream function filterBrokenPipe (err) { - // TODO verify on Windows + // Impossible to replicate across all operating systems + /* istanbul ignore next */ if (err.code === 'EPIPE') { // If we get EPIPE, we should stop logging here // however we have no control to the consumer of @@ -357,20 +241,6 @@ function buildSafeSonicBoom (opts) { } } -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) { // This check is needed only on some platforms /* istanbul ignore next */ @@ -385,6 +255,8 @@ function autoEnd (stream, eventName) { stream.end() }) } 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 stream.flushSync() } @@ -422,85 +294,23 @@ function createArgsNormalizer (defaultOptions) { opts.serializers = Object.assign({}, defaultOptions.serializers, opts.serializers) opts.formatters = Object.assign({}, defaultOptions.formatters, opts.formatters) + 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 }) } - if (prettyPrint) { - warning.emit('PINODEP008') - const prettyOpts = Object.assign({ messageKey }, prettyPrint) - stream = getPrettyStream(prettyOpts, prettifier, stream, instance) - } return { opts, stream } } } -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) { try { return JSON.stringify(obj) @@ -522,16 +332,6 @@ function buildFormatters (level, bindings, log) { } } -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 - } -} - /** * Convert a string integer file descriptor to a proper native integer * file descriptor. @@ -551,12 +351,10 @@ function normalizeDestFileDescriptor (destination) { module.exports = { noop, buildSafeSonicBoom, - getPrettyStream, asChindings, asJson, genLog, createArgsNormalizer, - final, stringify, buildFormatters, normalizeDestFileDescriptor diff --git a/lib/transport.js b/lib/transport.js index d818bc4bc..0ef0283c6 100644 --- a/lib/transport.js +++ b/lib/transport.js @@ -7,6 +7,7 @@ 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. @@ -60,6 +61,7 @@ function buildStream (filename, workerData, workerOpts) { } function onExit () { + /* istanbul ignore next */ if (stream.closed) { return } diff --git a/package.json b/package.json index 89e2a9f82..f75d401fc 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "fastbench": "^1.0.1", "flush-write-stream": "^2.0.0", "import-fresh": "^3.2.1", - "jest": "^27.3.1", + "jest": "^27.5.1", "log": "^6.0.0", "loglevel": "^1.6.7", "pino-pretty": "^v7.6.0", @@ -102,7 +102,7 @@ "through2": "^4.0.0", "ts-node": "^10.7.0", "tsd": "^0.20.0", - "typescript": "^4.4.4", + "typescript": "^4.5.2", "winston": "^3.3.3" }, "dependencies": { diff --git a/pino.js b/pino.js index 33bdde0a9..667112d96 100644 --- a/pino.js +++ b/pino.js @@ -12,7 +12,6 @@ const { assertDefaultLevelFound, mappings, genLsCache, levels } = require('./lib const { createArgsNormalizer, asChindings, - final, buildSafeSonicBoom, buildFormatters, stringify, @@ -52,7 +51,6 @@ const defaultOptions = { messageKey: 'msg', nestedKey: null, enabled: true, - prettyPrint: false, base: { pid, hostname }, serializers: Object.assign(Object.create(null), { err: defaultErrorSerializer @@ -199,7 +197,6 @@ module.exports.destination = (dest = process.stdout.fd) => { module.exports.transport = require('./lib/transport') module.exports.multistream = require('./lib/multistream') -module.exports.final = final module.exports.levels = mappings() module.exports.stdSerializers = serializers module.exports.stdTimeFunctions = Object.assign({}, time) diff --git a/test/basic.test.js b/test/basic.test.js index 5a46beb09..2f9700f0d 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -717,3 +717,11 @@ test('nestedKey should not be used for non-objects', async ({ strictSame }) => { msg: message }) }) + +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)')) +}) diff --git a/test/custom-levels.test.js b/test/custom-levels.test.js index ecae49af4..a7298d806 100644 --- a/test/custom-levels.test.js +++ b/test/custom-levels.test.js @@ -251,44 +251,3 @@ test('When useOnlyCustomLevels is set to true, the level formatter should only g const { level } = await once(stream, 'data') equal(level, 42) }) - -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') -}) diff --git a/test/exit.test.js b/test/exit.test.js index 36eca729e..114265f81 100644 --- a/test/exit.test.js +++ b/test/exit.test.js @@ -37,24 +37,7 @@ test('pino with no args log everything when calling process.exit(0)', async ({ n not(actual.match(/world/), null) }) -const hasWeak = !!global.WeakRef - -test('sync false does not log everything when calling process.exit(0)', { skip: hasWeak }, async ({ equal }) => { - 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') - - equal(actual.match(/hello/), null) - equal(actual.match(/world/), null) -}) - -test('sync false logs everything when calling process.exit(0)', { skip: !hasWeak }, async ({ not }) => { +test('sync false logs everything when calling process.exit(0)', async ({ not }) => { let actual = '' const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'syncfalse-exit.js')]) diff --git a/test/final.test.js b/test/final.test.js deleted file mode 100644 index 14faf32cc..000000000 --- a/test/final.test.js +++ /dev/null @@ -1,237 +0,0 @@ -'use strict' -const pino = require('..') -const fs = require('fs') -const { test } = require('tap') -const { sleep, getPathToNull } = require('./helper') - -// This test is too fast for the GC to trigger the removal, so a leak warning -// will be emitted. Let's raise this so we do not scare everybody. -process.setMaxListeners(100) - -test('should show warning for pino.final on node 14+', ({ equal, end, plan }) => { - const major = Number(process.versions.node.split('.')[0]) - if (major < 14) return end() - - plan(1) - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - dest.flushSync = () => {} - const instance = pino(dest) - - pino.final(instance, (_, finalLogger) => { - finalLogger.info('hello') - })() - - function onWarning (warning) { - equal(warning.code, 'PINODEP009') - end() - } - - process.once('warning', onWarning) - - instance.info('hello') -}) - -test('replaces onTerminated option', async ({ throws }) => { - throws(() => { - pino({ - onTerminated: () => {} - }) - }, Error('The onTerminated option has been removed, use pino.final instead')) -}) - -test('throws if not supplied a logger instance', async ({ throws }) => { - throws(() => { - pino.final() - }, Error('expected a pino logger instance')) -}) - -test('throws if the supplied handler is not a function', async ({ throws }) => { - throws(() => { - pino.final(pino(), 'dummy') - }, Error('if supplied, the handler parameter should be a function')) -}) - -test('throws if not supplied logger with pino.destination instance with sync false', async ({ throws, doesNotThrow }) => { - throws(() => { - pino.final(pino(fs.createWriteStream(getPathToNull())), () => {}) - }, Error('final requires a stream that has a flushSync method, such as pino.destination')) - - doesNotThrow(() => { - pino.final(pino(pino.destination({ sync: false })), () => {}) - }) - - doesNotThrow(() => { - pino.final(pino(pino.destination({ sync: false })), () => {}) - }) -}) - -test('returns an exit listener function', async ({ equal }) => { - equal(typeof pino.final(pino(pino.destination({ sync: false })), () => {}), 'function') -}) - -test('listener function immediately sync flushes when fired (sync false)', async ({ pass, fail }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - let passed = false - dest.flushSync = () => { - passed = true - pass('flushSync called') - dest.flushSync = () => {} - } - pino.final(pino(dest), () => {})() - await sleep(10) - if (passed === false) fail('flushSync not called') -}) - -test('listener function immediately sync flushes when fired (sync true)', async ({ pass, fail }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: true }) - let passed = false - dest.flushSync = () => { - passed = true - pass('flushSync called') - dest.flushSync = () => {} - } - pino.final(pino(dest), () => {})() - await sleep(10) - if (passed === false) fail('flushSync not called') -}) - -test('immediately sync flushes when no handler is provided (sync false)', async ({ pass, fail }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - let passed = false - dest.flushSync = () => { - passed = true - pass('flushSync called') - dest.flushSync = () => {} - } - pino.final(pino(dest)) - await sleep(10) - if (passed === false) fail('flushSync not called') -}) - -test('immediately sync flushes when no handler is provided (sync true)', async ({ pass, fail }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: true }) - let passed = false - dest.flushSync = () => { - passed = true - pass('flushSync called') - dest.flushSync = () => {} - } - pino.final(pino(dest)) - await sleep(10) - if (passed === false) fail('flushSync not called') -}) - -test('swallows the non-ready error', async ({ doesNotThrow }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - doesNotThrow(() => { - pino.final(pino(dest), () => {})() - }) -}) - -test('listener function triggers handler function parameter', async ({ pass, fail }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - let passed = false - pino.final(pino(dest), () => { - passed = true - pass('handler function triggered') - })() - await sleep(10) - if (passed === false) fail('handler function not triggered') -}) - -test('passes any error to the handler', async ({ equal }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - pino.final(pino(dest), (err) => { - equal(err.message, 'test') - })(Error('test')) -}) - -test('passes a specialized final logger instance', async ({ equal, not, error }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - const logger = pino(dest) - pino.final(logger, (err, finalLogger) => { - error(err) - equal(typeof finalLogger.trace, 'function') - equal(typeof finalLogger.debug, 'function') - equal(typeof finalLogger.info, 'function') - equal(typeof finalLogger.warn, 'function') - equal(typeof finalLogger.error, 'function') - equal(typeof finalLogger.fatal, 'function') - - not(finalLogger.trace, logger.trace) - not(finalLogger.debug, logger.debug) - not(finalLogger.info, logger.info) - not(finalLogger.warn, logger.warn) - not(finalLogger.error, logger.error) - not(finalLogger.fatal, logger.fatal) - - equal(finalLogger.child, logger.child) - equal(finalLogger.levels, logger.levels) - })() -}) - -test('returns a specialized final logger instance if no handler is passed', async ({ equal, not }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - const logger = pino(dest) - const finalLogger = pino.final(logger) - equal(typeof finalLogger.trace, 'function') - equal(typeof finalLogger.debug, 'function') - equal(typeof finalLogger.info, 'function') - equal(typeof finalLogger.warn, 'function') - equal(typeof finalLogger.error, 'function') - equal(typeof finalLogger.fatal, 'function') - - not(finalLogger.trace, logger.trace) - not(finalLogger.debug, logger.debug) - not(finalLogger.info, logger.info) - not(finalLogger.warn, logger.warn) - not(finalLogger.error, logger.error) - not(finalLogger.fatal, logger.fatal) - - equal(finalLogger.child, logger.child) - equal(finalLogger.levels, logger.levels) -}) - -test('final logger instances synchronously flush after a log method call', async ({ pass, fail, error }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - const logger = pino(dest) - let passed = false - let count = 0 - dest.flushSync = () => { - count++ - if (count === 2) { - passed = true - pass('flushSync called') - } - } - pino.final(logger, (err, finalLogger) => { - error(err) - finalLogger.info('hello') - })() - await sleep(10) - if (passed === false) fail('flushSync not called') -}) - -test('also instruments custom log methods', async ({ pass, fail, error }) => { - const dest = pino.destination({ dest: getPathToNull(), sync: false }) - const logger = pino({ - customLevels: { - foo: 35 - } - }, dest) - let passed = false - let count = 0 - dest.flushSync = () => { - count++ - if (count === 2) { - passed = true - pass('flushSync called') - } - } - pino.final(logger, (err, finalLogger) => { - error(err) - finalLogger.foo('hello') - })() - await sleep(10) - if (passed === false) fail('flushSync not called') -}) diff --git a/test/fixtures/pretty/basic.js b/test/fixtures/pretty/basic.js deleted file mode 100644 index 1c0dbed95..000000000 --- a/test/fixtures/pretty/basic.js +++ /dev/null @@ -1,6 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }) -log.info('h') diff --git a/test/fixtures/pretty/child-with-serializer.js b/test/fixtures/pretty/child-with-serializer.js deleted file mode 100644 index cb7df74cf..000000000 --- a/test/fixtures/pretty/child-with-serializer.js +++ /dev/null @@ -1,17 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: true, - serializers: { - a (num) { - return num * 2 - } - } -}) -log.info({ a: 1 }, 'h') -const child = log.child({ a: 8 }) -child.info('h2') -child.child({ b: 2 }).info('h3') -child.info({ a: 21 }, 'h4') diff --git a/test/fixtures/pretty/child-with-updated-chindings.js b/test/fixtures/pretty/child-with-updated-chindings.js deleted file mode 100644 index d5608fbb5..000000000 --- a/test/fixtures/pretty/child-with-updated-chindings.js +++ /dev/null @@ -1,8 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }).child({ foo: 123 }) -log.info('before') -log.setBindings({ foo: 456, bar: 789 }) -log.info('after') diff --git a/test/fixtures/pretty/child.js b/test/fixtures/pretty/child.js deleted file mode 100644 index 2b31c5122..000000000 --- a/test/fixtures/pretty/child.js +++ /dev/null @@ -1,8 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }).child({ a: 1 }) -log.info('h') -log.child({ b: 2 }).info('h3') -setTimeout(() => log.info('h2'), 200) diff --git a/test/fixtures/pretty/custom-time-label.js b/test/fixtures/pretty/custom-time-label.js deleted file mode 100644 index b912809a4..000000000 --- a/test/fixtures/pretty/custom-time-label.js +++ /dev/null @@ -1,9 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - timestamp: () => ',"custom-time-label":"test"', - prettyPrint: true -}) -log.info('h') diff --git a/test/fixtures/pretty/custom-time.js b/test/fixtures/pretty/custom-time.js deleted file mode 100644 index 7cfce6144..000000000 --- a/test/fixtures/pretty/custom-time.js +++ /dev/null @@ -1,9 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - timestamp: () => ',"time":"test"', - prettyPrint: true -}) -log.info('h') diff --git a/test/fixtures/pretty/dateformat.js b/test/fixtures/pretty/dateformat.js deleted file mode 100644 index d9f912b69..000000000 --- a/test/fixtures/pretty/dateformat.js +++ /dev/null @@ -1,10 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: { - translateTime: true - } -}) -log.info('h') diff --git a/test/fixtures/pretty/error-props.js b/test/fixtures/pretty/error-props.js deleted file mode 100644 index 959592bf6..000000000 --- a/test/fixtures/pretty/error-props.js +++ /dev/null @@ -1,9 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: { errorProps: 'code,errno' } -}) -const err = Object.assign(new Error('kaboom'), { code: 'ENOENT', errno: 1 }) -log.error(err) diff --git a/test/fixtures/pretty/error.js b/test/fixtures/pretty/error.js deleted file mode 100644 index 8aabc89da..000000000 --- a/test/fixtures/pretty/error.js +++ /dev/null @@ -1,7 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }) -log.error(new Error('kaboom')) -log.error(new Error('kaboom'), 'with a message') diff --git a/test/fixtures/pretty/final-no-log-before.js b/test/fixtures/pretty/final-no-log-before.js deleted file mode 100644 index fafb674c1..000000000 --- a/test/fixtures/pretty/final-no-log-before.js +++ /dev/null @@ -1,8 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }) -process.once('beforeExit', pino.final(log, (_, logger) => { - logger.info('beforeExit') -})) diff --git a/test/fixtures/pretty/final-return.js b/test/fixtures/pretty/final-return.js deleted file mode 100644 index 7f15ce3e6..000000000 --- a/test/fixtures/pretty/final-return.js +++ /dev/null @@ -1,7 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const 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 deleted file mode 100644 index 4024d6707..000000000 --- a/test/fixtures/pretty/final.js +++ /dev/null @@ -1,9 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }) -log.info('h') -process.once('beforeExit', pino.final(log, (_, logger) => { - logger.info('beforeExit') -})) diff --git a/test/fixtures/pretty/formatters.js b/test/fixtures/pretty/formatters.js deleted file mode 100644 index ac9c29def..000000000 --- a/test/fixtures/pretty/formatters.js +++ /dev/null @@ -1,13 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: true, - formatters: { - log (obj) { - return { foo: 'formatted_' + obj.foo } - } - } -}) -log.info({ foo: 'bar' }, 'h') diff --git a/test/fixtures/pretty/level-first.js b/test/fixtures/pretty/level-first.js deleted file mode 100644 index fde4f8d62..000000000 --- a/test/fixtures/pretty/level-first.js +++ /dev/null @@ -1,6 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: { levelFirst: true } }) -log.info('h') diff --git a/test/fixtures/pretty/no-time.js b/test/fixtures/pretty/no-time.js deleted file mode 100644 index 03573af8a..000000000 --- a/test/fixtures/pretty/no-time.js +++ /dev/null @@ -1,9 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - timestamp: false, - prettyPrint: true -}) -log.info('h') diff --git a/test/fixtures/pretty/obj-msg-prop.js b/test/fixtures/pretty/obj-msg-prop.js deleted file mode 100644 index 172ae9a86..000000000 --- a/test/fixtures/pretty/obj-msg-prop.js +++ /dev/null @@ -1,6 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: true }) -log.info({ msg: 'hello' }) diff --git a/test/fixtures/pretty/pretty-factory.js b/test/fixtures/pretty/pretty-factory.js deleted file mode 100644 index b32c68405..000000000 --- a/test/fixtures/pretty/pretty-factory.js +++ /dev/null @@ -1,6 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: { levelFirst: true }, prettifier: require('pino-pretty').prettyFactory }) -log.info('h') diff --git a/test/fixtures/pretty/redact.js b/test/fixtures/pretty/redact.js deleted file mode 100644 index de9aca120..000000000 --- a/test/fixtures/pretty/redact.js +++ /dev/null @@ -1,9 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: true, - redact: ['foo.an'] -}) -log.info({ foo: { an: 'object' } }, 'h') diff --git a/test/fixtures/pretty/serializers.js b/test/fixtures/pretty/serializers.js deleted file mode 100644 index 2e64d2f35..000000000 --- a/test/fixtures/pretty/serializers.js +++ /dev/null @@ -1,17 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: true, - serializers: { - foo (obj) { - if (obj.an !== 'object') { - throw new Error('kaboom') - } - - return 'bar' - } - } -}) -log.info({ foo: { an: 'object' } }, 'h') diff --git a/test/fixtures/pretty/skipped-output.js b/test/fixtures/pretty/skipped-output.js deleted file mode 100644 index 0ee5a5136..000000000 --- a/test/fixtures/pretty/skipped-output.js +++ /dev/null @@ -1,13 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ - prettyPrint: true, - prettifier: function () { - return function () { - return undefined - } - } -}) -log.info('h') diff --git a/test/fixtures/pretty/suppress-flush-sync-warning.js b/test/fixtures/pretty/suppress-flush-sync-warning.js deleted file mode 100644 index 8bd464818..000000000 --- a/test/fixtures/pretty/suppress-flush-sync-warning.js +++ /dev/null @@ -1,7 +0,0 @@ -global.process = { __proto__: process, pid: 123456 } -Date.now = function () { return 1459875739796 } -require('os').hostname = function () { return 'abcdefghijklmnopqr' } -const pino = require(require.resolve('./../../../')) -const log = pino({ prettyPrint: { suppressFlushSyncWarning: true } }) -log.info('h') -log.fatal('h1') diff --git a/test/fixtures/syncfalse-child.js b/test/fixtures/syncfalse-child.js index d7dcc4554..269ebfd0e 100644 --- a/test/fixtures/syncfalse-child.js +++ b/test/fixtures/syncfalse-child.js @@ -3,4 +3,4 @@ Date.now = function () { return 1459875739796 } require('os').hostname = function () { return 'abcdefghijklmnopqr' } const pino = require(require.resolve('./../../')) const asyncLogger = pino(pino.destination({ sync: false })).child({ hello: 'world' }) -pino.final(asyncLogger, (_, logger) => logger.info('h'))() +asyncLogger.info('h') diff --git a/test/fixtures/syncfalse.js b/test/fixtures/syncfalse.js index 00a5f5d8a..a111bd92a 100644 --- a/test/fixtures/syncfalse.js +++ b/test/fixtures/syncfalse.js @@ -3,4 +3,4 @@ Date.now = function () { return 1459875739796 } require('os').hostname = function () { return 'abcdefghijklmnopqr' } const pino = require(require.resolve('./../../')) const asyncLogger = pino(pino.destination({ minLength: 4096, sync: false })) -pino.final(asyncLogger, (_, logger) => logger.info('h'))() +asyncLogger.info('h') diff --git a/test/multistream.test.js b/test/multistream.test.js index 3838cda82..7caa321ee 100644 --- a/test/multistream.test.js +++ b/test/multistream.test.js @@ -541,21 +541,17 @@ test('multistream throws if not a stream', function (t) { test('flushSync', function (t) { const tmp = file() 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() }) }) diff --git a/test/pretty.test.js b/test/pretty.test.js deleted file mode 100644 index 43e25a28e..000000000 --- a/test/pretty.test.js +++ /dev/null @@ -1,392 +0,0 @@ -'use strict' - -const { Writable } = require('stream') -const { test } = require('tap') -const { join } = require('path') -const execa = require('execa') -const writer = require('flush-write-stream') -const { once } = require('./helper') -const pino = require('../') -const strip = require('strip-ansi') - -// silence warnings -process.removeAllListeners('warning') - -// This test MUST be the first -test('deprecation', ({ equal, plan }) => { - plan(1) - - process.once('warning', function (warning) { - equal(warning.code, 'PINODEP008') - }) - - pino({ - prettyPrint: true - }) -}) - -test('can be enabled via exported pino function', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'basic.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) -}) - -test('can be enabled via exported pino function with pretty configuration', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'level-first.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/^INFO.*h/), null) -}) - -test('can be enabled via exported pino function with prettifier', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'pretty-factory.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - - await once(child, 'close') - not(strip(actual).match(/^INFO.*h/), null) -}) - -test('does not throw error when enabled with stream specified', async ({ doesNotThrow }) => { - doesNotThrow(() => pino({ prettyPrint: true }, process.stdout)) -}) - -test('throws when prettyPrint is true but pino-pretty module is not installed', async ({ throws }) => { - // pino pretty *is* installed, and probably also cached, so rather than - // messing with the filesystem the simplest way to generate a not found - // error is to simulate it: - const prettyFactory = require('pino-pretty').prettyFactory - require('pino-pretty').prettyFactory = () => { - throw Error('Cannot find module \'pino-pretty\'') - } - throws(() => pino({ prettyPrint: true }), 'Missing `pino-pretty` module: `pino-pretty` must be installed separately') - require('pino-pretty').prettyFactory = prettyFactory -}) - -test('throws when prettyPrint has invalid options', async ({ throws }) => { - throws(() => pino({ prettyPrint: { ignore: ['hostname'] } }), 'opts.ignore.split is not a function') -}) - -test('can send pretty print to custom stream', async ({ equal }) => { - const dest = new Writable({ - objectMode: true, - write (formatted, enc) { - equal(/^INFO.*foo\n$/.test(formatted), true) - } - }) - - const log = pino({ - prettifier: require('pino-pretty').prettyFactory, - prettyPrint: { - levelFirst: true, - colorize: false - } - }, dest) - log.info('foo') -}) - -test('ignores `undefined` from prettifier', async ({ equal }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'skipped-output.js')]) - - child.stdout.pipe(writer((s, enc) => { - actual += s - })) - - await once(child, 'close') - equal(actual, '') -}) - -test('parses and outputs chindings', async ({ equal, not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'child.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h2/), null) - not(strip(actual).match(/a: 1/), null) - not(strip(actual).match(/b: 2/), null) - equal(strip(actual).match(/a: 1/g).length, 3) -}) - -test('applies updated chindings', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'child-with-updated-chindings.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/foo: 123/), null) - not(strip(actual).match(/foo: 456/), null) - not(strip(actual).match(/bar: 789/), null) -}) - -test('applies formatters', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'formatters.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) - not(strip(actual).match(/foo: "formatted_bar"/), null) -}) - -test('parses and outputs chindings with serializer', async ({ equal, not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'child-with-serializer.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h2/), null) - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h3/), null) - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h4/), null) - not(strip(actual).match(/a: 2/), null) - not(strip(actual).match(/a: 16/), null) - not(strip(actual).match(/a: 42/), null) - equal(strip(actual).match(/a: /g).length, 4) -}) - -test('applies serializers', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'serializers.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) - not(strip(actual).match(/foo: "bar"/), null) -}) - -test('applies redaction rules', async ({ equal, not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'redact.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) - not(strip(actual).match(/\[Redacted\]/), null) - equal(strip(actual).match(/object/), null) -}) - -test('dateformat', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'dateformat.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): h/), null) -}) - -test('without timestamp', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'no-time.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).slice(2), '[]') -}) - -test('with custom timestamp', async ({ equal }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'custom-time.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - equal(strip(actual).slice(0, 6), '[test]') -}) - -test('with custom timestamp label', async ({ equal }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'custom-time-label.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - equal(strip(actual).slice(0, 6), '[test]') -}) - -test('errors', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'error.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null) - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): with a message/), null) - not(strip(actual).match(/.*error\.js.*/), null) -}) - -test('errors with props', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'error-props.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): kaboom/), null) - not(strip(actual).match(/"code": "ENOENT"/), null) - not(strip(actual).match(/"errno": 1/), null) - not(strip(actual).match(/.*error-props\.js.*/), null) -}) - -test('final works with pretty', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null) - not(strip(actual).match(/INFO\s+\(123456 on abcdefghijklmnopqr\): beforeExit/), null) -}) - -test('final works when returning a logger', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final-return.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null) - not(strip(actual).match(/INFO\s+\(123456 on abcdefghijklmnopqr\): after/), null) -}) - -test('final works without prior logging', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'final-no-log-before.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/WARN\s*: pino.final with prettyPrint does not support flushing/), null) - not(strip(actual).match(/INFO\s*\(123456 on abcdefghijklmnopqr\): beforeExit/), null) -}) - -test('suppress flush sync warning when corresponding option is specified', async ({ equal }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'suppress-flush-sync-warning.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - equal(strip(actual).match(/WARN\s+\(123456 on abcdefghijklmnopqr\): pino.final with prettyPrint does not support flushing/), null) -}) - -test('works as expected with an object with the msg prop', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'obj-msg-prop.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): hello/), null) -}) - -test('handles objects with null prototypes', async ({ not }) => { - let actual = '' - const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'pretty', 'null-prototype.js')]) - - child.stdout.pipe(writer((s, enc, cb) => { - actual += s - cb() - })) - await once(child, 'close') - not(strip(actual).match(/\(123456 on abcdefghijklmnopqr\): hello\s+foo: "bar"/), null) -}) - -test('should not lose stream metadata for streams with `needsMetadataGsym` flag', async ({ not }) => { - const dest = new Writable({ - objectMode: true, - write () { - not(typeof this.lastLevel === 'undefined', true) - not(typeof this.lastMsg === 'undefined', true) - not(typeof this.lastObj === 'undefined', true) - not(typeof this.lastTime === 'undefined', true) - not(typeof this.lastLogger === 'undefined', true) - } - }) - - dest[pino.symbols.needsMetadataGsym] = true - - const log = pino({ - prettyPrint: true - }, dest) - log.info('foo') -}) - -test('should not add stream metadata for streams without `needsMetadataGsym` flag', async ({ equal }) => { - const dest = new Writable({ - objectMode: true, - write () { - equal(typeof this.lastLevel === 'undefined', true) - equal(typeof this.lastMsg === 'undefined', true) - equal(typeof this.lastObj === 'undefined', true) - equal(typeof this.lastTime === 'undefined', true) - equal(typeof this.lastLogger === 'undefined', true) - } - }) - - const log = pino({ - prettyPrint: true - }, dest) - log.info('foo') -})