First commit
This commit is contained in:
876
node_modules/pino/test/basic.test.js
generated
vendored
Normal file
876
node_modules/pino/test/basic.test.js
generated
vendored
Normal file
@@ -0,0 +1,876 @@
|
||||
'use strict'
|
||||
const os = require('node:os')
|
||||
const { readFileSync } = require('node:fs')
|
||||
const { test } = require('tap')
|
||||
const { sink, check, once, watchFileCreated, file } = require('./helper')
|
||||
const pino = require('../')
|
||||
const { version } = require('../package.json')
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
test('pino version is exposed on export', async ({ equal }) => {
|
||||
equal(pino.version, version)
|
||||
})
|
||||
|
||||
test('pino version is exposed on instance', async ({ equal }) => {
|
||||
const instance = pino()
|
||||
equal(instance.version, version)
|
||||
})
|
||||
|
||||
test('child instance exposes pino version', async ({ equal }) => {
|
||||
const child = pino().child({ foo: 'bar' })
|
||||
equal(child.version, version)
|
||||
})
|
||||
|
||||
test('bindings are exposed on every instance', async ({ same }) => {
|
||||
const instance = pino()
|
||||
same(instance.bindings(), {})
|
||||
})
|
||||
|
||||
test('bindings contain the name and the child bindings', async ({ same }) => {
|
||||
const instance = pino({ name: 'basicTest', level: 'info' }).child({ foo: 'bar' }).child({ a: 2 })
|
||||
same(instance.bindings(), { name: 'basicTest', foo: 'bar', a: 2 })
|
||||
})
|
||||
|
||||
test('set bindings on instance', async ({ same }) => {
|
||||
const instance = pino({ name: 'basicTest', level: 'info' })
|
||||
instance.setBindings({ foo: 'bar' })
|
||||
same(instance.bindings(), { name: 'basicTest', foo: 'bar' })
|
||||
})
|
||||
|
||||
test('newly set bindings overwrite old bindings', async ({ same }) => {
|
||||
const instance = pino({ name: 'basicTest', level: 'info', base: { foo: 'bar' } })
|
||||
instance.setBindings({ foo: 'baz' })
|
||||
same(instance.bindings(), { name: 'basicTest', foo: 'baz' })
|
||||
})
|
||||
|
||||
test('set bindings on child instance', async ({ same }) => {
|
||||
const child = pino({ name: 'basicTest', level: 'info' }).child({})
|
||||
child.setBindings({ foo: 'bar' })
|
||||
same(child.bindings(), { name: 'basicTest', foo: 'bar' })
|
||||
})
|
||||
|
||||
test('child should have bindings set by parent', async ({ same }) => {
|
||||
const instance = pino({ name: 'basicTest', level: 'info' })
|
||||
instance.setBindings({ foo: 'bar' })
|
||||
const child = instance.child({})
|
||||
same(child.bindings(), { name: 'basicTest', foo: 'bar' })
|
||||
})
|
||||
|
||||
test('child should not share bindings of parent set after child creation', async ({ same }) => {
|
||||
const instance = pino({ name: 'basicTest', level: 'info' })
|
||||
const child = instance.child({})
|
||||
instance.setBindings({ foo: 'bar' })
|
||||
same(instance.bindings(), { name: 'basicTest', foo: 'bar' })
|
||||
same(child.bindings(), { name: 'basicTest' })
|
||||
})
|
||||
|
||||
function levelTest (name, level) {
|
||||
test(`${name} logs as ${level}`, async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name]('hello world')
|
||||
check(equal, await once(stream, 'data'), level, 'hello world')
|
||||
})
|
||||
|
||||
test(`passing objects at level ${name}`, async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
const obj = { hello: 'world' }
|
||||
instance[name](obj)
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
equal(result.pid, pid)
|
||||
equal(result.hostname, hostname)
|
||||
equal(result.level, level)
|
||||
equal(result.hello, 'world')
|
||||
same(Object.keys(obj), ['hello'])
|
||||
})
|
||||
|
||||
test(`passing an object and a string at level ${name}`, async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
const obj = { hello: 'world' }
|
||||
instance[name](obj, 'a string')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
msg: 'a string',
|
||||
hello: 'world'
|
||||
})
|
||||
same(Object.keys(obj), ['hello'])
|
||||
})
|
||||
|
||||
test(`passing a undefined and a string at level ${name}`, async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name](undefined, 'a string')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
msg: 'a string'
|
||||
})
|
||||
})
|
||||
|
||||
test(`overriding object key by string at level ${name}`, async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name]({ hello: 'world', msg: 'object' }, 'string')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
msg: 'string',
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
|
||||
test(`formatting logs as ${name}`, async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name]('hello %d', 42)
|
||||
const result = await once(stream, 'data')
|
||||
check(equal, result, level, 'hello 42')
|
||||
})
|
||||
|
||||
test(`formatting a symbol at level ${name}`, async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
|
||||
const sym = Symbol('foo')
|
||||
instance[name]('hello %s', sym)
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
|
||||
check(equal, result, level, 'hello Symbol(foo)')
|
||||
})
|
||||
|
||||
test(`passing error with a serializer at level ${name}`, async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const err = new Error('myerror')
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
err: pino.stdSerializers.err
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({ err })
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test(`child logger for level ${name}`, async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
const child = instance.child({ hello: 'world' })
|
||||
child[name]('hello world')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
msg: 'hello world',
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
levelTest('fatal', 60)
|
||||
levelTest('error', 50)
|
||||
levelTest('warn', 40)
|
||||
levelTest('info', 30)
|
||||
levelTest('debug', 20)
|
||||
levelTest('trace', 10)
|
||||
|
||||
test('serializers can return undefined to strip field', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
test () { return undefined }
|
||||
}
|
||||
}, stream)
|
||||
|
||||
instance.info({ test: 'sensitive info' })
|
||||
const result = await once(stream, 'data')
|
||||
equal('test' in result, false)
|
||||
})
|
||||
|
||||
test('streams receive a message event with PINO_CONFIG', ({ match, end }) => {
|
||||
const stream = sink()
|
||||
stream.once('message', (message) => {
|
||||
match(message, {
|
||||
code: 'PINO_CONFIG',
|
||||
config: {
|
||||
errorKey: 'err',
|
||||
levels: {
|
||||
labels: {
|
||||
10: 'trace',
|
||||
20: 'debug',
|
||||
30: 'info',
|
||||
40: 'warn',
|
||||
50: 'error',
|
||||
60: 'fatal'
|
||||
},
|
||||
values: {
|
||||
debug: 20,
|
||||
error: 50,
|
||||
fatal: 60,
|
||||
info: 30,
|
||||
trace: 10,
|
||||
warn: 40
|
||||
}
|
||||
},
|
||||
messageKey: 'msg'
|
||||
}
|
||||
})
|
||||
end()
|
||||
})
|
||||
pino(stream)
|
||||
})
|
||||
|
||||
test('does not explode with a circular ref', async ({ doesNotThrow }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const b = {}
|
||||
const a = {
|
||||
hello: b
|
||||
}
|
||||
b.a = a // circular ref
|
||||
doesNotThrow(() => instance.info(a))
|
||||
})
|
||||
|
||||
test('set the name', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
instance.fatal('this is fatal')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: 'this is fatal'
|
||||
})
|
||||
})
|
||||
|
||||
test('set the messageKey', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const message = 'hello world'
|
||||
const messageKey = 'fooMessage'
|
||||
const instance = pino({
|
||||
messageKey
|
||||
}, stream)
|
||||
instance.info(message)
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
fooMessage: message
|
||||
})
|
||||
})
|
||||
|
||||
test('set the nestedKey', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const object = { hello: 'world' }
|
||||
const nestedKey = 'stuff'
|
||||
const instance = pino({
|
||||
nestedKey
|
||||
}, stream)
|
||||
instance.info(object)
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
stuff: object
|
||||
})
|
||||
})
|
||||
|
||||
test('set undefined properties', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info({ hello: 'world', property: undefined })
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
hello: 'world'
|
||||
})
|
||||
})
|
||||
|
||||
test('prototype properties are not logged', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info(Object.create({ hello: 'world' }))
|
||||
const { hello } = await once(stream, 'data')
|
||||
equal(hello, undefined)
|
||||
})
|
||||
|
||||
test('set the base', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
base: {
|
||||
a: 'b'
|
||||
}
|
||||
}, stream)
|
||||
|
||||
instance.fatal('this is fatal')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
a: 'b',
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
})
|
||||
})
|
||||
|
||||
test('set the base to null', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
base: null
|
||||
}, stream)
|
||||
instance.fatal('this is fatal')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
})
|
||||
})
|
||||
|
||||
test('set the base to null and use a formatter', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
base: null,
|
||||
formatters: {
|
||||
log (input) {
|
||||
return Object.assign({}, input, { additionalMessage: 'using pino' })
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
instance.fatal('this is fatal too')
|
||||
const result = await once(stream, 'data')
|
||||
equal(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
level: 60,
|
||||
msg: 'this is fatal too',
|
||||
additionalMessage: 'using pino'
|
||||
})
|
||||
})
|
||||
|
||||
test('throw if creating child without bindings', async ({ equal, fail }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
try {
|
||||
instance.child()
|
||||
fail('it should throw')
|
||||
} catch (err) {
|
||||
equal(err.message, 'missing bindings for child Pino')
|
||||
}
|
||||
})
|
||||
|
||||
test('correctly escapes msg strings with stray double quote at end', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
|
||||
instance.fatal('this contains "')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: 'this contains "'
|
||||
})
|
||||
})
|
||||
|
||||
test('correctly escape msg strings with unclosed double quote', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
instance.fatal('" this contains')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: '" this contains'
|
||||
})
|
||||
})
|
||||
|
||||
test('correctly escape quote in a key', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const obj = { 'some"obj': 'world' }
|
||||
instance.info(obj, 'a string')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
level: 30,
|
||||
pid,
|
||||
hostname,
|
||||
msg: 'a string',
|
||||
'some"obj': 'world'
|
||||
})
|
||||
same(Object.keys(obj), ['some"obj'])
|
||||
})
|
||||
|
||||
// https://github.com/pinojs/pino/issues/139
|
||||
test('object and format string', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info({}, 'foo %s', 'bar')
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'foo bar'
|
||||
})
|
||||
})
|
||||
|
||||
test('object and format string property', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info({ answer: 42 }, 'foo %s', 'bar')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'foo bar',
|
||||
answer: 42
|
||||
})
|
||||
})
|
||||
|
||||
test('correctly strip undefined when returned from toJSON', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
test: 'this'
|
||||
}, stream)
|
||||
instance.fatal({ test: { toJSON () { return undefined } } })
|
||||
const result = await once(stream, 'data')
|
||||
equal('test' in result, false)
|
||||
})
|
||||
|
||||
test('correctly supports stderr', async ({ same }) => {
|
||||
// stderr inherits from Stream, rather than Writable
|
||||
const dest = {
|
||||
writable: true,
|
||||
write (result) {
|
||||
result = JSON.parse(result)
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
msg: 'a message'
|
||||
})
|
||||
}
|
||||
}
|
||||
const instance = pino(dest)
|
||||
instance.fatal('a message')
|
||||
})
|
||||
|
||||
test('normalize number to string', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info(1)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: '1'
|
||||
})
|
||||
})
|
||||
|
||||
test('normalize number to string with an object', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info({ answer: 42 }, 1)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: '1',
|
||||
answer: 42
|
||||
})
|
||||
})
|
||||
|
||||
test('handles objects with null prototype', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const o = Object.create(null)
|
||||
o.test = 'test'
|
||||
instance.info(o)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
test: 'test'
|
||||
})
|
||||
})
|
||||
|
||||
test('pino.destination', async ({ same }) => {
|
||||
const tmp = file()
|
||||
const instance = pino(pino.destination(tmp))
|
||||
instance.info('hello')
|
||||
await watchFileCreated(tmp)
|
||||
const result = JSON.parse(readFileSync(tmp).toString())
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
})
|
||||
|
||||
test('auto pino.destination with a string', async ({ same }) => {
|
||||
const tmp = file()
|
||||
const instance = pino(tmp)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(tmp)
|
||||
const result = JSON.parse(readFileSync(tmp).toString())
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
})
|
||||
|
||||
test('auto pino.destination with a string as second argument', async ({ same }) => {
|
||||
const tmp = file()
|
||||
const instance = pino(null, tmp)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(tmp)
|
||||
const result = JSON.parse(readFileSync(tmp).toString())
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
})
|
||||
|
||||
test('does not override opts with a string as second argument', async ({ same }) => {
|
||||
const tmp = file()
|
||||
const instance = pino({
|
||||
timestamp: () => ',"time":"none"'
|
||||
}, tmp)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(tmp)
|
||||
const result = JSON.parse(readFileSync(tmp).toString())
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
time: 'none',
|
||||
msg: 'hello'
|
||||
})
|
||||
})
|
||||
|
||||
// https://github.com/pinojs/pino/issues/222
|
||||
test('children with same names render in correct order', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const root = pino(stream)
|
||||
root.child({ a: 1 }).child({ a: 2 }).info({ a: 3 })
|
||||
const { a } = await once(stream, 'data')
|
||||
equal(a, 3, 'last logged object takes precedence')
|
||||
})
|
||||
|
||||
test('use `safe-stable-stringify` to avoid circular dependencies', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const root = pino(stream)
|
||||
// circular depth
|
||||
const obj = {}
|
||||
obj.a = obj
|
||||
root.info(obj)
|
||||
const { a } = await once(stream, 'data')
|
||||
same(a, { a: '[Circular]' })
|
||||
})
|
||||
|
||||
test('correctly log non circular objects', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const root = pino(stream)
|
||||
const obj = {}
|
||||
let parent = obj
|
||||
for (let i = 0; i < 10; i++) {
|
||||
parent.node = {}
|
||||
parent = parent.node
|
||||
}
|
||||
root.info(obj)
|
||||
const { node } = await once(stream, 'data')
|
||||
same(node, { node: { node: { node: { node: { node: { node: { node: { node: { node: {} } } } } } } } } })
|
||||
})
|
||||
|
||||
test('safe-stable-stringify must be used when interpolating', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { a: { b: {} } }
|
||||
o.a.b.c = o.a.b
|
||||
instance.info('test %j', o)
|
||||
|
||||
const { msg } = await once(stream, 'data')
|
||||
t.equal(msg, 'test {"a":{"b":{"c":"[Circular]"}}}')
|
||||
})
|
||||
|
||||
test('throws when setting useOnlyCustomLevels without customLevels', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({
|
||||
useOnlyCustomLevels: true
|
||||
})
|
||||
}, 'customLevels is required if useOnlyCustomLevels is set true')
|
||||
})
|
||||
|
||||
test('correctly log Infinity', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { num: Infinity }
|
||||
instance.info(o)
|
||||
|
||||
const { num } = await once(stream, 'data')
|
||||
t.equal(num, null)
|
||||
})
|
||||
|
||||
test('correctly log -Infinity', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { num: -Infinity }
|
||||
instance.info(o)
|
||||
|
||||
const { num } = await once(stream, 'data')
|
||||
t.equal(num, null)
|
||||
})
|
||||
|
||||
test('correctly log NaN', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { num: NaN }
|
||||
instance.info(o)
|
||||
|
||||
const { num } = await once(stream, 'data')
|
||||
t.equal(num, null)
|
||||
})
|
||||
|
||||
test('offers a .default() method to please typescript', async ({ equal }) => {
|
||||
equal(pino.default, pino)
|
||||
|
||||
const stream = sink()
|
||||
const instance = pino.default(stream)
|
||||
instance.info('hello world')
|
||||
check(equal, await once(stream, 'data'), 30, 'hello world')
|
||||
})
|
||||
|
||||
test('correctly skip function', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { num: NaN }
|
||||
instance.info(o, () => {})
|
||||
|
||||
const { msg } = await once(stream, 'data')
|
||||
t.equal(msg, undefined)
|
||||
})
|
||||
|
||||
test('correctly skip Infinity', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { num: NaN }
|
||||
instance.info(o, Infinity)
|
||||
|
||||
const { msg } = await once(stream, 'data')
|
||||
t.equal(msg, null)
|
||||
})
|
||||
|
||||
test('correctly log number', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
const o = { num: NaN }
|
||||
instance.info(o, 42)
|
||||
|
||||
const { msg } = await once(stream, 'data')
|
||||
t.equal(msg, 42)
|
||||
})
|
||||
|
||||
test('nestedKey should not be used for non-objects', async ({ strictSame }) => {
|
||||
const stream = sink()
|
||||
const message = 'hello'
|
||||
const nestedKey = 'stuff'
|
||||
const instance = pino({
|
||||
nestedKey
|
||||
}, stream)
|
||||
instance.info(message)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
strictSame(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
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)'))
|
||||
})
|
||||
|
||||
test('Should invoke `onChild` with the newly created child', async ({ equal }) => {
|
||||
let innerChild
|
||||
const child = pino({
|
||||
onChild: (instance) => {
|
||||
innerChild = instance
|
||||
}
|
||||
}).child({ foo: 'bar' })
|
||||
equal(child, innerChild)
|
||||
})
|
||||
|
||||
test('logger message should have the prefix message that defined in the logger creation', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
msgPrefix: 'My name is Bond '
|
||||
}, stream)
|
||||
equal(logger.msgPrefix, 'My name is Bond ')
|
||||
logger.info('James Bond')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'My name is Bond James Bond')
|
||||
})
|
||||
|
||||
test('child message should have the prefix message that defined in the child creation', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const child = instance.child({}, { msgPrefix: 'My name is Bond ' })
|
||||
child.info('James Bond')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'My name is Bond James Bond')
|
||||
})
|
||||
|
||||
test('child message should have the prefix message that defined in the child creation when logging with log meta', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const child = instance.child({}, { msgPrefix: 'My name is Bond ' })
|
||||
child.info({ hello: 'world' }, 'James Bond')
|
||||
const { msg, hello } = await once(stream, 'data')
|
||||
equal(hello, 'world')
|
||||
equal(msg, 'My name is Bond James Bond')
|
||||
})
|
||||
|
||||
test('logged message should not have the prefix when not providing any message', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const child = instance.child({}, { msgPrefix: 'This should not be shown ' })
|
||||
child.info({ hello: 'world' })
|
||||
const { msg, hello } = await once(stream, 'data')
|
||||
equal(hello, 'world')
|
||||
equal(msg, undefined)
|
||||
})
|
||||
|
||||
test('child message should append parent prefix to current prefix that defined in the child creation', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
msgPrefix: 'My name is Bond '
|
||||
}, stream)
|
||||
const child = instance.child({}, { msgPrefix: 'James ' })
|
||||
child.info('Bond')
|
||||
equal(child.msgPrefix, 'My name is Bond James ')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'My name is Bond James Bond')
|
||||
})
|
||||
|
||||
test('child message should inherent parent prefix', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
msgPrefix: 'My name is Bond '
|
||||
}, stream)
|
||||
const child = instance.child({})
|
||||
child.info('James Bond')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'My name is Bond James Bond')
|
||||
})
|
||||
|
||||
test('grandchild message should inherent parent prefix', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
const child = instance.child({}, { msgPrefix: 'My name is Bond ' })
|
||||
const grandchild = child.child({})
|
||||
grandchild.info('James Bond')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'My name is Bond James Bond')
|
||||
})
|
||||
57
node_modules/pino/test/broken-pipe.test.js
generated
vendored
Normal file
57
node_modules/pino/test/broken-pipe.test.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict'
|
||||
|
||||
const t = require('tap')
|
||||
const { join } = require('node:path')
|
||||
const { fork } = require('node:child_process')
|
||||
const { once } = require('./helper')
|
||||
const pino = require('..')
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
t.skip('skipping on windows')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (process.env.CITGM) {
|
||||
// This looks like a some form of limitations of the CITGM test runner
|
||||
// or the HW/SW we run it on. This file can hang on Node.js v18.x.
|
||||
// The failure does not reproduce locally or on our CI.
|
||||
// Skipping it is the only way to keep pino in CITGM.
|
||||
// https://github.com/nodejs/citgm/pull/1002#issuecomment-1751942988
|
||||
t.skip('Skipping on Node.js core CITGM because it hangs on v18.x')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
function test (file) {
|
||||
file = join('fixtures', 'broken-pipe', file)
|
||||
t.test(file, { parallel: true }, async ({ equal }) => {
|
||||
const child = fork(join(__dirname, file), { silent: true })
|
||||
child.stdout.destroy()
|
||||
|
||||
child.stderr.pipe(process.stdout)
|
||||
|
||||
const res = await once(child, 'close')
|
||||
equal(res, 0) // process exits successfully
|
||||
})
|
||||
}
|
||||
|
||||
t.jobs = 42
|
||||
|
||||
test('basic.js')
|
||||
test('destination.js')
|
||||
test('syncfalse.js')
|
||||
|
||||
t.test('let error pass through', ({ equal, plan }) => {
|
||||
plan(3)
|
||||
const stream = pino.destination({ sync: true })
|
||||
|
||||
// side effect of the pino constructor is that it will set an
|
||||
// event handler for error
|
||||
pino(stream)
|
||||
|
||||
process.nextTick(() => stream.emit('error', new Error('kaboom')))
|
||||
process.nextTick(() => stream.emit('error', new Error('kaboom')))
|
||||
|
||||
stream.on('error', (err) => {
|
||||
equal(err.message, 'kaboom')
|
||||
})
|
||||
})
|
||||
132
node_modules/pino/test/browser-child.test.js
generated
vendored
Normal file
132
node_modules/pino/test/browser-child.test.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
test('child has parent level', ({ end, same, is }) => {
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {}
|
||||
})
|
||||
|
||||
const child = instance.child({})
|
||||
|
||||
same(child.level, instance.level)
|
||||
end()
|
||||
})
|
||||
|
||||
test('child can set level at creation time', ({ end, same, is }) => {
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {}
|
||||
})
|
||||
|
||||
const child = instance.child({}, { level: 'info' }) // first bindings, then options
|
||||
|
||||
same(child.level, 'info')
|
||||
end()
|
||||
})
|
||||
|
||||
test('changing child level does not affect parent', ({ end, same, is }) => {
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {}
|
||||
})
|
||||
|
||||
const child = instance.child({})
|
||||
child.level = 'info'
|
||||
|
||||
same(instance.level, 'error')
|
||||
end()
|
||||
})
|
||||
|
||||
test('child should log, if its own level allows it', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 30,
|
||||
msg: 'this is info'
|
||||
},
|
||||
{
|
||||
level: 40,
|
||||
msg: 'this is warn'
|
||||
},
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = instance.child({})
|
||||
child.level = 'info'
|
||||
|
||||
child.debug('this is debug')
|
||||
child.info('this is info')
|
||||
child.warn('this is warn')
|
||||
child.error('this is an error')
|
||||
|
||||
same(expected.length, 0, 'not all messages were read')
|
||||
end()
|
||||
})
|
||||
|
||||
test('changing child log level should not affect parent log behavior', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = instance.child({})
|
||||
child.level = 'info'
|
||||
|
||||
instance.warn('this is warn')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
same(expected.length, 0, 'not all messages were read')
|
||||
end()
|
||||
})
|
||||
|
||||
test('onChild callback should be called when new child is created', ({ end, pass, plan }) => {
|
||||
plan(1)
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {},
|
||||
onChild: (_child) => {
|
||||
pass('onChild callback was called')
|
||||
end()
|
||||
}
|
||||
})
|
||||
|
||||
instance.child({})
|
||||
})
|
||||
|
||||
function checkLogObjects (is, same, actual, expected) {
|
||||
is(actual.time <= Date.now(), true, 'time is greater than Date.now()')
|
||||
|
||||
const actualCopy = Object.assign({}, actual)
|
||||
const expectedCopy = Object.assign({}, expected)
|
||||
delete actualCopy.time
|
||||
delete expectedCopy.time
|
||||
|
||||
same(actualCopy, expectedCopy)
|
||||
}
|
||||
87
node_modules/pino/test/browser-disabled.test.js
generated
vendored
Normal file
87
node_modules/pino/test/browser-disabled.test.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
test('set browser opts disabled to true', ({ end, same }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
disabled: true,
|
||||
write (actual) {
|
||||
checkLogObjects(same, actual, [])
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set browser opts disabled to false', ({ end, same }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 30,
|
||||
msg: 'hello world'
|
||||
},
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
browser: {
|
||||
disabled: false,
|
||||
write (actual) {
|
||||
checkLogObjects(same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('disabled is not set in browser opts', ({ end, same }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 30,
|
||||
msg: 'hello world'
|
||||
},
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
function checkLogObjects (same, actual, expected, is) {
|
||||
const actualCopy = Object.assign({}, actual)
|
||||
const expectedCopy = Object.assign({}, expected)
|
||||
delete actualCopy.time
|
||||
delete expectedCopy.time
|
||||
|
||||
same(actualCopy, expectedCopy)
|
||||
}
|
||||
12
node_modules/pino/test/browser-early-console-freeze.test.js
generated
vendored
Normal file
12
node_modules/pino/test/browser-early-console-freeze.test.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict'
|
||||
Object.freeze(console)
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
test('silent level', ({ end, fail, pass }) => {
|
||||
pino({
|
||||
level: 'silent',
|
||||
browser: { }
|
||||
})
|
||||
end()
|
||||
})
|
||||
104
node_modules/pino/test/browser-is-level-enabled.test.js
generated
vendored
Normal file
104
node_modules/pino/test/browser-is-level-enabled.test.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const pino = require('../browser')
|
||||
|
||||
const customLevels = {
|
||||
trace: 10,
|
||||
debug: 20,
|
||||
info: 30,
|
||||
warn: 40,
|
||||
error: 50,
|
||||
fatal: 60
|
||||
}
|
||||
|
||||
test('Default levels suite', ({ test, end }) => {
|
||||
test('can check if current level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if current level enabled when as object', async ({ equal }) => {
|
||||
const log = pino({ asObject: true, level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if level enabled after level set', async ({ equal }) => {
|
||||
const log = pino()
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
log.level = 'debug'
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if higher level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
})
|
||||
|
||||
test('can check if lower level is disabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error' })
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('ASC: can check if child has current level enabled', async ({ equal }) => {
|
||||
const log = pino().child({}, { level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if custom level is enabled', async ({ equal }) => {
|
||||
const log = pino({
|
||||
customLevels: { foo: 35 },
|
||||
level: 'debug'
|
||||
})
|
||||
equal(true, log.isLevelEnabled('foo'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('Custom levels suite', ({ test, end }) => {
|
||||
test('can check if current level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug', customLevels })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if level enabled after level set', async ({ equal }) => {
|
||||
const log = pino({ customLevels })
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
log.level = 'debug'
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if higher level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug', customLevels })
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
})
|
||||
|
||||
test('can check if lower level is disabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error', customLevels })
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if child has current level enabled', async ({ equal }) => {
|
||||
const log = pino().child({ customLevels }, { level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if custom level is enabled', async ({ equal }) => {
|
||||
const log = pino({
|
||||
customLevels: { foo: 35, ...customLevels },
|
||||
level: 'debug'
|
||||
})
|
||||
equal(true, log.isLevelEnabled('foo'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
241
node_modules/pino/test/browser-levels.test.js
generated
vendored
Normal file
241
node_modules/pino/test/browser-levels.test.js
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
test('set the level by string', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set the level by string. init with silent', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set the level by string. init with silent and transmit', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
},
|
||||
transmit: {
|
||||
send () {}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set the level via constructor', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set custom level and use it', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 31,
|
||||
msg: 'this is a custom level'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
customLevels: {
|
||||
success: 31
|
||||
},
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.success('this is a custom level')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('the wrong level throws', ({ end, throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => {
|
||||
instance.level = 'kaboom'
|
||||
})
|
||||
end()
|
||||
})
|
||||
|
||||
test('the wrong level by number throws', ({ end, throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => {
|
||||
instance.levelVal = 55
|
||||
})
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes level string mappings', ({ end, is }) => {
|
||||
is(pino.levels.values.error, 50)
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes level number mappings', ({ end, is }) => {
|
||||
is(pino.levels.labels[50], 'error')
|
||||
end()
|
||||
})
|
||||
|
||||
test('returns level integer', ({ end, is }) => {
|
||||
const instance = pino({ level: 'error' })
|
||||
is(instance.levelVal, 50)
|
||||
end()
|
||||
})
|
||||
|
||||
test('silent level via constructor', ({ end, fail }) => {
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write () {
|
||||
fail('no data should be logged')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('silent level by string', ({ end, fail }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write () {
|
||||
fail('no data should be logged')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'silent'
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposed levels', ({ end, same }) => {
|
||||
same(Object.keys(pino.levels.values), [
|
||||
'fatal',
|
||||
'error',
|
||||
'warn',
|
||||
'info',
|
||||
'debug',
|
||||
'trace'
|
||||
])
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposed labels', ({ end, same }) => {
|
||||
same(Object.keys(pino.levels.labels), [
|
||||
'10',
|
||||
'20',
|
||||
'30',
|
||||
'40',
|
||||
'50',
|
||||
'60'
|
||||
])
|
||||
end()
|
||||
})
|
||||
|
||||
function checkLogObjects (is, same, actual, expected) {
|
||||
is(actual.time <= Date.now(), true, 'time is greater than Date.now()')
|
||||
|
||||
const actualCopy = Object.assign({}, actual)
|
||||
const expectedCopy = Object.assign({}, expected)
|
||||
delete actualCopy.time
|
||||
delete expectedCopy.time
|
||||
|
||||
same(actualCopy, expectedCopy)
|
||||
}
|
||||
352
node_modules/pino/test/browser-serializers.test.js
generated
vendored
Normal file
352
node_modules/pino/test/browser-serializers.test.js
generated
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
'use strict'
|
||||
// eslint-disable-next-line
|
||||
if (typeof $1 !== 'undefined') $1 = arguments.callee.caller.arguments[0]
|
||||
|
||||
const test = require('tape')
|
||||
const fresh = require('import-fresh')
|
||||
const pino = require('../browser')
|
||||
|
||||
const parentSerializers = {
|
||||
test: () => 'parent'
|
||||
}
|
||||
|
||||
const childSerializers = {
|
||||
test: () => 'child'
|
||||
}
|
||||
|
||||
test('serializers override values', ({ end, is }) => {
|
||||
const parent = pino({
|
||||
serializers: parentSerializers,
|
||||
browser: {
|
||||
serialize: true,
|
||||
write (o) {
|
||||
is(o.test, 'parent')
|
||||
end()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
parent.fatal({ test: 'test' })
|
||||
})
|
||||
|
||||
test('without the serialize option, serializers do not override values', ({ end, is }) => {
|
||||
const parent = pino({
|
||||
serializers: parentSerializers,
|
||||
browser: {
|
||||
write (o) {
|
||||
is(o.test, 'test')
|
||||
end()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
parent.fatal({ test: 'test' })
|
||||
})
|
||||
|
||||
if (process.title !== 'browser') {
|
||||
test('if serialize option is true, standard error serializer is auto enabled', ({ end, same }) => {
|
||||
const err = Error('test')
|
||||
err.code = 'test'
|
||||
err.type = 'Error' // get that cov
|
||||
const expect = pino.stdSerializers.err(err)
|
||||
|
||||
const consoleError = console.error
|
||||
console.error = function (err) {
|
||||
same(err, expect)
|
||||
}
|
||||
|
||||
const logger = fresh('../browser')({
|
||||
browser: { serialize: true }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.fatal(err)
|
||||
end()
|
||||
})
|
||||
|
||||
test('if serialize option is array, standard error serializer is auto enabled', ({ end, same }) => {
|
||||
const err = Error('test')
|
||||
err.code = 'test'
|
||||
const expect = pino.stdSerializers.err(err)
|
||||
|
||||
const consoleError = console.error
|
||||
console.error = function (err) {
|
||||
same(err, expect)
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
browser: { serialize: [] }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.fatal(err)
|
||||
end()
|
||||
})
|
||||
|
||||
test('if serialize option is array containing !stdSerializers.err, standard error serializer is disabled', ({ end, is }) => {
|
||||
const err = Error('test')
|
||||
err.code = 'test'
|
||||
const expect = err
|
||||
|
||||
const consoleError = console.error
|
||||
console.error = function (err) {
|
||||
is(err, expect)
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
browser: { serialize: ['!stdSerializers.err'] }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.fatal(err)
|
||||
end()
|
||||
})
|
||||
|
||||
test('in browser, serializers apply to all objects', ({ end, is }) => {
|
||||
const consoleError = console.error
|
||||
console.error = function (test, test2, test3, test4, test5) {
|
||||
is(test.key, 'serialized')
|
||||
is(test2.key2, 'serialized2')
|
||||
is(test5.key3, 'serialized3')
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
serializers: {
|
||||
key: () => 'serialized',
|
||||
key2: () => 'serialized2',
|
||||
key3: () => 'serialized3'
|
||||
},
|
||||
browser: { serialize: true }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('serialize can be an array of selected serializers', ({ end, is }) => {
|
||||
const consoleError = console.error
|
||||
console.error = function (test, test2, test3, test4, test5) {
|
||||
is(test.key, 'test')
|
||||
is(test2.key2, 'serialized2')
|
||||
is(test5.key3, 'test')
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
serializers: {
|
||||
key: () => 'serialized',
|
||||
key2: () => 'serialized2',
|
||||
key3: () => 'serialized3'
|
||||
},
|
||||
browser: { serialize: ['key2'] }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('serialize filter applies to child loggers', ({ end, is }) => {
|
||||
const consoleError = console.error
|
||||
console.error = function (binding, test, test2, test3, test4, test5) {
|
||||
is(test.key, 'test')
|
||||
is(test2.key2, 'serialized2')
|
||||
is(test5.key3, 'test')
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
browser: { serialize: ['key2'] }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.child({
|
||||
aBinding: 'test'
|
||||
}, {
|
||||
serializers: {
|
||||
key: () => 'serialized',
|
||||
key2: () => 'serialized2',
|
||||
key3: () => 'serialized3'
|
||||
}
|
||||
}).fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('serialize filter applies to child loggers through bindings', ({ end, is }) => {
|
||||
const consoleError = console.error
|
||||
console.error = function (binding, test, test2, test3, test4, test5) {
|
||||
is(test.key, 'test')
|
||||
is(test2.key2, 'serialized2')
|
||||
is(test5.key3, 'test')
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
browser: { serialize: ['key2'] }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.child({
|
||||
aBinding: 'test',
|
||||
serializers: {
|
||||
key: () => 'serialized',
|
||||
key2: () => 'serialized2',
|
||||
key3: () => 'serialized3'
|
||||
}
|
||||
}).fatal({ key: 'test' }, { key2: 'test' }, 'str should skip', [{ foo: 'array should skip' }], { key3: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('parent serializers apply to child bindings', ({ end, is }) => {
|
||||
const consoleError = console.error
|
||||
console.error = function (binding) {
|
||||
is(binding.key, 'serialized')
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
serializers: {
|
||||
key: () => 'serialized'
|
||||
},
|
||||
browser: { serialize: true }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.child({ key: 'test' }).fatal({ test: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('child serializers apply to child bindings', ({ end, is }) => {
|
||||
const consoleError = console.error
|
||||
console.error = function (binding) {
|
||||
is(binding.key, 'serialized')
|
||||
}
|
||||
|
||||
const logger = fresh('../browser', require)({
|
||||
browser: { serialize: true }
|
||||
})
|
||||
|
||||
console.error = consoleError
|
||||
|
||||
logger.child({
|
||||
key: 'test'
|
||||
}, {
|
||||
serializers: {
|
||||
key: () => 'serialized'
|
||||
}
|
||||
}).fatal({ test: 'test' })
|
||||
end()
|
||||
})
|
||||
}
|
||||
|
||||
test('child does not overwrite parent serializers', ({ end, is }) => {
|
||||
let c = 0
|
||||
const parent = pino({
|
||||
serializers: parentSerializers,
|
||||
browser: {
|
||||
serialize: true,
|
||||
write (o) {
|
||||
c++
|
||||
if (c === 1) is(o.test, 'parent')
|
||||
if (c === 2) {
|
||||
is(o.test, 'child')
|
||||
end()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
const child = parent.child({}, { serializers: childSerializers })
|
||||
|
||||
parent.fatal({ test: 'test' })
|
||||
child.fatal({ test: 'test' })
|
||||
})
|
||||
|
||||
test('children inherit parent serializers', ({ end, is }) => {
|
||||
const parent = pino({
|
||||
serializers: parentSerializers,
|
||||
browser: {
|
||||
serialize: true,
|
||||
write (o) {
|
||||
is(o.test, 'parent')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = parent.child({ a: 'property' })
|
||||
child.fatal({ test: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('children serializers get called', ({ end, is }) => {
|
||||
const parent = pino({
|
||||
browser: {
|
||||
serialize: true,
|
||||
write (o) {
|
||||
is(o.test, 'child')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = parent.child({ a: 'property' }, { serializers: childSerializers })
|
||||
|
||||
child.fatal({ test: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('children serializers get called when inherited from parent', ({ end, is }) => {
|
||||
const parent = pino({
|
||||
serializers: parentSerializers,
|
||||
browser: {
|
||||
serialize: true,
|
||||
write: (o) => {
|
||||
is(o.test, 'pass')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = parent.child({}, { serializers: { test: () => 'pass' } })
|
||||
|
||||
child.fatal({ test: 'fail' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('non overridden serializers are available in the children', ({ end, is }) => {
|
||||
const pSerializers = {
|
||||
onlyParent: () => 'parent',
|
||||
shared: () => 'parent'
|
||||
}
|
||||
|
||||
const cSerializers = {
|
||||
shared: () => 'child',
|
||||
onlyChild: () => 'child'
|
||||
}
|
||||
|
||||
let c = 0
|
||||
|
||||
const parent = pino({
|
||||
serializers: pSerializers,
|
||||
browser: {
|
||||
serialize: true,
|
||||
write (o) {
|
||||
c++
|
||||
if (c === 1) is(o.shared, 'child')
|
||||
if (c === 2) is(o.onlyParent, 'parent')
|
||||
if (c === 3) is(o.onlyChild, 'child')
|
||||
if (c === 4) is(o.onlyChild, 'test')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = parent.child({}, { serializers: cSerializers })
|
||||
|
||||
child.fatal({ shared: 'test' })
|
||||
child.fatal({ onlyParent: 'test' })
|
||||
child.fatal({ onlyChild: 'test' })
|
||||
parent.fatal({ onlyChild: 'test' })
|
||||
end()
|
||||
})
|
||||
88
node_modules/pino/test/browser-timestamp.test.js
generated
vendored
Normal file
88
node_modules/pino/test/browser-timestamp.test.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
Date.now = () => 1599400603614
|
||||
|
||||
test('null timestamp', ({ end, is }) => {
|
||||
const instance = pino({
|
||||
timestamp: pino.stdTimeFunctions.nullTime,
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.time, undefined)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
end()
|
||||
})
|
||||
|
||||
test('iso timestamp', ({ end, is }) => {
|
||||
const instance = pino({
|
||||
timestamp: pino.stdTimeFunctions.isoTime,
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.time, '2020-09-06T13:56:43.614Z')
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
end()
|
||||
})
|
||||
|
||||
test('epoch timestamp', ({ end, is }) => {
|
||||
const instance = pino({
|
||||
timestamp: pino.stdTimeFunctions.epochTime,
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.time, 1599400603614)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
end()
|
||||
})
|
||||
|
||||
test('unix timestamp', ({ end, is }) => {
|
||||
const instance = pino({
|
||||
timestamp: pino.stdTimeFunctions.unixTime,
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.time, Math.round(1599400603614 / 1000.0))
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
end()
|
||||
})
|
||||
|
||||
test('epoch timestamp by default', ({ end, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.time, 1599400603614)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
end()
|
||||
})
|
||||
|
||||
test('not print timestamp if the option is false', ({ end, is }) => {
|
||||
const instance = pino({
|
||||
timestamp: false,
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.time, undefined)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('hello world')
|
||||
end()
|
||||
})
|
||||
417
node_modules/pino/test/browser-transmit.test.js
generated
vendored
Normal file
417
node_modules/pino/test/browser-transmit.test.js
generated
vendored
Normal file
@@ -0,0 +1,417 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
function noop () {}
|
||||
|
||||
test('throws if transmit object does not have send function', ({ end, throws }) => {
|
||||
throws(() => {
|
||||
pino({ browser: { transmit: {} } })
|
||||
})
|
||||
|
||||
throws(() => {
|
||||
pino({ browser: { transmit: { send: 'not a func' } } })
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('calls send function after write', ({ end, is }) => {
|
||||
let c = 0
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: () => {
|
||||
c++
|
||||
},
|
||||
transmit: {
|
||||
send () { is(c, 1) }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal({ test: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function the logged level', ({ end, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write () {},
|
||||
transmit: {
|
||||
send (level) {
|
||||
is(level, 'fatal')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal({ test: 'test' })
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function message strings in logEvent object when asObject is not set', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, { messages }) {
|
||||
is(messages[0], 'test')
|
||||
is(messages[1], 'another test')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal('test', 'another test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function message objects in logEvent object when asObject is not set', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, { messages }) {
|
||||
same(messages[0], { test: 'test' })
|
||||
is(messages[1], 'another test')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal({ test: 'test' }, 'another test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function message strings in logEvent object when asObject is set', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, { messages }) {
|
||||
is(messages[0], 'test')
|
||||
is(messages[1], 'another test')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal('test', 'another test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function message objects in logEvent object when asObject is set', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, { messages }) {
|
||||
same(messages[0], { test: 'test' })
|
||||
is(messages[1], 'another test')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal({ test: 'test' }, 'another test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('supplies a timestamp (ts) in logEvent object which is exactly the same as the `time` property in asObject mode', ({ end, is }) => {
|
||||
let expected
|
||||
const logger = pino({
|
||||
browser: {
|
||||
asObject: true, // implicit because `write`, but just to be explicit
|
||||
write (o) {
|
||||
expected = o.time
|
||||
},
|
||||
transmit: {
|
||||
send (level, logEvent) {
|
||||
is(logEvent.ts, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function child bindings via logEvent object', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, logEvent) {
|
||||
const messages = logEvent.messages
|
||||
const bindings = logEvent.bindings
|
||||
same(bindings[0], { first: 'binding' })
|
||||
same(bindings[1], { second: 'binding2' })
|
||||
same(messages[0], { test: 'test' })
|
||||
is(messages[1], 'another test')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger
|
||||
.child({ first: 'binding' })
|
||||
.child({ second: 'binding2' })
|
||||
.fatal({ test: 'test' }, 'another test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('passes send function level:{label, value} via logEvent object', ({ end, is }) => {
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, logEvent) {
|
||||
const label = logEvent.level.label
|
||||
const value = logEvent.level.value
|
||||
|
||||
is(label, 'fatal')
|
||||
is(value, 60)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.fatal({ test: 'test' }, 'another test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('calls send function according to transmit.level', ({ end, is }) => {
|
||||
let c = 0
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
level: 'error',
|
||||
send (level) {
|
||||
c++
|
||||
if (c === 1) is(level, 'error')
|
||||
if (c === 2) is(level, 'fatal')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
logger.warn('ignored')
|
||||
logger.error('test')
|
||||
logger.fatal('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('transmit.level defaults to logger level', ({ end, is }) => {
|
||||
let c = 0
|
||||
const logger = pino({
|
||||
level: 'error',
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level) {
|
||||
c++
|
||||
if (c === 1) is(level, 'error')
|
||||
if (c === 2) is(level, 'fatal')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
logger.warn('ignored')
|
||||
logger.error('test')
|
||||
logger.fatal('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('transmit.level is effective even if lower than logger level', ({ end, is }) => {
|
||||
let c = 0
|
||||
const logger = pino({
|
||||
level: 'error',
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
level: 'info',
|
||||
send (level) {
|
||||
c++
|
||||
if (c === 1) is(level, 'warn')
|
||||
if (c === 2) is(level, 'error')
|
||||
if (c === 3) is(level, 'fatal')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
logger.warn('ignored')
|
||||
logger.error('test')
|
||||
logger.fatal('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('applies all serializers to messages and bindings (serialize:false - default)', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
serializers: {
|
||||
first: () => 'first',
|
||||
second: () => 'second',
|
||||
test: () => 'serialize it'
|
||||
},
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, logEvent) {
|
||||
const messages = logEvent.messages
|
||||
const bindings = logEvent.bindings
|
||||
same(bindings[0], { first: 'first' })
|
||||
same(bindings[1], { second: 'second' })
|
||||
same(messages[0], { test: 'serialize it' })
|
||||
is(messages[1].type, 'Error')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger
|
||||
.child({ first: 'binding' })
|
||||
.child({ second: 'binding2' })
|
||||
.fatal({ test: 'test' }, Error())
|
||||
end()
|
||||
})
|
||||
|
||||
test('applies all serializers to messages and bindings (serialize:true)', ({ end, same, is }) => {
|
||||
const logger = pino({
|
||||
serializers: {
|
||||
first: () => 'first',
|
||||
second: () => 'second',
|
||||
test: () => 'serialize it'
|
||||
},
|
||||
browser: {
|
||||
serialize: true,
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, logEvent) {
|
||||
const messages = logEvent.messages
|
||||
const bindings = logEvent.bindings
|
||||
same(bindings[0], { first: 'first' })
|
||||
same(bindings[1], { second: 'second' })
|
||||
same(messages[0], { test: 'serialize it' })
|
||||
is(messages[1].type, 'Error')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger
|
||||
.child({ first: 'binding' })
|
||||
.child({ second: 'binding2' })
|
||||
.fatal({ test: 'test' }, Error())
|
||||
end()
|
||||
})
|
||||
|
||||
test('extracts correct bindings and raw messages over multiple transmits', ({ end, same, is }) => {
|
||||
let messages = null
|
||||
let bindings = null
|
||||
|
||||
const logger = pino({
|
||||
browser: {
|
||||
write: noop,
|
||||
transmit: {
|
||||
send (level, logEvent) {
|
||||
messages = logEvent.messages
|
||||
bindings = logEvent.bindings
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const child = logger.child({ child: true })
|
||||
const grandchild = child.child({ grandchild: true })
|
||||
|
||||
logger.fatal({ test: 'parent:test1' })
|
||||
logger.fatal({ test: 'parent:test2' })
|
||||
same([], bindings)
|
||||
same([{ test: 'parent:test2' }], messages)
|
||||
|
||||
child.fatal({ test: 'child:test1' })
|
||||
child.fatal({ test: 'child:test2' })
|
||||
same([{ child: true }], bindings)
|
||||
same([{ test: 'child:test2' }], messages)
|
||||
|
||||
grandchild.fatal({ test: 'grandchild:test1' })
|
||||
grandchild.fatal({ test: 'grandchild:test2' })
|
||||
same([{ child: true }, { grandchild: true }], bindings)
|
||||
same([{ test: 'grandchild:test2' }], messages)
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('does not log below configured level', ({ end, is }) => {
|
||||
let message = null
|
||||
const logger = pino({
|
||||
level: 'info',
|
||||
browser: {
|
||||
write (o) {
|
||||
message = o.msg
|
||||
},
|
||||
transmit: {
|
||||
send () { }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
logger.debug('this message is silent')
|
||||
is(message, null)
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('silent level prevents logging even with transmit', ({ end, fail }) => {
|
||||
const logger = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write () {
|
||||
fail('no data should be logged by the write method')
|
||||
},
|
||||
transmit: {
|
||||
send () {
|
||||
fail('no data should be logged by the send method')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
logger[level]('ignored')
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('does not call send when transmit.level is set to silent', ({ end, fail, is }) => {
|
||||
let c = 0
|
||||
const logger = pino({
|
||||
level: 'trace',
|
||||
browser: {
|
||||
write () {
|
||||
c++
|
||||
},
|
||||
transmit: {
|
||||
level: 'silent',
|
||||
send () {
|
||||
fail('no data should be logged by the transmit method')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const levels = Object.keys(pino.levels.values)
|
||||
levels.forEach((level) => {
|
||||
logger[level]('message')
|
||||
})
|
||||
|
||||
is(c, levels.length, 'write must be called exactly once per level')
|
||||
end()
|
||||
})
|
||||
679
node_modules/pino/test/browser.test.js
generated
vendored
Normal file
679
node_modules/pino/test/browser.test.js
generated
vendored
Normal file
@@ -0,0 +1,679 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const fresh = require('import-fresh')
|
||||
const pinoStdSerializers = require('pino-std-serializers')
|
||||
const pino = require('../browser')
|
||||
|
||||
levelTest('fatal')
|
||||
levelTest('error')
|
||||
levelTest('warn')
|
||||
levelTest('info')
|
||||
levelTest('debug')
|
||||
levelTest('trace')
|
||||
|
||||
test('silent level', ({ end, fail, pass }) => {
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: { write: fail }
|
||||
})
|
||||
instance.info('test')
|
||||
const child = instance.child({ test: 'test' })
|
||||
child.info('msg-test')
|
||||
// use setTimeout because setImmediate isn't supported in most browsers
|
||||
setTimeout(() => {
|
||||
pass()
|
||||
end()
|
||||
}, 0)
|
||||
})
|
||||
|
||||
test('enabled false', ({ end, fail, pass }) => {
|
||||
const instance = pino({
|
||||
enabled: false,
|
||||
browser: { write: fail }
|
||||
})
|
||||
instance.info('test')
|
||||
const child = instance.child({ test: 'test' })
|
||||
child.info('msg-test')
|
||||
// use setTimeout because setImmediate isn't supported in most browsers
|
||||
setTimeout(() => {
|
||||
pass()
|
||||
end()
|
||||
}, 0)
|
||||
})
|
||||
|
||||
test('throw if creating child without bindings', ({ end, throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => instance.child())
|
||||
end()
|
||||
})
|
||||
|
||||
test('stubs write, flush and ee methods on instance', ({ end, ok, is }) => {
|
||||
const instance = pino()
|
||||
|
||||
ok(isFunc(instance.setMaxListeners))
|
||||
ok(isFunc(instance.getMaxListeners))
|
||||
ok(isFunc(instance.emit))
|
||||
ok(isFunc(instance.addListener))
|
||||
ok(isFunc(instance.on))
|
||||
ok(isFunc(instance.prependListener))
|
||||
ok(isFunc(instance.once))
|
||||
ok(isFunc(instance.prependOnceListener))
|
||||
ok(isFunc(instance.removeListener))
|
||||
ok(isFunc(instance.removeAllListeners))
|
||||
ok(isFunc(instance.listeners))
|
||||
ok(isFunc(instance.listenerCount))
|
||||
ok(isFunc(instance.eventNames))
|
||||
ok(isFunc(instance.write))
|
||||
ok(isFunc(instance.flush))
|
||||
|
||||
is(instance.on(), undefined)
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes levels object', ({ end, same }) => {
|
||||
same(pino.levels, {
|
||||
values: {
|
||||
fatal: 60,
|
||||
error: 50,
|
||||
warn: 40,
|
||||
info: 30,
|
||||
debug: 20,
|
||||
trace: 10
|
||||
},
|
||||
labels: {
|
||||
10: 'trace',
|
||||
20: 'debug',
|
||||
30: 'info',
|
||||
40: 'warn',
|
||||
50: 'error',
|
||||
60: 'fatal'
|
||||
}
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes faux stdSerializers', ({ end, ok, same }) => {
|
||||
ok(pino.stdSerializers)
|
||||
// make sure faux stdSerializers match pino-std-serializers
|
||||
for (const serializer in pinoStdSerializers) {
|
||||
ok(pino.stdSerializers[serializer], `pino.stdSerializers.${serializer}`)
|
||||
}
|
||||
// confirm faux methods return empty objects
|
||||
same(pino.stdSerializers.req(), {})
|
||||
same(pino.stdSerializers.mapHttpRequest(), {})
|
||||
same(pino.stdSerializers.mapHttpResponse(), {})
|
||||
same(pino.stdSerializers.res(), {})
|
||||
// confirm wrapping function is a passthrough
|
||||
const noChange = { foo: 'bar', fuz: 42 }
|
||||
same(pino.stdSerializers.wrapRequestSerializer(noChange), noChange)
|
||||
same(pino.stdSerializers.wrapResponseSerializer(noChange), noChange)
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes err stdSerializer', ({ end, ok }) => {
|
||||
ok(pino.stdSerializers.err)
|
||||
ok(pino.stdSerializers.err(Error()))
|
||||
end()
|
||||
})
|
||||
|
||||
consoleMethodTest('error')
|
||||
consoleMethodTest('fatal', 'error')
|
||||
consoleMethodTest('warn')
|
||||
consoleMethodTest('info')
|
||||
consoleMethodTest('debug')
|
||||
consoleMethodTest('trace')
|
||||
absentConsoleMethodTest('error', 'log')
|
||||
absentConsoleMethodTest('warn', 'error')
|
||||
absentConsoleMethodTest('info', 'log')
|
||||
absentConsoleMethodTest('debug', 'log')
|
||||
absentConsoleMethodTest('trace', 'log')
|
||||
|
||||
// do not run this with airtap
|
||||
if (process.title !== 'browser') {
|
||||
test('in absence of console, log methods become noops', ({ end, ok }) => {
|
||||
const console = global.console
|
||||
delete global.console
|
||||
const instance = fresh('../browser')()
|
||||
global.console = console
|
||||
ok(fnName(instance.log).match(/noop/))
|
||||
ok(fnName(instance.fatal).match(/noop/))
|
||||
ok(fnName(instance.error).match(/noop/))
|
||||
ok(fnName(instance.warn).match(/noop/))
|
||||
ok(fnName(instance.info).match(/noop/))
|
||||
ok(fnName(instance.debug).match(/noop/))
|
||||
ok(fnName(instance.trace).match(/noop/))
|
||||
end()
|
||||
})
|
||||
}
|
||||
|
||||
test('opts.browser.asObject logs pino-like object to console', ({ end, ok, is }) => {
|
||||
const info = console.info
|
||||
console.info = function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test')
|
||||
ok(o.time)
|
||||
console.info = info
|
||||
}
|
||||
const instance = require('../browser')({
|
||||
browser: {
|
||||
asObject: true
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.asObject uses opts.messageKey in logs', ({ end, ok, is }) => {
|
||||
const messageKey = 'message'
|
||||
const instance = require('../browser')({
|
||||
messageKey,
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o[messageKey], 'test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.asObjectBindingsOnly passes the bindings but keep the message unformatted', ({ end, ok, is, deepEqual }) => {
|
||||
const messageKey = 'message'
|
||||
const instance = require('../browser')({
|
||||
messageKey,
|
||||
browser: {
|
||||
asObjectBindingsOnly: true,
|
||||
write: function (o, msg, ...args) {
|
||||
is(o.level, 30)
|
||||
ok(o.time)
|
||||
is(msg, 'test %s')
|
||||
deepEqual(args, ['foo'])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('test %s', 'foo')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.formatters (level) logs pino-like object to console', ({ end, ok, is }) => {
|
||||
const info = console.info
|
||||
console.info = function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.label, 'info')
|
||||
is(o.msg, 'test')
|
||||
ok(o.time)
|
||||
console.info = info
|
||||
}
|
||||
const instance = require('../browser')({
|
||||
browser: {
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { label, level: number }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.formatters (log) logs pino-like object to console', ({ end, ok, is }) => {
|
||||
const info = console.info
|
||||
console.info = function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test')
|
||||
is(o.hello, 'world')
|
||||
is(o.newField, 'test')
|
||||
ok(o.time, `Logged at ${o.time}`)
|
||||
console.info = info
|
||||
}
|
||||
const instance = require('../browser')({
|
||||
browser: {
|
||||
formatters: {
|
||||
log (o) {
|
||||
return { ...o, newField: 'test', time: `Logged at ${o.time}` }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info({ hello: 'world' }, 'test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.serialize and opts.browser.transmit only serializes log data once', ({ end, ok, is }) => {
|
||||
const instance = require('../browser')({
|
||||
serializers: {
|
||||
extras (data) {
|
||||
return { serializedExtras: data }
|
||||
}
|
||||
},
|
||||
browser: {
|
||||
serialize: ['extras'],
|
||||
transmit: {
|
||||
level: 'info',
|
||||
send (level, o) {
|
||||
is(o.messages[0].extras.serializedExtras, 'world')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info({ extras: 'world' }, 'test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.serialize and opts.asObject only serializes log data once', ({ end, ok, is }) => {
|
||||
const instance = require('../browser')({
|
||||
serializers: {
|
||||
extras (data) {
|
||||
return { serializedExtras: data }
|
||||
}
|
||||
},
|
||||
browser: {
|
||||
serialize: ['extras'],
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.extras.serializedExtras, 'world')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info({ extras: 'world' }, 'test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.serialize, opts.asObject and opts.browser.transmit only serializes log data once', ({ end, ok, is }) => {
|
||||
const instance = require('../browser')({
|
||||
serializers: {
|
||||
extras (data) {
|
||||
return { serializedExtras: data }
|
||||
}
|
||||
},
|
||||
browser: {
|
||||
serialize: ['extras'],
|
||||
asObject: true,
|
||||
transmit: {
|
||||
send (level, o) {
|
||||
is(o.messages[0].extras.serializedExtras, 'world')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info({ extras: 'world' }, 'test')
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func log single string', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func string joining', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test test2 test3')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('test %s %s', 'test2', 'test3')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func string joining when asObject is true', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test test2 test3')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('test %s %s', 'test2', 'test3')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func string object joining', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test {"test":"test2"} {"test":"test3"}')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('test %j %j', { test: 'test2' }, { test: 'test3' })
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func string object joining when asObject is true', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
asObject: true,
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test {"test":"test2"} {"test":"test3"}')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('test %j %j', { test: 'test2' }, { test: 'test3' })
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func string interpolation', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test2 test ({"test":"test3"})')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info('%s test (%j)', 'test2', { test: 'test3' })
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func number', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 1)
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info(1)
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write func log single object', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: function (o) {
|
||||
is(o.level, 30)
|
||||
is(o.test, 'test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.info({ test: 'test' })
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write obj writes to methods corresponding to level', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write: {
|
||||
error: function (o) {
|
||||
is(o.level, 50)
|
||||
is(o.test, 'test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.error({ test: 'test' })
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.asObject/write supports child loggers', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write (o) {
|
||||
is(o.level, 30)
|
||||
is(o.test, 'test')
|
||||
is(o.msg, 'msg-test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
const child = instance.child({ test: 'test' })
|
||||
child.info('msg-test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.asObject/write supports child child loggers', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write (o) {
|
||||
is(o.level, 30)
|
||||
is(o.test, 'test')
|
||||
is(o.foo, 'bar')
|
||||
is(o.msg, 'msg-test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
const child = instance.child({ test: 'test' }).child({ foo: 'bar' })
|
||||
child.info('msg-test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.asObject/write supports child child child loggers', ({ end, ok, is }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write (o) {
|
||||
is(o.level, 30)
|
||||
is(o.test, 'test')
|
||||
is(o.foo, 'bar')
|
||||
is(o.baz, 'bop')
|
||||
is(o.msg, 'msg-test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
})
|
||||
const child = instance.child({ test: 'test' }).child({ foo: 'bar' }).child({ baz: 'bop' })
|
||||
child.info('msg-test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.asObject defensively mitigates naughty numbers', ({ end, pass }) => {
|
||||
const instance = pino({
|
||||
browser: { asObject: true, write: () => {} }
|
||||
})
|
||||
const child = instance.child({ test: 'test' })
|
||||
child._childLevel = -10
|
||||
child.info('test')
|
||||
pass() // if we reached here, there was no infinite loop, so, .. pass.
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('opts.browser.write obj falls back to console where a method is not supplied', ({ end, ok, is }) => {
|
||||
const info = console.info
|
||||
console.info = (o) => {
|
||||
is(o.level, 30)
|
||||
is(o.msg, 'test')
|
||||
ok(o.time)
|
||||
console.info = info
|
||||
}
|
||||
const instance = require('../browser')({
|
||||
browser: {
|
||||
write: {
|
||||
error (o) {
|
||||
is(o.level, 50)
|
||||
is(o.test, 'test')
|
||||
ok(o.time)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
instance.error({ test: 'test' })
|
||||
instance.info('test')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
function levelTest (name) {
|
||||
test(name + ' logs', ({ end, is }) => {
|
||||
const msg = 'hello world'
|
||||
sink(name, (args) => {
|
||||
is(args[0], msg)
|
||||
end()
|
||||
})
|
||||
pino({ level: name })[name](msg)
|
||||
})
|
||||
|
||||
test('passing objects at level ' + name, ({ end, is }) => {
|
||||
const msg = { hello: 'world' }
|
||||
sink(name, (args) => {
|
||||
is(args[0], msg)
|
||||
end()
|
||||
})
|
||||
pino({ level: name })[name](msg)
|
||||
})
|
||||
|
||||
test('passing an object and a string at level ' + name, ({ end, is }) => {
|
||||
const a = { hello: 'world' }
|
||||
const b = 'a string'
|
||||
sink(name, (args) => {
|
||||
is(args[0], a)
|
||||
is(args[1], b)
|
||||
end()
|
||||
})
|
||||
pino({ level: name })[name](a, b)
|
||||
})
|
||||
|
||||
test('formatting logs as ' + name, ({ end, is }) => {
|
||||
sink(name, (args) => {
|
||||
is(args[0], 'hello %d')
|
||||
is(args[1], 42)
|
||||
end()
|
||||
})
|
||||
pino({ level: name })[name]('hello %d', 42)
|
||||
})
|
||||
|
||||
test('passing error at level ' + name, ({ end, is }) => {
|
||||
const err = new Error('myerror')
|
||||
sink(name, (args) => {
|
||||
is(args[0], err)
|
||||
end()
|
||||
})
|
||||
pino({ level: name })[name](err)
|
||||
})
|
||||
|
||||
test('passing error with a serializer at level ' + name, ({ end, is }) => {
|
||||
// in browser - should have no effect (should not crash)
|
||||
const err = new Error('myerror')
|
||||
sink(name, (args) => {
|
||||
is(args[0].err, err)
|
||||
end()
|
||||
})
|
||||
const instance = pino({
|
||||
level: name,
|
||||
serializers: {
|
||||
err: pino.stdSerializers.err
|
||||
}
|
||||
})
|
||||
instance[name]({ err })
|
||||
})
|
||||
|
||||
test('child logger for level ' + name, ({ end, is }) => {
|
||||
const msg = 'hello world'
|
||||
const parent = { hello: 'world' }
|
||||
sink(name, (args) => {
|
||||
is(args[0], parent)
|
||||
is(args[1], msg)
|
||||
end()
|
||||
})
|
||||
const instance = pino({ level: name })
|
||||
const child = instance.child(parent)
|
||||
child[name](msg)
|
||||
})
|
||||
|
||||
test('child-child logger for level ' + name, ({ end, is }) => {
|
||||
const msg = 'hello world'
|
||||
const grandParent = { hello: 'world' }
|
||||
const parent = { hello: 'you' }
|
||||
sink(name, (args) => {
|
||||
is(args[0], grandParent)
|
||||
is(args[1], parent)
|
||||
is(args[2], msg)
|
||||
end()
|
||||
})
|
||||
const instance = pino({ level: name })
|
||||
const child = instance.child(grandParent).child(parent)
|
||||
child[name](msg)
|
||||
})
|
||||
}
|
||||
|
||||
function consoleMethodTest (level, method) {
|
||||
if (!method) method = level
|
||||
test('pino().' + level + ' uses console.' + method, ({ end, is }) => {
|
||||
sink(method, (args) => {
|
||||
is(args[0], 'test')
|
||||
end()
|
||||
})
|
||||
const instance = require('../browser')({ level })
|
||||
instance[level]('test')
|
||||
})
|
||||
}
|
||||
|
||||
function absentConsoleMethodTest (method, fallback) {
|
||||
test('in absence of console.' + method + ', console.' + fallback + ' is used', ({ end, is }) => {
|
||||
const fn = console[method]
|
||||
console[method] = undefined
|
||||
sink(fallback, function (args) {
|
||||
is(args[0], 'test')
|
||||
end()
|
||||
console[method] = fn
|
||||
})
|
||||
const instance = require('../browser')({ level: method })
|
||||
instance[method]('test')
|
||||
})
|
||||
}
|
||||
|
||||
function isFunc (fn) { return typeof fn === 'function' }
|
||||
function fnName (fn) {
|
||||
const rx = /^\s*function\s*([^(]*)/i
|
||||
const match = rx.exec(fn)
|
||||
return match && match[1]
|
||||
}
|
||||
function sink (method, fn) {
|
||||
if (method === 'fatal') method = 'error'
|
||||
const orig = console[method]
|
||||
console[method] = function () {
|
||||
console[method] = orig
|
||||
fn(Array.prototype.slice.call(arguments))
|
||||
}
|
||||
}
|
||||
34
node_modules/pino/test/complex-objects.test.js
generated
vendored
Normal file
34
node_modules/pino/test/complex-objects.test.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const { PassThrough } = require('node:stream')
|
||||
const pino = require('../')
|
||||
|
||||
test('Proxy and stream objects', async ({ equal }) => {
|
||||
const s = new PassThrough()
|
||||
s.resume()
|
||||
s.write('', () => {})
|
||||
const obj = { s, p: new Proxy({}, { get () { throw new Error('kaboom') } }) }
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info({ obj })
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
|
||||
equal(result.obj, '[unable to serialize, circular reference is too complex to analyze]')
|
||||
})
|
||||
|
||||
test('Proxy and stream objects', async ({ equal }) => {
|
||||
const s = new PassThrough()
|
||||
s.resume()
|
||||
s.write('', () => {})
|
||||
const obj = { s, p: new Proxy({}, { get () { throw new Error('kaboom') } }) }
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info(obj)
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
|
||||
equal(result.p, '[unable to serialize, circular reference is too complex to analyze]')
|
||||
})
|
||||
32
node_modules/pino/test/crlf.test.js
generated
vendored
Normal file
32
node_modules/pino/test/crlf.test.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const writer = require('flush-write-stream')
|
||||
const pino = require('../')
|
||||
|
||||
function capture () {
|
||||
const ws = writer((chunk, enc, cb) => {
|
||||
ws.data += chunk.toString()
|
||||
cb()
|
||||
})
|
||||
ws.data = ''
|
||||
return ws
|
||||
}
|
||||
|
||||
test('pino uses LF by default', async ({ ok }) => {
|
||||
const stream = capture()
|
||||
const logger = pino(stream)
|
||||
logger.info('foo')
|
||||
logger.error('bar')
|
||||
ok(/foo[^\r\n]+\n[^\r\n]+bar[^\r\n]+\n/.test(stream.data))
|
||||
})
|
||||
|
||||
test('pino can log CRLF', async ({ ok }) => {
|
||||
const stream = capture()
|
||||
const logger = pino({
|
||||
crlf: true
|
||||
}, stream)
|
||||
logger.info('foo')
|
||||
logger.error('bar')
|
||||
ok(/foo[^\n]+\r\n[^\n]+bar[^\n]+\r\n/.test(stream.data))
|
||||
})
|
||||
253
node_modules/pino/test/custom-levels.test.js
generated
vendored
Normal file
253
node_modules/pino/test/custom-levels.test.js
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: 0 */
|
||||
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
// Silence all warnings for this test
|
||||
process.removeAllListeners('warning')
|
||||
process.on('warning', () => {})
|
||||
|
||||
test('adds additional levels', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
foo: 35,
|
||||
bar: 45
|
||||
}
|
||||
}, stream)
|
||||
|
||||
logger.foo('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 35)
|
||||
})
|
||||
|
||||
test('custom levels does not override default levels', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}, stream)
|
||||
|
||||
logger.info('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 30)
|
||||
})
|
||||
|
||||
test('default levels can be redefined using custom levels', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
info: 35,
|
||||
debug: 45
|
||||
},
|
||||
useOnlyCustomLevels: true
|
||||
}, stream)
|
||||
|
||||
equal(logger.hasOwnProperty('info'), true)
|
||||
|
||||
logger.info('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 35)
|
||||
})
|
||||
|
||||
test('custom levels overrides default level label if use useOnlyCustomLevels', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
},
|
||||
useOnlyCustomLevels: true,
|
||||
level: 'foo'
|
||||
}, stream)
|
||||
|
||||
equal(logger.hasOwnProperty('info'), false)
|
||||
})
|
||||
|
||||
test('custom levels overrides default level value if use useOnlyCustomLevels', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
},
|
||||
useOnlyCustomLevels: true,
|
||||
level: 35
|
||||
}, stream)
|
||||
|
||||
equal(logger.hasOwnProperty('info'), false)
|
||||
})
|
||||
|
||||
test('custom levels are inherited by children', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}, stream)
|
||||
|
||||
logger.child({ childMsg: 'ok' }).foo('test')
|
||||
const { msg, childMsg, level } = await once(stream, 'data')
|
||||
equal(level, 35)
|
||||
equal(childMsg, 'ok')
|
||||
equal(msg, 'test')
|
||||
})
|
||||
|
||||
test('custom levels can be specified on child bindings', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino(stream).child({
|
||||
childMsg: 'ok'
|
||||
}, {
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
})
|
||||
|
||||
logger.foo('test')
|
||||
const { msg, childMsg, level } = await once(stream, 'data')
|
||||
equal(level, 35)
|
||||
equal(childMsg, 'ok')
|
||||
equal(msg, 'test')
|
||||
})
|
||||
|
||||
test('customLevels property child bindings does not get logged', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino(stream).child({
|
||||
childMsg: 'ok'
|
||||
}, {
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
})
|
||||
|
||||
logger.foo('test')
|
||||
const { customLevels } = await once(stream, 'data')
|
||||
equal(customLevels, undefined)
|
||||
})
|
||||
|
||||
test('throws when specifying pre-existing parent labels via child bindings', async ({ throws }) => {
|
||||
const stream = sink()
|
||||
throws(() => pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}, stream).child({}, {
|
||||
customLevels: {
|
||||
foo: 45
|
||||
}
|
||||
}), 'levels cannot be overridden')
|
||||
})
|
||||
|
||||
test('throws when specifying pre-existing parent values via child bindings', async ({ throws }) => {
|
||||
const stream = sink()
|
||||
throws(() => pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}, stream).child({}, {
|
||||
customLevels: {
|
||||
bar: 35
|
||||
}
|
||||
}), 'pre-existing level values cannot be used for new levels')
|
||||
})
|
||||
|
||||
test('throws when specifying core values via child bindings', async ({ throws }) => {
|
||||
const stream = sink()
|
||||
throws(() => pino(stream).child({}, {
|
||||
customLevels: {
|
||||
foo: 30
|
||||
}
|
||||
}), 'pre-existing level values cannot be used for new levels')
|
||||
})
|
||||
|
||||
test('throws when useOnlyCustomLevels is set true without customLevels', async ({ throws }) => {
|
||||
const stream = sink()
|
||||
throws(() => pino({
|
||||
useOnlyCustomLevels: true
|
||||
}, stream), 'customLevels is required if useOnlyCustomLevels is set true')
|
||||
})
|
||||
|
||||
test('custom level on one instance does not affect other instances', async ({ equal }) => {
|
||||
pino({
|
||||
customLevels: {
|
||||
foo: 37
|
||||
}
|
||||
})
|
||||
equal(typeof pino().foo, 'undefined')
|
||||
})
|
||||
|
||||
test('setting level below or at custom level will successfully log', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ customLevels: { foo: 35 } }, stream)
|
||||
instance.level = 'foo'
|
||||
instance.info('nope')
|
||||
instance.foo('bar')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'bar')
|
||||
})
|
||||
|
||||
test('custom level below level threshold will not log', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ customLevels: { foo: 15 } }, stream)
|
||||
instance.level = 'info'
|
||||
instance.info('bar')
|
||||
instance.foo('nope')
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(msg, 'bar')
|
||||
})
|
||||
|
||||
test('does not share custom level state across siblings', async ({ doesNotThrow }) => {
|
||||
const stream = sink()
|
||||
const logger = pino(stream)
|
||||
logger.child({}, {
|
||||
customLevels: { foo: 35 }
|
||||
})
|
||||
doesNotThrow(() => {
|
||||
logger.child({}, {
|
||||
customLevels: { foo: 35 }
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('custom level does not affect the levels serializer', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
foo: 35,
|
||||
bar: 45
|
||||
},
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { priority: number }
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
logger.foo('test')
|
||||
const { priority } = await once(stream, 'data')
|
||||
equal(priority, 35)
|
||||
})
|
||||
|
||||
test('When useOnlyCustomLevels is set to true, the level formatter should only get custom levels', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
customLevels: {
|
||||
answer: 42
|
||||
},
|
||||
useOnlyCustomLevels: true,
|
||||
level: 42,
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
equal(label, 'answer')
|
||||
equal(number, 42)
|
||||
return { level: number }
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
logger.answer('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 42)
|
||||
})
|
||||
107
node_modules/pino/test/diagnostics.test.js
generated
vendored
Normal file
107
node_modules/pino/test/diagnostics.test.js
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
'use strict'
|
||||
|
||||
const test = require('node:test')
|
||||
const os = require('node:os')
|
||||
const diagChan = require('node:diagnostics_channel')
|
||||
const { AsyncLocalStorage } = require('node:async_hooks')
|
||||
const { Writable } = require('node:stream')
|
||||
const tspl = require('@matteo.collina/tspl')
|
||||
const pino = require('../pino')
|
||||
|
||||
const hostname = os.hostname()
|
||||
const { pid } = process
|
||||
const AS_JSON_START = 'tracing:pino_asJson:start'
|
||||
const AS_JSON_END = 'tracing:pino_asJson:end'
|
||||
|
||||
// Skip tests if diagnostics_channel.tracingChannel is not available (Node < 18.19)
|
||||
const skip = typeof diagChan.tracingChannel !== 'function'
|
||||
|
||||
test.beforeEach(ctx => {
|
||||
ctx.pino = {
|
||||
ts: 1757512800000, // 2025-09-10T10:00:00.000-05:00
|
||||
now: Date.now
|
||||
}
|
||||
|
||||
Date.now = () => ctx.pino.ts
|
||||
|
||||
ctx.pino.dest = new Writable({
|
||||
objectMode: true,
|
||||
write (data, enc, cb) {
|
||||
cb()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test.afterEach(ctx => {
|
||||
Date.now = ctx.pino.now
|
||||
})
|
||||
|
||||
test('asJson emits events', { skip }, async (t) => {
|
||||
const plan = tspl(t, { plan: 8 })
|
||||
const { dest } = t.pino
|
||||
const logger = pino({}, dest)
|
||||
const expectedArguments = [
|
||||
{},
|
||||
'testing',
|
||||
30,
|
||||
`,"time":${t.pino.ts}`
|
||||
]
|
||||
|
||||
let startEvent
|
||||
diagChan.subscribe(AS_JSON_START, startHandler)
|
||||
diagChan.subscribe(AS_JSON_END, endHandler)
|
||||
|
||||
logger.info('testing')
|
||||
await plan
|
||||
|
||||
diagChan.unsubscribe(AS_JSON_START, startHandler)
|
||||
diagChan.unsubscribe(AS_JSON_END, endHandler)
|
||||
|
||||
function startHandler (event) {
|
||||
startEvent = event
|
||||
plan.equal(Object.prototype.toString.call(event.instance), '[object Pino]')
|
||||
plan.equal(event.instance === logger, true)
|
||||
plan.deepStrictEqual(Array.from(event.arguments ?? []), expectedArguments)
|
||||
}
|
||||
|
||||
function endHandler (event) {
|
||||
plan.equal(Object.prototype.toString.call(event.instance), '[object Pino]')
|
||||
plan.equal(event.instance === logger, true)
|
||||
plan.deepStrictEqual(Array.from(event.arguments ?? []), expectedArguments)
|
||||
plan.equal(
|
||||
event.result,
|
||||
`{"level":30,"time":${t.pino.ts},"pid":${pid},"hostname":"${hostname}","msg":"testing"}\n`
|
||||
)
|
||||
|
||||
plan.equal(event.arguments === startEvent.arguments, true, 'same event object is supplied to both events')
|
||||
}
|
||||
})
|
||||
|
||||
test('asJson context is not lost', { skip }, async (t) => {
|
||||
const plan = tspl(t, { plan: 2 })
|
||||
const { dest } = t.pino
|
||||
const logger = pino({}, dest)
|
||||
const asyncLocalStorage = new AsyncLocalStorage()
|
||||
const localStore = { foo: 'bar' }
|
||||
|
||||
diagChan.subscribe(AS_JSON_START, startHandler)
|
||||
diagChan.subscribe(AS_JSON_END, endHandler)
|
||||
|
||||
asyncLocalStorage.run(localStore, () => {
|
||||
logger.info('testing')
|
||||
})
|
||||
await plan
|
||||
|
||||
diagChan.unsubscribe(AS_JSON_START, startHandler)
|
||||
diagChan.unsubscribe(AS_JSON_END, endHandler)
|
||||
|
||||
function startHandler () {
|
||||
const store = asyncLocalStorage.getStore()
|
||||
plan.equal(store === localStore, true)
|
||||
}
|
||||
|
||||
function endHandler () {
|
||||
const store = asyncLocalStorage.getStore()
|
||||
plan.equal(store === localStore, true)
|
||||
}
|
||||
})
|
||||
398
node_modules/pino/test/error.test.js
generated
vendored
Normal file
398
node_modules/pino/test/error.test.js
generated
vendored
Normal file
@@ -0,0 +1,398 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: 0 */
|
||||
|
||||
const os = require('node:os')
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
const level = 50
|
||||
const name = 'error'
|
||||
|
||||
test('err is serialized with additional properties set on the Error object', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const err = Object.assign(new Error('myerror'), { foo: 'bar' })
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name](err)
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
foo: err.foo
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('type should be detected based on constructor', async ({ ok, same }) => {
|
||||
class Bar extends Error {}
|
||||
const stream = sink()
|
||||
const err = new Bar('myerror')
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name](err)
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
err: {
|
||||
type: 'Bar',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('type, message and stack should be first level properties', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const err = Object.assign(new Error('foo'), { foo: 'bar' })
|
||||
const instance = pino(stream)
|
||||
instance.level = name
|
||||
instance[name](err)
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
foo: err.foo
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('err serializer', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const err = Object.assign(new Error('myerror'), { foo: 'bar' })
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
err: pino.stdSerializers.err
|
||||
}
|
||||
}, stream)
|
||||
|
||||
instance.level = name
|
||||
instance[name]({ err })
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
foo: err.foo
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('an error with statusCode property is not confused for a http response', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const err = Object.assign(new Error('StatusCodeErr'), { statusCode: 500 })
|
||||
const instance = pino(stream)
|
||||
|
||||
instance.level = name
|
||||
instance[name](err)
|
||||
const result = await once(stream, 'data')
|
||||
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
statusCode: err.statusCode
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('stack is omitted if it is not set on err', t => {
|
||||
t.plan(2)
|
||||
const err = new Error('myerror')
|
||||
delete err.stack
|
||||
const instance = pino(sink(function (chunk, enc, cb) {
|
||||
t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
t.equal(chunk.hasOwnProperty('stack'), false)
|
||||
cb()
|
||||
}))
|
||||
|
||||
instance.level = name
|
||||
instance[name](err)
|
||||
})
|
||||
|
||||
test('correctly ignores toString on errors', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
err.toString = () => undefined
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
test: 'this'
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('assign mixin()', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin () {
|
||||
return { hello: 'world' }
|
||||
}
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
hello: 'world',
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('no err serializer', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
serializers: {}
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('empty serializer', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
err () {}
|
||||
}
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('assign mixin()', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin () {
|
||||
return { hello: 'world' }
|
||||
}
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
hello: 'world',
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('no err serializer', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
serializers: {}
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
err: {
|
||||
type: 'Error',
|
||||
message: err.message,
|
||||
stack: err.stack
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('empty serializer', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
err () {}
|
||||
}
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('correctly adds error information when nestedKey is used', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
err.toString = () => undefined
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
test: 'this',
|
||||
nestedKey: 'obj'
|
||||
}, stream)
|
||||
instance.fatal(err)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
obj: {
|
||||
err: {
|
||||
type: 'Error',
|
||||
stack: err.stack,
|
||||
message: err.message
|
||||
}
|
||||
},
|
||||
msg: err.message
|
||||
})
|
||||
})
|
||||
|
||||
test('correctly adds msg on error when nestedKey is used', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
err.toString = () => undefined
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
test: 'this',
|
||||
nestedKey: 'obj'
|
||||
}, stream)
|
||||
instance.fatal(err, 'msg message')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
obj: {
|
||||
err: {
|
||||
type: 'Error',
|
||||
stack: err.stack,
|
||||
message: err.message
|
||||
}
|
||||
},
|
||||
msg: 'msg message'
|
||||
})
|
||||
})
|
||||
|
||||
test('msg should take precedence over error message on mergingObject', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.error({ msg: 'my message', err })
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 50,
|
||||
err: {
|
||||
type: 'Error',
|
||||
stack: err.stack,
|
||||
message: err.message
|
||||
},
|
||||
msg: 'my message'
|
||||
})
|
||||
})
|
||||
|
||||
test('considers messageKey when giving msg precedence over error', async ({ same }) => {
|
||||
const err = new Error('myerror')
|
||||
const stream = sink()
|
||||
const instance = pino({ messageKey: 'message' }, stream)
|
||||
instance.error({ message: 'my message', err })
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 50,
|
||||
err: {
|
||||
type: 'Error',
|
||||
stack: err.stack,
|
||||
message: err.message
|
||||
},
|
||||
message: 'my message'
|
||||
})
|
||||
})
|
||||
34
node_modules/pino/test/errorKey.test.js
generated
vendored
Normal file
34
node_modules/pino/test/errorKey.test.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const stdSerializers = require('pino-std-serializers')
|
||||
const pino = require('../')
|
||||
|
||||
test('set the errorKey with error serializer', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const errorKey = 'error'
|
||||
const instance = pino({
|
||||
errorKey,
|
||||
serializers: { [errorKey]: stdSerializers.err }
|
||||
}, stream)
|
||||
instance.error(new ReferenceError('test'))
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o[errorKey], 'object')
|
||||
equal(o[errorKey].type, 'ReferenceError')
|
||||
equal(o[errorKey].message, 'test')
|
||||
equal(typeof o[errorKey].stack, 'string')
|
||||
})
|
||||
|
||||
test('set the errorKey without error serializer', async ({ equal, same }) => {
|
||||
const stream = sink()
|
||||
const errorKey = 'error'
|
||||
const instance = pino({
|
||||
errorKey
|
||||
}, stream)
|
||||
instance.error(new ReferenceError('test'))
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o[errorKey], 'object')
|
||||
equal(o[errorKey].type, 'ReferenceError')
|
||||
equal(o[errorKey].message, 'test')
|
||||
equal(typeof o[errorKey].stack, 'string')
|
||||
})
|
||||
91
node_modules/pino/test/escaping.test.js
generated
vendored
Normal file
91
node_modules/pino/test/escaping.test.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
const os = require('node:os')
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
function testEscape (ch, key) {
|
||||
test('correctly escape ' + ch, async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
instance.fatal('this contains ' + key)
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: 'this contains ' + key
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
testEscape('\\n', '\n')
|
||||
testEscape('\\/', '/')
|
||||
testEscape('\\\\', '\\')
|
||||
testEscape('\\r', '\r')
|
||||
testEscape('\\t', '\t')
|
||||
testEscape('\\b', '\b')
|
||||
|
||||
const toEscape = [
|
||||
'\u0000', // NUL Null character
|
||||
'\u0001', // SOH Start of Heading
|
||||
'\u0002', // STX Start of Text
|
||||
'\u0003', // ETX End-of-text character
|
||||
'\u0004', // EOT End-of-transmission character
|
||||
'\u0005', // ENQ Enquiry character
|
||||
'\u0006', // ACK Acknowledge character
|
||||
'\u0007', // BEL Bell character
|
||||
'\u0008', // BS Backspace
|
||||
'\u0009', // HT Horizontal tab
|
||||
'\u000A', // LF Line feed
|
||||
'\u000B', // VT Vertical tab
|
||||
'\u000C', // FF Form feed
|
||||
'\u000D', // CR Carriage return
|
||||
'\u000E', // SO Shift Out
|
||||
'\u000F', // SI Shift In
|
||||
'\u0010', // DLE Data Link Escape
|
||||
'\u0011', // DC1 Device Control 1
|
||||
'\u0012', // DC2 Device Control 2
|
||||
'\u0013', // DC3 Device Control 3
|
||||
'\u0014', // DC4 Device Control 4
|
||||
'\u0015', // NAK Negative-acknowledge character
|
||||
'\u0016', // SYN Synchronous Idle
|
||||
'\u0017', // ETB End of Transmission Block
|
||||
'\u0018', // CAN Cancel character
|
||||
'\u0019', // EM End of Medium
|
||||
'\u001A', // SUB Substitute character
|
||||
'\u001B', // ESC Escape character
|
||||
'\u001C', // FS File Separator
|
||||
'\u001D', // GS Group Separator
|
||||
'\u001E', // RS Record Separator
|
||||
'\u001F' // US Unit Separator
|
||||
]
|
||||
|
||||
toEscape.forEach((key) => {
|
||||
testEscape(JSON.stringify(key), key)
|
||||
})
|
||||
|
||||
test('correctly escape `hello \\u001F world \\n \\u0022`', async ({ same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
name: 'hello'
|
||||
}, stream)
|
||||
instance.fatal('hello \u001F world \n \u0022')
|
||||
const result = await once(stream, 'data')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 60,
|
||||
name: 'hello',
|
||||
msg: 'hello \u001F world \n \u0022'
|
||||
})
|
||||
})
|
||||
12
node_modules/pino/test/esm/esm.mjs
generated
vendored
Normal file
12
node_modules/pino/test/esm/esm.mjs
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import t from 'tap'
|
||||
import pino from '../../pino.js'
|
||||
import helper from '../helper.js'
|
||||
|
||||
const { sink, check, once } = helper
|
||||
|
||||
t.test('esm support', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info('hello world')
|
||||
check(equal, await once(stream, 'data'), 30, 'hello world')
|
||||
})
|
||||
34
node_modules/pino/test/esm/index.test.js
generated
vendored
Normal file
34
node_modules/pino/test/esm/index.test.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
const t = require('tap')
|
||||
const semver = require('semver')
|
||||
|
||||
const { isYarnPnp } = require('../helper')
|
||||
|
||||
if (!semver.satisfies(process.versions.node, '^13.3.0 || ^12.10.0 || >= 14.0.0') || isYarnPnp) {
|
||||
t.skip('Skip esm because not supported by Node')
|
||||
} else {
|
||||
// Node v8 throw a `SyntaxError: Unexpected token import`
|
||||
// even if this branch is never touch in the code,
|
||||
// by using `eval` we can avoid this issue.
|
||||
// eslint-disable-next-line
|
||||
new Function('module', 'return import(module)')('./esm.mjs').catch((err) => {
|
||||
process.nextTick(() => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (!semver.satisfies(process.versions.node, '>= 14.13.0 || ^12.20.0') || isYarnPnp) {
|
||||
t.skip('Skip named exports because not supported by Node')
|
||||
} else {
|
||||
// Node v8 throw a `SyntaxError: Unexpected token import`
|
||||
// even if this branch is never touch in the code,
|
||||
// by using `eval` we can avoid this issue.
|
||||
// eslint-disable-next-line
|
||||
new Function('module', 'return import(module)')('./named-exports.mjs').catch((err) => {
|
||||
process.nextTick(() => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
27
node_modules/pino/test/esm/named-exports.mjs
generated
vendored
Normal file
27
node_modules/pino/test/esm/named-exports.mjs
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { hostname } from 'node:os'
|
||||
import t from 'tap'
|
||||
import { sink, check, once, watchFileCreated, file } from '../helper.js'
|
||||
import { pino, destination } from '../../pino.js'
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
||||
t.test('named exports support', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info('hello world')
|
||||
check(equal, await once(stream, 'data'), 30, 'hello world')
|
||||
})
|
||||
|
||||
t.test('destination', async ({ same }) => {
|
||||
const tmp = file()
|
||||
const instance = pino(destination(tmp))
|
||||
instance.info('hello')
|
||||
await watchFileCreated(tmp)
|
||||
const result = JSON.parse(readFileSync(tmp).toString())
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid: process.pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
})
|
||||
77
node_modules/pino/test/exit.test.js
generated
vendored
Normal file
77
node_modules/pino/test/exit.test.js
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { join } = require('node:path')
|
||||
const execa = require('execa')
|
||||
const writer = require('flush-write-stream')
|
||||
const { once } = require('./helper')
|
||||
|
||||
// https://github.com/pinojs/pino/issues/542
|
||||
test('pino.destination log everything when calling process.exit(0)', async ({ not }) => {
|
||||
let actual = ''
|
||||
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'destination-exit.js')])
|
||||
|
||||
child.stdout.pipe(writer((s, enc, cb) => {
|
||||
actual += s
|
||||
cb()
|
||||
}))
|
||||
|
||||
await once(child, 'close')
|
||||
|
||||
not(actual.match(/hello/), null)
|
||||
not(actual.match(/world/), null)
|
||||
})
|
||||
|
||||
test('pino with no args log everything when calling process.exit(0)', async ({ not }) => {
|
||||
let actual = ''
|
||||
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'default-exit.js')])
|
||||
|
||||
child.stdout.pipe(writer((s, enc, cb) => {
|
||||
actual += s
|
||||
cb()
|
||||
}))
|
||||
|
||||
await once(child, 'close')
|
||||
|
||||
not(actual.match(/hello/), null)
|
||||
not(actual.match(/world/), null)
|
||||
})
|
||||
|
||||
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')])
|
||||
|
||||
child.stdout.pipe(writer((s, enc, cb) => {
|
||||
actual += s
|
||||
cb()
|
||||
}))
|
||||
|
||||
await once(child, 'close')
|
||||
|
||||
not(actual.match(/hello/), null)
|
||||
not(actual.match(/world/), null)
|
||||
})
|
||||
|
||||
test('sync false logs everything when calling flushSync', async ({ not }) => {
|
||||
let actual = ''
|
||||
const child = execa(process.argv[0], [join(__dirname, 'fixtures', 'syncfalse-flush-exit.js')])
|
||||
|
||||
child.stdout.pipe(writer((s, enc, cb) => {
|
||||
actual += s
|
||||
cb()
|
||||
}))
|
||||
|
||||
await once(child, 'close')
|
||||
|
||||
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)
|
||||
})
|
||||
9
node_modules/pino/test/fixtures/broken-pipe/basic.js
generated
vendored
Normal file
9
node_modules/pino/test/fixtures/broken-pipe/basic.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
|
||||
const pino = require('../../..')()
|
||||
|
||||
pino.info('hello world')
|
||||
10
node_modules/pino/test/fixtures/broken-pipe/destination.js
generated
vendored
Normal file
10
node_modules/pino/test/fixtures/broken-pipe/destination.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
|
||||
const pino = require('../../..')
|
||||
const logger = pino(pino.destination())
|
||||
|
||||
logger.info('hello world')
|
||||
12
node_modules/pino/test/fixtures/broken-pipe/syncfalse.js
generated
vendored
Normal file
12
node_modules/pino/test/fixtures/broken-pipe/syncfalse.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict'
|
||||
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
|
||||
const pino = require('../../..')
|
||||
const logger = pino(pino.destination({ sync: false }))
|
||||
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
logger.info('hello world')
|
||||
}
|
||||
13
node_modules/pino/test/fixtures/console-transport.js
generated
vendored
Normal file
13
node_modules/pino/test/fixtures/console-transport.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
const { Writable } = require('node:stream')
|
||||
|
||||
module.exports = (options) => {
|
||||
const myTransportStream = new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
// apply a transform and send to stdout
|
||||
console.log(chunk.toString().toUpperCase())
|
||||
cb()
|
||||
}
|
||||
})
|
||||
return myTransportStream
|
||||
}
|
||||
13
node_modules/pino/test/fixtures/crashing-transport.js
generated
vendored
Normal file
13
node_modules/pino/test/fixtures/crashing-transport.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
const { Writable } = require('node:stream')
|
||||
|
||||
module.exports = () =>
|
||||
new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
setImmediate(() => {
|
||||
/* eslint-disable no-empty */
|
||||
for (let i = 0; i < 1e3; i++) {}
|
||||
process.exit(0)
|
||||
})
|
||||
}
|
||||
})
|
||||
8
node_modules/pino/test/fixtures/default-exit.js
generated
vendored
Normal file
8
node_modules/pino/test/fixtures/default-exit.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const logger = pino()
|
||||
logger.info('hello')
|
||||
logger.info('world')
|
||||
process.exit(0)
|
||||
8
node_modules/pino/test/fixtures/destination-exit.js
generated
vendored
Normal file
8
node_modules/pino/test/fixtures/destination-exit.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const logger = pino({}, pino.destination(1))
|
||||
logger.info('hello')
|
||||
logger.info('world')
|
||||
process.exit(0)
|
||||
13
node_modules/pino/test/fixtures/eval/index.js
generated
vendored
Normal file
13
node_modules/pino/test/fixtures/eval/index.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* eslint-disable no-eval */
|
||||
|
||||
eval(`
|
||||
const pino = require('../../../')
|
||||
|
||||
const logger = pino(
|
||||
pino.transport({
|
||||
target: 'pino/file'
|
||||
})
|
||||
)
|
||||
|
||||
logger.info('done!')
|
||||
`)
|
||||
3
node_modules/pino/test/fixtures/eval/node_modules/14-files.js
generated
vendored
Normal file
3
node_modules/pino/test/fixtures/eval/node_modules/14-files.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
const file1 = require("./file1.js")
|
||||
|
||||
file1()
|
||||
3
node_modules/pino/test/fixtures/eval/node_modules/2-files.js
generated
vendored
Normal file
3
node_modules/pino/test/fixtures/eval/node_modules/2-files.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
const file12 = require("./file12.js")
|
||||
|
||||
file12()
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file1.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file1.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file2 = require("./file2.js")
|
||||
|
||||
module.exports = function () {
|
||||
file2()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file10.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file10.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file11 = require("./file11.js")
|
||||
|
||||
module.exports = function () {
|
||||
file11()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file11.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file11.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file12 = require("./file12.js")
|
||||
|
||||
module.exports = function () {
|
||||
file12()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file12.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file12.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file13 = require("./file13.js")
|
||||
|
||||
module.exports = function () {
|
||||
file13()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file13.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file13.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file14 = require("./file14.js")
|
||||
|
||||
module.exports = function () {
|
||||
file14()
|
||||
}
|
||||
11
node_modules/pino/test/fixtures/eval/node_modules/file14.js
generated
vendored
Normal file
11
node_modules/pino/test/fixtures/eval/node_modules/file14.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
const pino = require("../../../../");
|
||||
|
||||
module.exports = function() {
|
||||
const logger = pino(
|
||||
pino.transport({
|
||||
target: 'pino/file'
|
||||
})
|
||||
)
|
||||
|
||||
logger.info('done!')
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file2.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file2.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file3 = require("./file3.js")
|
||||
|
||||
module.exports = function () {
|
||||
file3()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file3.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file3.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file4 = require("./file4.js")
|
||||
|
||||
module.exports = function () {
|
||||
file4()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file4.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file4.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file5 = require("./file5.js")
|
||||
|
||||
module.exports = function () {
|
||||
file5()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file5.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file5.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file6 = require("./file6.js")
|
||||
|
||||
module.exports = function () {
|
||||
file6()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file6.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file6.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file7 = require("./file7.js")
|
||||
|
||||
module.exports = function () {
|
||||
file7()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file7.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file7.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file8 = require("./file8.js")
|
||||
|
||||
module.exports = function () {
|
||||
file8()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file8.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file8.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file9 = require("./file9.js")
|
||||
|
||||
module.exports = function () {
|
||||
file9()
|
||||
}
|
||||
5
node_modules/pino/test/fixtures/eval/node_modules/file9.js
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/eval/node_modules/file9.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const file10 = require("./file10.js")
|
||||
|
||||
module.exports = function () {
|
||||
file10()
|
||||
}
|
||||
10
node_modules/pino/test/fixtures/noop-transport.js
generated
vendored
Normal file
10
node_modules/pino/test/fixtures/noop-transport.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const { Writable } = require('node:stream')
|
||||
|
||||
module.exports = () => {
|
||||
return new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
cb()
|
||||
}
|
||||
})
|
||||
}
|
||||
8
node_modules/pino/test/fixtures/pretty/null-prototype.js
generated
vendored
Normal file
8
node_modules/pino/test/fixtures/pretty/null-prototype.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../../'))
|
||||
const log = pino({ prettyPrint: true })
|
||||
const obj = Object.create(null)
|
||||
Object.assign(obj, { foo: 'bar' })
|
||||
log.info(obj, 'hello')
|
||||
11
node_modules/pino/test/fixtures/stdout-hack-protection.js
generated
vendored
Normal file
11
node_modules/pino/test/fixtures/stdout-hack-protection.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
|
||||
const write = process.stdout.write.bind(process.stdout)
|
||||
process.stdout.write = function (chunk) {
|
||||
write('hack ' + chunk)
|
||||
}
|
||||
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('../../'))()
|
||||
pino.info('me')
|
||||
6
node_modules/pino/test/fixtures/syncfalse-child.js
generated
vendored
Normal file
6
node_modules/pino/test/fixtures/syncfalse-child.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const asyncLogger = pino(pino.destination({ sync: false })).child({ hello: 'world' })
|
||||
asyncLogger.info('h')
|
||||
9
node_modules/pino/test/fixtures/syncfalse-exit.js
generated
vendored
Normal file
9
node_modules/pino/test/fixtures/syncfalse-exit.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const dest = pino.destination({ dest: 1, minLength: 4096, sync: false })
|
||||
const logger = pino({}, dest)
|
||||
logger.info('hello')
|
||||
logger.info('world')
|
||||
process.exit(0)
|
||||
10
node_modules/pino/test/fixtures/syncfalse-flush-exit.js
generated
vendored
Normal file
10
node_modules/pino/test/fixtures/syncfalse-flush-exit.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const dest = pino.destination({ dest: 1, minLength: 4096, sync: false })
|
||||
const logger = pino({}, dest)
|
||||
logger.info('hello')
|
||||
logger.info('world')
|
||||
dest.flushSync()
|
||||
process.exit(0)
|
||||
6
node_modules/pino/test/fixtures/syncfalse.js
generated
vendored
Normal file
6
node_modules/pino/test/fixtures/syncfalse.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const asyncLogger = pino(pino.destination({ minLength: 4096, sync: false }))
|
||||
asyncLogger.info('h')
|
||||
2
node_modules/pino/test/fixtures/syntax-error-esm.mjs
generated
vendored
Normal file
2
node_modules/pino/test/fixtures/syntax-error-esm.mjs
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// This is a syntax error
|
||||
import
|
||||
20
node_modules/pino/test/fixtures/to-file-transport-with-transform.js
generated
vendored
Normal file
20
node_modules/pino/test/fixtures/to-file-transport-with-transform.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const { once } = require('node:events')
|
||||
const { Transform } = require('node:stream')
|
||||
|
||||
async function run (opts) {
|
||||
if (!opts.destination) throw new Error('kaboom')
|
||||
const stream = fs.createWriteStream(opts.destination)
|
||||
await once(stream, 'open')
|
||||
const t = new Transform({
|
||||
transform (chunk, enc, cb) {
|
||||
setImmediate(cb, null, chunk.toString().toUpperCase())
|
||||
}
|
||||
})
|
||||
t.pipe(stream)
|
||||
return t
|
||||
}
|
||||
|
||||
module.exports = run
|
||||
13
node_modules/pino/test/fixtures/to-file-transport.js
generated
vendored
Normal file
13
node_modules/pino/test/fixtures/to-file-transport.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const { once } = require('node:events')
|
||||
|
||||
async function run (opts) {
|
||||
if (!opts.destination) throw new Error('kaboom')
|
||||
const stream = fs.createWriteStream(opts.destination)
|
||||
await once(stream, 'open')
|
||||
return stream
|
||||
}
|
||||
|
||||
module.exports = run
|
||||
8
node_modules/pino/test/fixtures/to-file-transport.mjs
generated
vendored
Normal file
8
node_modules/pino/test/fixtures/to-file-transport.mjs
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { createWriteStream } from 'node:fs'
|
||||
import { once } from 'node:events'
|
||||
|
||||
export default async function run (opts) {
|
||||
const stream = createWriteStream(opts.destination)
|
||||
await once(stream, 'open')
|
||||
return stream
|
||||
}
|
||||
16
node_modules/pino/test/fixtures/transport-exit-immediately-with-async-dest.js
generated
vendored
Normal file
16
node_modules/pino/test/fixtures/transport-exit-immediately-with-async-dest.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict'
|
||||
|
||||
const pino = require('../..')
|
||||
const transport = pino.transport({
|
||||
target: './to-file-transport-with-transform.js',
|
||||
options: {
|
||||
destination: process.argv[2]
|
||||
}
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
logger.info('Hello')
|
||||
|
||||
logger.info('World')
|
||||
|
||||
process.exit(0)
|
||||
11
node_modules/pino/test/fixtures/transport-exit-immediately.js
generated
vendored
Normal file
11
node_modules/pino/test/fixtures/transport-exit-immediately.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict'
|
||||
|
||||
const pino = require('../..')
|
||||
const transport = pino.transport({
|
||||
target: 'pino/file'
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
logger.info('Hello')
|
||||
|
||||
process.exit(0)
|
||||
12
node_modules/pino/test/fixtures/transport-exit-on-ready.js
generated
vendored
Normal file
12
node_modules/pino/test/fixtures/transport-exit-on-ready.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict'
|
||||
|
||||
const pino = require('../..')
|
||||
const transport = pino.transport({
|
||||
target: 'pino/file'
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
transport.on('ready', function () {
|
||||
logger.info('Hello')
|
||||
process.exit(0)
|
||||
})
|
||||
9
node_modules/pino/test/fixtures/transport-main.js
generated
vendored
Normal file
9
node_modules/pino/test/fixtures/transport-main.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
const { join } = require('node:path')
|
||||
const pino = require('../..')
|
||||
const transport = pino.transport({
|
||||
target: join(__dirname, 'transport-worker.js')
|
||||
})
|
||||
const logger = pino(transport)
|
||||
logger.info('Hello')
|
||||
29
node_modules/pino/test/fixtures/transport-many-lines.js
generated
vendored
Normal file
29
node_modules/pino/test/fixtures/transport-many-lines.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
|
||||
const pino = require('../..')
|
||||
const transport = pino.transport({
|
||||
targets: [{
|
||||
level: 'info',
|
||||
target: 'pino/file',
|
||||
options: {
|
||||
destination: process.argv[2]
|
||||
}
|
||||
}]
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
const toWrite = 1000000
|
||||
transport.on('ready', run)
|
||||
|
||||
let total = 0
|
||||
|
||||
function run () {
|
||||
if (total++ === 8) {
|
||||
return
|
||||
}
|
||||
|
||||
for (let i = 0; i < toWrite; i++) {
|
||||
logger.info(`hello ${i}`)
|
||||
}
|
||||
transport.once('drain', run)
|
||||
}
|
||||
9
node_modules/pino/test/fixtures/transport-string-stdout.js
generated
vendored
Normal file
9
node_modules/pino/test/fixtures/transport-string-stdout.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
const pino = require('../..')
|
||||
const transport = pino.transport({
|
||||
target: 'pino/file',
|
||||
options: { destination: '1' }
|
||||
})
|
||||
const logger = pino(transport)
|
||||
logger.info('Hello')
|
||||
21
node_modules/pino/test/fixtures/transport-transform.js
generated
vendored
Normal file
21
node_modules/pino/test/fixtures/transport-transform.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict'
|
||||
|
||||
const build = require('pino-abstract-transport')
|
||||
const { pipeline, Transform } = require('node:stream')
|
||||
module.exports = (options) => {
|
||||
return build(function (source) {
|
||||
const myTransportStream = new Transform({
|
||||
autoDestroy: true,
|
||||
objectMode: true,
|
||||
transform (chunk, enc, cb) {
|
||||
chunk.service = 'pino'
|
||||
this.push(JSON.stringify(chunk))
|
||||
cb()
|
||||
}
|
||||
})
|
||||
pipeline(source, myTransportStream, () => {})
|
||||
return myTransportStream
|
||||
}, {
|
||||
enablePipelining: true
|
||||
})
|
||||
}
|
||||
33
node_modules/pino/test/fixtures/transport-uses-pino-config.js
generated
vendored
Normal file
33
node_modules/pino/test/fixtures/transport-uses-pino-config.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict'
|
||||
|
||||
const build = require('pino-abstract-transport')
|
||||
const { pipeline, Transform } = require('node:stream')
|
||||
module.exports = () => {
|
||||
return build(function (source) {
|
||||
const myTransportStream = new Transform({
|
||||
autoDestroy: true,
|
||||
objectMode: true,
|
||||
transform (chunk, enc, cb) {
|
||||
const {
|
||||
time,
|
||||
level,
|
||||
[source.messageKey]: body,
|
||||
[source.errorKey]: error,
|
||||
...attributes
|
||||
} = chunk
|
||||
this.push(JSON.stringify({
|
||||
severityText: source.levels.labels[level],
|
||||
body,
|
||||
attributes,
|
||||
...(error && { error })
|
||||
}))
|
||||
cb()
|
||||
}
|
||||
})
|
||||
pipeline(source, myTransportStream, () => {})
|
||||
return myTransportStream
|
||||
}, {
|
||||
enablePipelining: true,
|
||||
expectPinoConfig: true
|
||||
})
|
||||
}
|
||||
12
node_modules/pino/test/fixtures/transport-with-on-exit.js
generated
vendored
Normal file
12
node_modules/pino/test/fixtures/transport-with-on-exit.js
generated
vendored
Normal file
@@ -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')
|
||||
})
|
||||
19
node_modules/pino/test/fixtures/transport-worker-data.js
generated
vendored
Normal file
19
node_modules/pino/test/fixtures/transport-worker-data.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict'
|
||||
|
||||
const { parentPort, workerData } = require('worker_threads')
|
||||
const { Writable } = require('node:stream')
|
||||
|
||||
module.exports = (options) => {
|
||||
const myTransportStream = new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
parentPort.postMessage({
|
||||
code: 'EVENT',
|
||||
name: 'workerData',
|
||||
args: [workerData]
|
||||
})
|
||||
cb()
|
||||
}
|
||||
})
|
||||
return myTransportStream
|
||||
}
|
||||
15
node_modules/pino/test/fixtures/transport-worker.js
generated
vendored
Normal file
15
node_modules/pino/test/fixtures/transport-worker.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict'
|
||||
|
||||
const { Writable } = require('node:stream')
|
||||
const fs = require('node:fs')
|
||||
module.exports = (options) => {
|
||||
const myTransportStream = new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
// Bypass console.log() to avoid flakiness
|
||||
fs.writeSync(1, chunk.toString())
|
||||
cb()
|
||||
}
|
||||
})
|
||||
return myTransportStream
|
||||
}
|
||||
3
node_modules/pino/test/fixtures/transport-wrong-export-type.js
generated
vendored
Normal file
3
node_modules/pino/test/fixtures/transport-wrong-export-type.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
completelyUnrelatedProperty: 'Just a very incorrect transport worker implementation'
|
||||
}
|
||||
12
node_modules/pino/test/fixtures/transport/index.js
generated
vendored
Normal file
12
node_modules/pino/test/fixtures/transport/index.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const { once } = require('node:events')
|
||||
|
||||
async function run (opts) {
|
||||
const stream = fs.createWriteStream(opts.destination)
|
||||
await once(stream, 'open')
|
||||
return stream
|
||||
}
|
||||
|
||||
module.exports = run
|
||||
5
node_modules/pino/test/fixtures/transport/package.json
generated
vendored
Normal file
5
node_modules/pino/test/fixtures/transport/package.json
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "transport",
|
||||
"version": "0.0.1",
|
||||
"main": "./index.js"
|
||||
}
|
||||
18
node_modules/pino/test/fixtures/ts/to-file-transport-with-transform.ts
generated
vendored
Normal file
18
node_modules/pino/test/fixtures/ts/to-file-transport-with-transform.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import * as fs from 'node:fs'
|
||||
import { once } from 'node:events'
|
||||
import { Transform } from 'node:stream'
|
||||
|
||||
async function run (opts: { destination?: fs.PathLike }): Promise<Transform> {
|
||||
if (!opts.destination) throw new Error('kaboom')
|
||||
const stream = fs.createWriteStream(opts.destination)
|
||||
await once(stream, 'open')
|
||||
const t = new Transform({
|
||||
transform (chunk, enc, cb) {
|
||||
setImmediate(cb, null, chunk.toString().toUpperCase())
|
||||
}
|
||||
})
|
||||
t.pipe(stream)
|
||||
return t
|
||||
}
|
||||
|
||||
export default run
|
||||
11
node_modules/pino/test/fixtures/ts/to-file-transport.ts
generated
vendored
Normal file
11
node_modules/pino/test/fixtures/ts/to-file-transport.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import * as fs from 'node:fs'
|
||||
import { once } from 'node:events'
|
||||
|
||||
async function run (opts: { destination?: fs.PathLike }): Promise<fs.WriteStream> {
|
||||
if (!opts.destination) throw new Error('kaboom')
|
||||
const stream = fs.createWriteStream(opts.destination, { encoding: 'utf8' })
|
||||
await once(stream, 'open')
|
||||
return stream
|
||||
}
|
||||
|
||||
export default run
|
||||
36
node_modules/pino/test/fixtures/ts/transpile.cjs
generated
vendored
Executable file
36
node_modules/pino/test/fixtures/ts/transpile.cjs
generated
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const execa = require('execa')
|
||||
const fs = require('node:fs')
|
||||
|
||||
const existsSync = fs.existsSync
|
||||
const stat = fs.promises.stat
|
||||
|
||||
// Hardcoded parameters
|
||||
const esVersions = ['es5', 'es6', 'es2017', 'esnext']
|
||||
const filesToTranspile = ['to-file-transport.ts']
|
||||
|
||||
async function transpile () {
|
||||
process.chdir(__dirname)
|
||||
|
||||
for (const sourceFileName of filesToTranspile) {
|
||||
const sourceStat = await stat(sourceFileName)
|
||||
|
||||
for (const esVersion of esVersions) {
|
||||
const intermediateFileName = sourceFileName.replace(/\.ts$/, '.js')
|
||||
const targetFileName = sourceFileName.replace(/\.ts$/, `.${esVersion}.cjs`)
|
||||
|
||||
const shouldTranspile = !existsSync(targetFileName) || (await stat(targetFileName)).mtimeMs < sourceStat.mtimeMs
|
||||
|
||||
if (shouldTranspile) {
|
||||
await execa('tsc', ['--target', esVersion, '--module', 'commonjs', sourceFileName])
|
||||
await execa('mv', [intermediateFileName, targetFileName])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transpile().catch(err => {
|
||||
process.exitCode = 1
|
||||
throw err
|
||||
})
|
||||
15
node_modules/pino/test/fixtures/ts/transport-exit-immediately-with-async-dest.ts
generated
vendored
Normal file
15
node_modules/pino/test/fixtures/ts/transport-exit-immediately-with-async-dest.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import pino from '../../..'
|
||||
import { join } from 'node:path'
|
||||
|
||||
const transport = pino.transport({
|
||||
target: join(__dirname, 'to-file-transport-with-transform.ts'),
|
||||
options: {
|
||||
destination: process.argv[2]
|
||||
}
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
logger.info('Hello')
|
||||
logger.info('World')
|
||||
|
||||
process.exit(0)
|
||||
10
node_modules/pino/test/fixtures/ts/transport-exit-immediately.ts
generated
vendored
Normal file
10
node_modules/pino/test/fixtures/ts/transport-exit-immediately.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import pino from '../../..'
|
||||
|
||||
const transport = pino.transport({
|
||||
target: 'pino/file'
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
logger.info('Hello')
|
||||
|
||||
process.exit(0)
|
||||
11
node_modules/pino/test/fixtures/ts/transport-exit-on-ready.ts
generated
vendored
Normal file
11
node_modules/pino/test/fixtures/ts/transport-exit-on-ready.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import pino from '../../..'
|
||||
|
||||
const transport = pino.transport({
|
||||
target: 'pino/file'
|
||||
})
|
||||
const logger = pino(transport)
|
||||
|
||||
transport.on('ready', function () {
|
||||
logger.info('Hello')
|
||||
process.exit(0)
|
||||
})
|
||||
8
node_modules/pino/test/fixtures/ts/transport-main.ts
generated
vendored
Normal file
8
node_modules/pino/test/fixtures/ts/transport-main.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { join } from 'node:path'
|
||||
import pino from '../../..'
|
||||
|
||||
const transport = pino.transport({
|
||||
target: join(__dirname, 'transport-worker.ts')
|
||||
})
|
||||
const logger = pino(transport)
|
||||
logger.info('Hello')
|
||||
8
node_modules/pino/test/fixtures/ts/transport-string-stdout.ts
generated
vendored
Normal file
8
node_modules/pino/test/fixtures/ts/transport-string-stdout.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import pino from '../../..'
|
||||
|
||||
const transport = pino.transport({
|
||||
target: 'pino/file',
|
||||
options: { destination: '1' }
|
||||
})
|
||||
const logger = pino(transport)
|
||||
logger.info('Hello')
|
||||
14
node_modules/pino/test/fixtures/ts/transport-worker.ts
generated
vendored
Normal file
14
node_modules/pino/test/fixtures/ts/transport-worker.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Writable } from 'node:stream'
|
||||
|
||||
export default (): Writable => {
|
||||
const myTransportStream = new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, _enc, cb) {
|
||||
console.log(chunk.toString())
|
||||
cb()
|
||||
},
|
||||
defaultEncoding: 'utf8'
|
||||
})
|
||||
|
||||
return myTransportStream
|
||||
}
|
||||
355
node_modules/pino/test/formatters.test.js
generated
vendored
Normal file
355
node_modules/pino/test/formatters.test.js
generated
vendored
Normal file
@@ -0,0 +1,355 @@
|
||||
'use strict'
|
||||
/* eslint no-prototype-builtins: 0 */
|
||||
|
||||
const { hostname } = require('node:os')
|
||||
const { join } = require('node:path')
|
||||
const { readFile } = require('node:fs').promises
|
||||
const { test } = require('tap')
|
||||
const { sink, once, watchFileCreated, file } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
test('level formatter', async ({ match }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return {
|
||||
log: {
|
||||
level: label
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info('hello world')
|
||||
match(await o, {
|
||||
log: {
|
||||
level: 'info'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('bindings formatter', async ({ match }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
bindings (bindings) {
|
||||
return {
|
||||
process: {
|
||||
pid: bindings.pid
|
||||
},
|
||||
host: {
|
||||
name: bindings.hostname
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info('hello world')
|
||||
match(await o, {
|
||||
process: {
|
||||
pid: process.pid
|
||||
},
|
||||
host: {
|
||||
name: hostname()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('no bindings formatter', async ({ match, notOk }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
bindings (bindings) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info('hello world')
|
||||
const log = await o
|
||||
notOk(log.hasOwnProperty('pid'))
|
||||
notOk(log.hasOwnProperty('hostname'))
|
||||
match(log, { msg: 'hello world' })
|
||||
})
|
||||
|
||||
test('log formatter', async ({ match, equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
log (obj) {
|
||||
equal(obj.hasOwnProperty('msg'), false)
|
||||
return { hello: 'world', ...obj }
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info({ foo: 'bar', nested: { object: true } }, 'hello world')
|
||||
match(await o, {
|
||||
hello: 'world',
|
||||
foo: 'bar',
|
||||
nested: { object: true }
|
||||
})
|
||||
})
|
||||
|
||||
test('Formatters combined', async ({ match }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return {
|
||||
log: {
|
||||
level: label
|
||||
}
|
||||
}
|
||||
},
|
||||
bindings (bindings) {
|
||||
return {
|
||||
process: {
|
||||
pid: bindings.pid
|
||||
},
|
||||
host: {
|
||||
name: bindings.hostname
|
||||
}
|
||||
}
|
||||
},
|
||||
log (obj) {
|
||||
return { hello: 'world', ...obj }
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info({ foo: 'bar', nested: { object: true } }, 'hello world')
|
||||
match(await o, {
|
||||
log: {
|
||||
level: 'info'
|
||||
},
|
||||
process: {
|
||||
pid: process.pid
|
||||
},
|
||||
host: {
|
||||
name: hostname()
|
||||
},
|
||||
hello: 'world',
|
||||
foo: 'bar',
|
||||
nested: { object: true }
|
||||
})
|
||||
})
|
||||
|
||||
test('Formatters in child logger', async ({ match }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return {
|
||||
log: {
|
||||
level: label
|
||||
}
|
||||
}
|
||||
},
|
||||
bindings (bindings) {
|
||||
return {
|
||||
process: {
|
||||
pid: bindings.pid
|
||||
},
|
||||
host: {
|
||||
name: bindings.hostname
|
||||
}
|
||||
}
|
||||
},
|
||||
log (obj) {
|
||||
return { hello: 'world', ...obj }
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const child = logger.child({
|
||||
foo: 'bar',
|
||||
nested: { object: true }
|
||||
}, {
|
||||
formatters: {
|
||||
bindings (bindings) {
|
||||
return { ...bindings, faz: 'baz' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const o = once(stream, 'data')
|
||||
child.info('hello world')
|
||||
match(await o, {
|
||||
log: {
|
||||
level: 'info'
|
||||
},
|
||||
process: {
|
||||
pid: process.pid
|
||||
},
|
||||
host: {
|
||||
name: hostname()
|
||||
},
|
||||
hello: 'world',
|
||||
foo: 'bar',
|
||||
nested: { object: true },
|
||||
faz: 'baz'
|
||||
})
|
||||
})
|
||||
|
||||
test('Formatters without bindings in child logger', async ({ match }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return {
|
||||
log: {
|
||||
level: label
|
||||
}
|
||||
}
|
||||
},
|
||||
bindings (bindings) {
|
||||
return {
|
||||
process: {
|
||||
pid: bindings.pid
|
||||
},
|
||||
host: {
|
||||
name: bindings.hostname
|
||||
}
|
||||
}
|
||||
},
|
||||
log (obj) {
|
||||
return { hello: 'world', ...obj }
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const child = logger.child({
|
||||
foo: 'bar',
|
||||
nested: { object: true }
|
||||
}, {
|
||||
formatters: {
|
||||
log (obj) {
|
||||
return { other: 'stuff', ...obj }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const o = once(stream, 'data')
|
||||
child.info('hello world')
|
||||
match(await o, {
|
||||
log: {
|
||||
level: 'info'
|
||||
},
|
||||
process: {
|
||||
pid: process.pid
|
||||
},
|
||||
host: {
|
||||
name: hostname()
|
||||
},
|
||||
foo: 'bar',
|
||||
other: 'stuff',
|
||||
nested: { object: true }
|
||||
})
|
||||
})
|
||||
|
||||
test('elastic common schema format', async ({ match, type }) => {
|
||||
const stream = sink()
|
||||
const ecs = {
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return {
|
||||
log: {
|
||||
level: label,
|
||||
logger: 'pino'
|
||||
}
|
||||
}
|
||||
},
|
||||
bindings (bindings) {
|
||||
return {
|
||||
process: {
|
||||
pid: bindings.pid
|
||||
},
|
||||
host: {
|
||||
name: bindings.hostname
|
||||
}
|
||||
}
|
||||
},
|
||||
log (obj) {
|
||||
return { ecs: { version: '1.4.0' }, ...obj }
|
||||
}
|
||||
},
|
||||
messageKey: 'message',
|
||||
timestamp: () => `,"@timestamp":"${new Date(Date.now()).toISOString()}"`
|
||||
}
|
||||
|
||||
const logger = pino({ ...ecs }, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info({ foo: 'bar' }, 'hello world')
|
||||
const log = await o
|
||||
type(log['@timestamp'], 'string')
|
||||
match(log, {
|
||||
log: { level: 'info', logger: 'pino' },
|
||||
process: { pid: process.pid },
|
||||
host: { name: hostname() },
|
||||
ecs: { version: '1.4.0' },
|
||||
foo: 'bar',
|
||||
message: 'hello world'
|
||||
})
|
||||
})
|
||||
|
||||
test('formatter with transport', async ({ match, equal }) => {
|
||||
const destination = file()
|
||||
const logger = pino({
|
||||
formatters: {
|
||||
log (obj) {
|
||||
equal(obj.hasOwnProperty('msg'), false)
|
||||
return { hello: 'world', ...obj }
|
||||
}
|
||||
},
|
||||
transport: {
|
||||
targets: [
|
||||
{
|
||||
target: join(__dirname, 'fixtures', 'to-file-transport.js'),
|
||||
options: { destination }
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
logger.info({ foo: 'bar', nested: { object: true } }, 'hello world')
|
||||
await watchFileCreated(destination)
|
||||
const result = JSON.parse(await readFile(destination))
|
||||
delete result.time
|
||||
match(result, {
|
||||
hello: 'world',
|
||||
foo: 'bar',
|
||||
nested: { object: true }
|
||||
})
|
||||
})
|
||||
|
||||
test('throws when custom level formatter is used with transport.targets', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({
|
||||
formatters: {
|
||||
level (label) {
|
||||
return label
|
||||
}
|
||||
},
|
||||
transport: {
|
||||
targets: [
|
||||
{
|
||||
target: 'pino/file',
|
||||
options: { destination: 'foo.log' }
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
Error('option.transport.targets do not allow custom level formatters'))
|
||||
})
|
||||
4
node_modules/pino/test/helper.d.ts
generated
vendored
Normal file
4
node_modules/pino/test/helper.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { PathLike } from 'node:fs'
|
||||
|
||||
export declare function watchFileCreated(filename: PathLike): Promise<void>
|
||||
export declare function watchForWrite(filename: PathLike, testString: string): Promise<void>
|
||||
128
node_modules/pino/test/helper.js
generated
vendored
Normal file
128
node_modules/pino/test/helper.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
'use strict'
|
||||
|
||||
const crypto = require('crypto')
|
||||
const os = require('node:os')
|
||||
const writer = require('flush-write-stream')
|
||||
const split = require('split2')
|
||||
const { existsSync, readFileSync, statSync, unlinkSync } = require('node:fs')
|
||||
const pid = process.pid
|
||||
const hostname = os.hostname()
|
||||
const t = require('tap')
|
||||
const { join } = require('node:path')
|
||||
const { tmpdir } = os
|
||||
|
||||
const isWin = process.platform === 'win32'
|
||||
const isYarnPnp = process.versions.pnp !== undefined
|
||||
|
||||
function getPathToNull () {
|
||||
return isWin ? '\\\\.\\NUL' : '/dev/null'
|
||||
}
|
||||
|
||||
function once (emitter, name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (name !== 'error') emitter.once('error', reject)
|
||||
emitter.once(name, (...args) => {
|
||||
emitter.removeListener('error', reject)
|
||||
resolve(...args)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function sink (func) {
|
||||
const result = split((data) => {
|
||||
try {
|
||||
return JSON.parse(data)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
console.log(data)
|
||||
}
|
||||
})
|
||||
if (func) result.pipe(writer.obj(func))
|
||||
return result
|
||||
}
|
||||
|
||||
function check (is, chunk, level, msg) {
|
||||
is(new Date(chunk.time) <= new Date(), true, 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
is(chunk.pid, pid)
|
||||
is(chunk.hostname, hostname)
|
||||
is(chunk.level, level)
|
||||
is(chunk.msg, msg)
|
||||
}
|
||||
|
||||
function sleep (ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms)
|
||||
})
|
||||
}
|
||||
|
||||
function watchFileCreated (filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const TIMEOUT = process.env.PINO_TEST_WAIT_WATCHFILE_TIMEOUT || 10000
|
||||
const INTERVAL = 100
|
||||
const threshold = TIMEOUT / INTERVAL
|
||||
let counter = 0
|
||||
const interval = setInterval(() => {
|
||||
const exists = existsSync(filename)
|
||||
// On some CI runs file is created but not filled
|
||||
if (exists && statSync(filename).size !== 0) {
|
||||
clearInterval(interval)
|
||||
resolve()
|
||||
} else if (counter <= threshold) {
|
||||
counter++
|
||||
} else {
|
||||
clearInterval(interval)
|
||||
reject(new Error(
|
||||
`${filename} hasn't been created within ${TIMEOUT} ms. ` +
|
||||
(exists ? 'File exist, but still empty.' : 'File not yet created.')
|
||||
))
|
||||
}
|
||||
}, INTERVAL)
|
||||
})
|
||||
}
|
||||
|
||||
function watchForWrite (filename, testString) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const TIMEOUT = process.env.PINO_TEST_WAIT_WRITE_TIMEOUT || 10000
|
||||
const INTERVAL = 100
|
||||
const threshold = TIMEOUT / INTERVAL
|
||||
let counter = 0
|
||||
const interval = setInterval(() => {
|
||||
if (readFileSync(filename).includes(testString)) {
|
||||
clearInterval(interval)
|
||||
resolve()
|
||||
} else if (counter <= threshold) {
|
||||
counter++
|
||||
} else {
|
||||
clearInterval(interval)
|
||||
reject(new Error(`'${testString}' hasn't been written to ${filename} within ${TIMEOUT} ms.`))
|
||||
}
|
||||
}, INTERVAL)
|
||||
})
|
||||
}
|
||||
|
||||
let files = []
|
||||
|
||||
function file () {
|
||||
const hash = crypto.randomBytes(12).toString('hex')
|
||||
const file = join(tmpdir(), `pino-${pid}-${hash}`)
|
||||
files.push(file)
|
||||
return file
|
||||
}
|
||||
|
||||
process.on('beforeExit', () => {
|
||||
if (files.length === 0) return
|
||||
t.comment('unlink files')
|
||||
for (const file of files) {
|
||||
try {
|
||||
t.comment(`unliking ${file}`)
|
||||
unlinkSync(file)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
files = []
|
||||
t.comment('unlink completed')
|
||||
})
|
||||
|
||||
module.exports = { getPathToNull, sink, check, once, sleep, watchFileCreated, watchForWrite, isWin, isYarnPnp, file }
|
||||
118
node_modules/pino/test/hooks.test.js
generated
vendored
Normal file
118
node_modules/pino/test/hooks.test.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
'use strict'
|
||||
|
||||
const tap = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
tap.test('log method hook', t => {
|
||||
t.test('gets invoked', async t => {
|
||||
t.plan(8)
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
hooks: {
|
||||
logMethod (args, method, level) {
|
||||
t.type(args, Array)
|
||||
t.type(level, 'number')
|
||||
t.equal(args.length, 3)
|
||||
t.equal(level, this.levels.values.info)
|
||||
t.same(args, ['a', 'b', 'c'])
|
||||
|
||||
t.type(method, Function)
|
||||
t.equal(method.name, 'LOG')
|
||||
|
||||
method.apply(this, [args.join('-')])
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info('a', 'b', 'c')
|
||||
t.match(await o, { msg: 'a-b-c' })
|
||||
})
|
||||
|
||||
t.test('fatal method invokes hook', async t => {
|
||||
t.plan(2)
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
hooks: {
|
||||
logMethod (args, method) {
|
||||
t.pass()
|
||||
method.apply(this, [args.join('-')])
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.fatal('a')
|
||||
t.match(await o, { msg: 'a' })
|
||||
})
|
||||
|
||||
t.test('children get the hook', async t => {
|
||||
t.plan(4)
|
||||
|
||||
const stream = sink()
|
||||
const root = pino({
|
||||
hooks: {
|
||||
logMethod (args, method) {
|
||||
t.pass()
|
||||
method.apply(this, [args.join('-')])
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
const child = root.child({ child: 'one' })
|
||||
const grandchild = child.child({ child: 'two' })
|
||||
|
||||
let o = once(stream, 'data')
|
||||
child.info('a', 'b')
|
||||
t.match(await o, { msg: 'a-b' })
|
||||
|
||||
o = once(stream, 'data')
|
||||
grandchild.info('c', 'd')
|
||||
t.match(await o, { msg: 'c-d' })
|
||||
})
|
||||
|
||||
t.test('get log level', async t => {
|
||||
t.plan(3)
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
hooks: {
|
||||
logMethod (args, method, level) {
|
||||
t.type(level, 'number')
|
||||
t.equal(level, this.levels.values.error)
|
||||
|
||||
method.apply(this, [args.join('-')])
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.error('a')
|
||||
t.match(await o, { msg: 'a' })
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
tap.test('streamWrite hook', t => {
|
||||
t.test('gets invoked', async t => {
|
||||
t.plan(1)
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
hooks: {
|
||||
streamWrite (s) {
|
||||
return s.replaceAll('redact-me', 'XXX')
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
const o = once(stream, 'data')
|
||||
logger.info('hide redact-me in this string')
|
||||
t.match(await o, { msg: 'hide XXX in this string' })
|
||||
})
|
||||
|
||||
t.end()
|
||||
})
|
||||
242
node_modules/pino/test/http.test.js
generated
vendored
Normal file
242
node_modules/pino/test/http.test.js
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
'use strict'
|
||||
|
||||
const http = require('http')
|
||||
const os = require('node:os')
|
||||
const semver = require('semver')
|
||||
const { test, skip } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
test('http request support', async ({ ok, same, error, teardown }) => {
|
||||
let originalReq
|
||||
const instance = pino(sink((chunk, enc) => {
|
||||
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
same(chunk, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'my request',
|
||||
req: {
|
||||
method: originalReq.method,
|
||||
url: originalReq.url,
|
||||
headers: originalReq.headers,
|
||||
remoteAddress: originalReq.socket.remoteAddress,
|
||||
remotePort: originalReq.socket.remotePort
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
originalReq = req
|
||||
instance.info(req, 'my request')
|
||||
res.end('hello')
|
||||
})
|
||||
server.unref()
|
||||
server.listen()
|
||||
const err = await once(server, 'listening')
|
||||
error(err)
|
||||
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
|
||||
res.resume()
|
||||
server.close()
|
||||
})
|
||||
|
||||
test('http request support via serializer', async ({ ok, same, error, teardown }) => {
|
||||
let originalReq
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
req: pino.stdSerializers.req
|
||||
}
|
||||
}, sink((chunk, enc) => {
|
||||
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
same(chunk, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'my request',
|
||||
req: {
|
||||
method: originalReq.method,
|
||||
url: originalReq.url,
|
||||
headers: originalReq.headers,
|
||||
remoteAddress: originalReq.socket.remoteAddress,
|
||||
remotePort: originalReq.socket.remotePort
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
const server = http.createServer(function (req, res) {
|
||||
originalReq = req
|
||||
instance.info({ req }, 'my request')
|
||||
res.end('hello')
|
||||
})
|
||||
server.unref()
|
||||
server.listen()
|
||||
const err = await once(server, 'listening')
|
||||
error(err)
|
||||
|
||||
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
|
||||
res.resume()
|
||||
server.close()
|
||||
})
|
||||
|
||||
// skipped because request connection is deprecated since v13, and request socket is always available
|
||||
skip('http request support via serializer without request connection', async ({ ok, same, error, teardown }) => {
|
||||
let originalReq
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
req: pino.stdSerializers.req
|
||||
}
|
||||
}, sink((chunk, enc) => {
|
||||
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
const expected = {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'my request',
|
||||
req: {
|
||||
method: originalReq.method,
|
||||
url: originalReq.url,
|
||||
headers: originalReq.headers
|
||||
}
|
||||
}
|
||||
if (semver.gte(process.version, '13.0.0')) {
|
||||
expected.req.remoteAddress = originalReq.socket.remoteAddress
|
||||
expected.req.remotePort = originalReq.socket.remotePort
|
||||
}
|
||||
same(chunk, expected)
|
||||
}))
|
||||
|
||||
const server = http.createServer(function (req, res) {
|
||||
originalReq = req
|
||||
delete req.connection
|
||||
instance.info({ req }, 'my request')
|
||||
res.end('hello')
|
||||
})
|
||||
server.unref()
|
||||
server.listen()
|
||||
const err = await once(server, 'listening')
|
||||
error(err)
|
||||
|
||||
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
|
||||
res.resume()
|
||||
server.close()
|
||||
})
|
||||
|
||||
test('http response support', async ({ ok, same, error, teardown }) => {
|
||||
let originalRes
|
||||
const instance = pino(sink((chunk, enc) => {
|
||||
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
same(chunk, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'my response',
|
||||
res: {
|
||||
statusCode: originalRes.statusCode,
|
||||
headers: originalRes.getHeaders()
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
const server = http.createServer(function (req, res) {
|
||||
originalRes = res
|
||||
res.end('hello')
|
||||
instance.info(res, 'my response')
|
||||
})
|
||||
server.unref()
|
||||
server.listen()
|
||||
const err = await once(server, 'listening')
|
||||
|
||||
error(err)
|
||||
|
||||
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
|
||||
res.resume()
|
||||
server.close()
|
||||
})
|
||||
|
||||
test('http response support via a serializer', async ({ ok, same, error, teardown }) => {
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
res: pino.stdSerializers.res
|
||||
}
|
||||
}, sink((chunk, enc) => {
|
||||
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
same(chunk, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'my response',
|
||||
res: {
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'x-single': 'y',
|
||||
'x-multi': [1, 2]
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
const server = http.createServer(function (req, res) {
|
||||
res.setHeader('x-single', 'y')
|
||||
res.setHeader('x-multi', [1, 2])
|
||||
res.end('hello')
|
||||
instance.info({ res }, 'my response')
|
||||
})
|
||||
|
||||
server.unref()
|
||||
server.listen()
|
||||
const err = await once(server, 'listening')
|
||||
error(err)
|
||||
|
||||
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
|
||||
res.resume()
|
||||
server.close()
|
||||
})
|
||||
|
||||
test('http request support via serializer in a child', async ({ ok, same, error, teardown }) => {
|
||||
let originalReq
|
||||
const instance = pino({
|
||||
serializers: {
|
||||
req: pino.stdSerializers.req
|
||||
}
|
||||
}, sink((chunk, enc) => {
|
||||
ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete chunk.time
|
||||
same(chunk, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'my request',
|
||||
req: {
|
||||
method: originalReq.method,
|
||||
url: originalReq.url,
|
||||
headers: originalReq.headers,
|
||||
remoteAddress: originalReq.socket.remoteAddress,
|
||||
remotePort: originalReq.socket.remotePort
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
const server = http.createServer(function (req, res) {
|
||||
originalReq = req
|
||||
const child = instance.child({ req })
|
||||
child.info('my request')
|
||||
res.end('hello')
|
||||
})
|
||||
|
||||
server.unref()
|
||||
server.listen()
|
||||
const err = await once(server, 'listening')
|
||||
error(err)
|
||||
|
||||
const res = await once(http.get('http://localhost:' + server.address().port), 'response')
|
||||
res.resume()
|
||||
server.close()
|
||||
})
|
||||
15
node_modules/pino/test/internals/version.test.js
generated
vendored
Normal file
15
node_modules/pino/test/internals/version.test.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const t = require('tap')
|
||||
const test = t.test
|
||||
const pino = require('../..')()
|
||||
|
||||
test('should be the same as package.json', t => {
|
||||
t.plan(1)
|
||||
|
||||
const json = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json')).toString('utf8'))
|
||||
|
||||
t.equal(pino.version, json.version)
|
||||
})
|
||||
185
node_modules/pino/test/is-level-enabled.test.js
generated
vendored
Normal file
185
node_modules/pino/test/is-level-enabled.test.js
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const pino = require('../')
|
||||
|
||||
const descLevels = {
|
||||
trace: 60,
|
||||
debug: 50,
|
||||
info: 40,
|
||||
warn: 30,
|
||||
error: 20,
|
||||
fatal: 10
|
||||
}
|
||||
|
||||
const ascLevels = {
|
||||
trace: 10,
|
||||
debug: 20,
|
||||
info: 30,
|
||||
warn: 40,
|
||||
error: 50,
|
||||
fatal: 60
|
||||
}
|
||||
|
||||
test('Default levels suite', ({ test, end }) => {
|
||||
test('can check if current level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if level enabled after level set', async ({ equal }) => {
|
||||
const log = pino()
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
log.level = 'debug'
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if higher level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
})
|
||||
|
||||
test('can check if lower level is disabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error' })
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('ASC: can check if child has current level enabled', async ({ equal }) => {
|
||||
const log = pino().child({}, { level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if custom level is enabled', async ({ equal }) => {
|
||||
const log = pino({
|
||||
customLevels: { foo: 35 },
|
||||
level: 'debug'
|
||||
})
|
||||
equal(true, log.isLevelEnabled('foo'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('Ascending levels suite', ({ test, end }) => {
|
||||
const customLevels = ascLevels
|
||||
const levelComparison = 'ASC'
|
||||
|
||||
test('can check if current level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug', levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if level enabled after level set', async ({ equal }) => {
|
||||
const log = pino({ levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
log.level = 'debug'
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if higher level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug', levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
})
|
||||
|
||||
test('can check if lower level is disabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error', customLevels, useOnlyCustomLevels: true })
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if child has current level enabled', async ({ equal }) => {
|
||||
const log = pino().child({ levelComparison, customLevels, useOnlyCustomLevels: true }, { level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if custom level is enabled', async ({ equal }) => {
|
||||
const log = pino({
|
||||
levelComparison,
|
||||
useOnlyCustomLevels: true,
|
||||
customLevels: { foo: 35, ...customLevels },
|
||||
level: 'debug'
|
||||
})
|
||||
equal(true, log.isLevelEnabled('foo'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('Descending levels suite', ({ test, end }) => {
|
||||
const customLevels = descLevels
|
||||
const levelComparison = 'DESC'
|
||||
|
||||
test('can check if current level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug', levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if level enabled after level set', async ({ equal }) => {
|
||||
const log = pino({ levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
log.level = 'debug'
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('can check if higher level enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'debug', levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
})
|
||||
|
||||
test('can check if lower level is disabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error', levelComparison, customLevels, useOnlyCustomLevels: true })
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if child has current level enabled', async ({ equal }) => {
|
||||
const log = pino({ levelComparison, customLevels, useOnlyCustomLevels: true }).child({}, { level: 'debug' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
test('can check if custom level is enabled', async ({ equal }) => {
|
||||
const log = pino({
|
||||
levelComparison,
|
||||
customLevels: { foo: 35, ...customLevels },
|
||||
useOnlyCustomLevels: true,
|
||||
level: 'debug'
|
||||
})
|
||||
equal(true, log.isLevelEnabled('foo'))
|
||||
equal(true, log.isLevelEnabled('error'))
|
||||
equal(false, log.isLevelEnabled('trace'))
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('Custom levels comparison', async ({ test, end }) => {
|
||||
test('Custom comparison returns true cause level is enabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error', levelComparison: () => true })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('Custom comparison returns false cause level is disabled', async ({ equal }) => {
|
||||
const log = pino({ level: 'error', levelComparison: () => false })
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('Custom comparison returns true cause child level is enabled', async ({ equal }) => {
|
||||
const log = pino({ levelComparison: () => true }).child({ level: 'error' })
|
||||
equal(true, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
test('Custom comparison returns false cause child level is disabled', async ({ equal }) => {
|
||||
const log = pino({ levelComparison: () => false }).child({ level: 'error' })
|
||||
equal(false, log.isLevelEnabled('debug'))
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
10
node_modules/pino/test/jest/basic.spec.js
generated
vendored
Normal file
10
node_modules/pino/test/jest/basic.spec.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/* global test */
|
||||
const pino = require('../../pino')
|
||||
|
||||
test('transport should work in jest', function () {
|
||||
pino({
|
||||
transport: {
|
||||
target: 'pino-pretty'
|
||||
}
|
||||
})
|
||||
})
|
||||
772
node_modules/pino/test/levels.test.js
generated
vendored
Normal file
772
node_modules/pino/test/levels.test.js
generated
vendored
Normal file
@@ -0,0 +1,772 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { sink, once, check } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const levelsLib = require('../lib/levels')
|
||||
|
||||
// Silence all warnings for this test
|
||||
process.removeAllListeners('warning')
|
||||
process.on('warning', () => {})
|
||||
|
||||
test('set the level by string', async ({ equal }) => {
|
||||
const expected = [{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
}, {
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}]
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
const result = await once(stream, 'data')
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
})
|
||||
|
||||
test('the wrong level throws', async ({ throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => {
|
||||
instance.level = 'kaboom'
|
||||
})
|
||||
})
|
||||
|
||||
test('set the level by number', async ({ equal }) => {
|
||||
const expected = [{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
}, {
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}]
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
|
||||
instance.level = 50
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
const result = await once(stream, 'data')
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
})
|
||||
|
||||
test('exposes level string mappings', async ({ equal }) => {
|
||||
equal(pino.levels.values.error, 50)
|
||||
})
|
||||
|
||||
test('exposes level number mappings', async ({ equal }) => {
|
||||
equal(pino.levels.labels[50], 'error')
|
||||
})
|
||||
|
||||
test('returns level integer', async ({ equal }) => {
|
||||
const instance = pino({ level: 'error' })
|
||||
equal(instance.levelVal, 50)
|
||||
})
|
||||
|
||||
test('child returns level integer', async ({ equal }) => {
|
||||
const parent = pino({ level: 'error' })
|
||||
const child = parent.child({ foo: 'bar' })
|
||||
equal(child.levelVal, 50)
|
||||
})
|
||||
|
||||
test('set the level via exported pino function', async ({ equal }) => {
|
||||
const expected = [{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
}, {
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}]
|
||||
const stream = sink()
|
||||
const instance = pino({ level: 'error' }, stream)
|
||||
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
const result = await once(stream, 'data')
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
})
|
||||
|
||||
test('level-change event', async ({ equal }) => {
|
||||
const instance = pino()
|
||||
function handle (lvl, val, prevLvl, prevVal, logger) {
|
||||
equal(lvl, 'trace')
|
||||
equal(val, 10)
|
||||
equal(prevLvl, 'info')
|
||||
equal(prevVal, 30)
|
||||
equal(logger, instance)
|
||||
}
|
||||
instance.on('level-change', handle)
|
||||
instance.level = 'trace'
|
||||
instance.removeListener('level-change', handle)
|
||||
instance.level = 'info'
|
||||
|
||||
let count = 0
|
||||
|
||||
const l1 = () => count++
|
||||
const l2 = () => count++
|
||||
const l3 = () => count++
|
||||
instance.on('level-change', l1)
|
||||
instance.on('level-change', l2)
|
||||
instance.on('level-change', l3)
|
||||
|
||||
instance.level = 'trace'
|
||||
instance.removeListener('level-change', l3)
|
||||
instance.level = 'fatal'
|
||||
instance.removeListener('level-change', l1)
|
||||
instance.level = 'debug'
|
||||
instance.removeListener('level-change', l2)
|
||||
instance.level = 'info'
|
||||
|
||||
equal(count, 6)
|
||||
|
||||
instance.once('level-change', (lvl, val, prevLvl, prevVal, logger) => equal(logger, instance))
|
||||
instance.level = 'info'
|
||||
const child = instance.child({})
|
||||
instance.once('level-change', (lvl, val, prevLvl, prevVal, logger) => equal(logger, child))
|
||||
child.level = 'trace'
|
||||
})
|
||||
|
||||
test('enable', async ({ fail }) => {
|
||||
const instance = pino({
|
||||
level: 'trace',
|
||||
enabled: false
|
||||
}, sink((result, enc) => {
|
||||
fail('no data should be logged')
|
||||
}))
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
})
|
||||
|
||||
test('silent level', async ({ fail }) => {
|
||||
const instance = pino({
|
||||
level: 'silent'
|
||||
}, sink((result, enc) => {
|
||||
fail('no data should be logged')
|
||||
}))
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
})
|
||||
|
||||
test('set silent via Infinity', async ({ fail }) => {
|
||||
const instance = pino({
|
||||
level: Infinity
|
||||
}, sink((result, enc) => {
|
||||
fail('no data should be logged')
|
||||
}))
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
})
|
||||
|
||||
test('exposed levels', async ({ same }) => {
|
||||
same(Object.keys(pino.levels.values), [
|
||||
'trace',
|
||||
'debug',
|
||||
'info',
|
||||
'warn',
|
||||
'error',
|
||||
'fatal'
|
||||
])
|
||||
})
|
||||
|
||||
test('exposed labels', async ({ same }) => {
|
||||
same(Object.keys(pino.levels.labels), [
|
||||
'10',
|
||||
'20',
|
||||
'30',
|
||||
'40',
|
||||
'50',
|
||||
'60'
|
||||
])
|
||||
})
|
||||
|
||||
test('setting level in child', async ({ equal }) => {
|
||||
const expected = [{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
}, {
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}]
|
||||
const instance = pino(sink((result, enc, cb) => {
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
cb()
|
||||
})).child({ level: 30 })
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
})
|
||||
|
||||
test('setting level by assigning a number to level', async ({ equal }) => {
|
||||
const instance = pino()
|
||||
equal(instance.levelVal, 30)
|
||||
equal(instance.level, 'info')
|
||||
instance.level = 50
|
||||
equal(instance.levelVal, 50)
|
||||
equal(instance.level, 'error')
|
||||
})
|
||||
|
||||
test('setting level by number to unknown value results in a throw', async ({ throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => { instance.level = 973 })
|
||||
})
|
||||
|
||||
test('setting level by assigning a known label to level', async ({ equal }) => {
|
||||
const instance = pino()
|
||||
equal(instance.levelVal, 30)
|
||||
equal(instance.level, 'info')
|
||||
instance.level = 'error'
|
||||
equal(instance.levelVal, 50)
|
||||
equal(instance.level, 'error')
|
||||
})
|
||||
|
||||
test('levelVal is read only', async ({ throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => { instance.levelVal = 20 })
|
||||
})
|
||||
|
||||
test('produces labels when told to', async ({ equal }) => {
|
||||
const expected = [{
|
||||
level: 'info',
|
||||
msg: 'hello world'
|
||||
}]
|
||||
const instance = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { level: label }
|
||||
}
|
||||
}
|
||||
}, sink((result, enc, cb) => {
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
cb()
|
||||
}))
|
||||
|
||||
instance.info('hello world')
|
||||
})
|
||||
|
||||
test('resets levels from labels to numbers', async ({ equal }) => {
|
||||
const expected = [{
|
||||
level: 30,
|
||||
msg: 'hello world'
|
||||
}]
|
||||
pino({ useLevelLabels: true })
|
||||
const instance = pino({ useLevelLabels: false }, sink((result, enc, cb) => {
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
cb()
|
||||
}))
|
||||
|
||||
instance.info('hello world')
|
||||
})
|
||||
|
||||
test('changes label naming when told to', async ({ equal }) => {
|
||||
const expected = [{
|
||||
priority: 30,
|
||||
msg: 'hello world'
|
||||
}]
|
||||
const instance = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { priority: number }
|
||||
}
|
||||
}
|
||||
}, sink((result, enc, cb) => {
|
||||
const current = expected.shift()
|
||||
equal(result.priority, current.priority)
|
||||
equal(result.msg, current.msg)
|
||||
cb()
|
||||
}))
|
||||
|
||||
instance.info('hello world')
|
||||
})
|
||||
|
||||
test('children produce labels when told to', async ({ equal }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 'info',
|
||||
msg: 'child 1'
|
||||
},
|
||||
{
|
||||
level: 'info',
|
||||
msg: 'child 2'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { level: label }
|
||||
}
|
||||
}
|
||||
}, sink((result, enc, cb) => {
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
cb()
|
||||
}))
|
||||
|
||||
const child1 = instance.child({ name: 'child1' })
|
||||
const child2 = child1.child({ name: 'child2' })
|
||||
|
||||
child1.info('child 1')
|
||||
child2.info('child 2')
|
||||
})
|
||||
|
||||
test('produces labels for custom levels', async ({ equal }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 'info',
|
||||
msg: 'hello world'
|
||||
},
|
||||
{
|
||||
level: 'foo',
|
||||
msg: 'foobar'
|
||||
}
|
||||
]
|
||||
const opts = {
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { level: label }
|
||||
}
|
||||
},
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}
|
||||
const instance = pino(opts, sink((result, enc, cb) => {
|
||||
const current = expected.shift()
|
||||
check(equal, result, current.level, current.msg)
|
||||
cb()
|
||||
}))
|
||||
|
||||
instance.info('hello world')
|
||||
instance.foo('foobar')
|
||||
})
|
||||
|
||||
test('setting levelKey does not affect labels when told to', async ({ equal }) => {
|
||||
const instance = pino(
|
||||
{
|
||||
formatters: {
|
||||
level (label, number) {
|
||||
return { priority: label }
|
||||
}
|
||||
}
|
||||
},
|
||||
sink((result, enc, cb) => {
|
||||
equal(result.priority, 'info')
|
||||
cb()
|
||||
})
|
||||
)
|
||||
|
||||
instance.info('hello world')
|
||||
})
|
||||
|
||||
test('throws when creating a default label that does not exist in logger levels', async ({ throws }) => {
|
||||
const defaultLevel = 'foo'
|
||||
throws(() => {
|
||||
pino({
|
||||
customLevels: {
|
||||
bar: 5
|
||||
},
|
||||
level: defaultLevel
|
||||
})
|
||||
}, `default level:${defaultLevel} must be included in custom levels`)
|
||||
})
|
||||
|
||||
test('throws when creating a default value that does not exist in logger levels', async ({ throws }) => {
|
||||
const defaultLevel = 15
|
||||
throws(() => {
|
||||
pino({
|
||||
customLevels: {
|
||||
bar: 5
|
||||
},
|
||||
level: defaultLevel
|
||||
})
|
||||
}, `default level:${defaultLevel} must be included in custom levels`)
|
||||
})
|
||||
|
||||
test('throws when creating a default value that does not exist in logger levels', async ({ equal, throws }) => {
|
||||
throws(() => {
|
||||
pino({
|
||||
customLevels: {
|
||||
foo: 5
|
||||
},
|
||||
useOnlyCustomLevels: true
|
||||
})
|
||||
}, 'default level:info must be included in custom levels')
|
||||
})
|
||||
|
||||
test('passes when creating a default value that exists in logger levels', async ({ equal, throws }) => {
|
||||
pino({
|
||||
level: 30
|
||||
})
|
||||
})
|
||||
|
||||
test('log null value when message is null', async ({ equal }) => {
|
||||
const expected = {
|
||||
msg: null,
|
||||
level: 30
|
||||
}
|
||||
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = 'info'
|
||||
instance.info(null)
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('formats when base param is null', async ({ equal }) => {
|
||||
const expected = {
|
||||
msg: 'a string',
|
||||
level: 30
|
||||
}
|
||||
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.level = 'info'
|
||||
instance.info(null, 'a %s', 'string')
|
||||
|
||||
const result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('fatal method sync-flushes the destination if sync flushing is available', async ({ pass, doesNotThrow, plan }) => {
|
||||
plan(2)
|
||||
const stream = sink()
|
||||
stream.flushSync = () => {
|
||||
pass('destination flushed')
|
||||
}
|
||||
const instance = pino(stream)
|
||||
instance.fatal('this is fatal')
|
||||
await once(stream, 'data')
|
||||
doesNotThrow(() => {
|
||||
stream.flushSync = undefined
|
||||
instance.fatal('this is fatal')
|
||||
})
|
||||
})
|
||||
|
||||
test('fatal method should call async when sync-flushing fails', ({ equal, fail, doesNotThrow, plan }) => {
|
||||
plan(2)
|
||||
const messages = [
|
||||
'this is fatal 1'
|
||||
]
|
||||
const stream = sink((result) => equal(result.msg, messages.shift()))
|
||||
stream.flushSync = () => { throw new Error('Error') }
|
||||
stream.flush = () => fail('flush should be called')
|
||||
|
||||
const instance = pino(stream)
|
||||
doesNotThrow(() => instance.fatal(messages[0]))
|
||||
})
|
||||
|
||||
test('calling silent method on logger instance', async ({ fail }) => {
|
||||
const instance = pino({ level: 'silent' }, sink((result, enc) => {
|
||||
fail('no data should be logged')
|
||||
}))
|
||||
instance.silent('hello world')
|
||||
})
|
||||
|
||||
test('calling silent method on child logger', async ({ fail }) => {
|
||||
const child = pino({ level: 'silent' }, sink((result, enc) => {
|
||||
fail('no data should be logged')
|
||||
})).child({})
|
||||
child.silent('hello world')
|
||||
})
|
||||
|
||||
test('changing level from info to silent and back to info', async ({ equal }) => {
|
||||
const expected = {
|
||||
level: 30,
|
||||
msg: 'hello world'
|
||||
}
|
||||
const stream = sink()
|
||||
const instance = pino({ level: 'info' }, stream)
|
||||
|
||||
instance.level = 'silent'
|
||||
instance.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
instance.level = 'info'
|
||||
instance.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('changing level from info to silent and back to info in child logger', async ({ equal }) => {
|
||||
const expected = {
|
||||
level: 30,
|
||||
msg: 'hello world'
|
||||
}
|
||||
const stream = sink()
|
||||
const child = pino({ level: 'info' }, stream).child({})
|
||||
|
||||
child.level = 'silent'
|
||||
child.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
child.level = 'info'
|
||||
child.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('changing level respects level comparison set to', async ({ test, end }) => {
|
||||
const ascLevels = {
|
||||
debug: 1,
|
||||
info: 2,
|
||||
warn: 3
|
||||
}
|
||||
|
||||
const descLevels = {
|
||||
debug: 3,
|
||||
info: 2,
|
||||
warn: 1
|
||||
}
|
||||
|
||||
const expected = {
|
||||
level: 2,
|
||||
msg: 'hello world'
|
||||
}
|
||||
|
||||
test('ASC in parent logger', async ({ equal }) => {
|
||||
const customLevels = ascLevels
|
||||
const levelComparison = 'ASC'
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream)
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('DESC in parent logger', async ({ equal }) => {
|
||||
const customLevels = descLevels
|
||||
const levelComparison = 'DESC'
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream)
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('custom function in parent logger', async ({ equal }) => {
|
||||
const customLevels = {
|
||||
info: 2,
|
||||
debug: 345,
|
||||
warn: 789
|
||||
}
|
||||
const levelComparison = (current, expected) => {
|
||||
if (expected === customLevels.warn) return false
|
||||
return true
|
||||
}
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream)
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('ASC in child logger', async ({ equal }) => {
|
||||
const customLevels = ascLevels
|
||||
const levelComparison = 'ASC'
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream).child({ })
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('DESC in parent logger', async ({ equal }) => {
|
||||
const customLevels = descLevels
|
||||
const levelComparison = 'DESC'
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream).child({ })
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
test('custom function in child logger', async ({ equal }) => {
|
||||
const customLevels = {
|
||||
info: 2,
|
||||
debug: 345,
|
||||
warn: 789
|
||||
}
|
||||
const levelComparison = (current, expected) => {
|
||||
if (expected === customLevels.warn) return false
|
||||
return true
|
||||
}
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream).child({ })
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('changing level respects level comparison DESC', async ({ equal }) => {
|
||||
const customLevels = {
|
||||
warn: 1,
|
||||
info: 2,
|
||||
debug: 3
|
||||
}
|
||||
|
||||
const levelComparison = 'DESC'
|
||||
|
||||
const expected = {
|
||||
level: 2,
|
||||
msg: 'hello world'
|
||||
}
|
||||
|
||||
const stream = sink()
|
||||
const logger = pino({ levelComparison, customLevels, useOnlyCustomLevels: true, level: 'info' }, stream)
|
||||
|
||||
logger.level = 'warn'
|
||||
logger.info('hello world')
|
||||
let result = stream.read()
|
||||
equal(result, null)
|
||||
|
||||
logger.level = 'debug'
|
||||
logger.info('hello world')
|
||||
result = await once(stream, 'data')
|
||||
check(equal, result, expected.level, expected.msg)
|
||||
})
|
||||
|
||||
// testing for potential loss of Pino constructor scope from serializers - an edge case with circular refs see: https://github.com/pinojs/pino/issues/833
|
||||
test('trying to get levels when `this` is no longer a Pino instance returns an empty string', async ({ equal }) => {
|
||||
const notPinoInstance = { some: 'object', getLevel: levelsLib.getLevel }
|
||||
const blankedLevelValue = notPinoInstance.getLevel()
|
||||
equal(blankedLevelValue, '')
|
||||
})
|
||||
|
||||
test('accepts capital letter for INFO level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
level: 'INFO'
|
||||
}, stream)
|
||||
|
||||
logger.info('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 30)
|
||||
})
|
||||
|
||||
test('accepts capital letter for FATAL level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
level: 'FATAL'
|
||||
}, stream)
|
||||
|
||||
logger.fatal('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 60)
|
||||
})
|
||||
|
||||
test('accepts capital letter for ERROR level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
level: 'ERROR'
|
||||
}, stream)
|
||||
|
||||
logger.error('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 50)
|
||||
})
|
||||
|
||||
test('accepts capital letter for WARN level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
level: 'WARN'
|
||||
}, stream)
|
||||
|
||||
logger.warn('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 40)
|
||||
})
|
||||
|
||||
test('accepts capital letter for DEBUG level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
level: 'DEBUG'
|
||||
}, stream)
|
||||
|
||||
logger.debug('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 20)
|
||||
})
|
||||
|
||||
test('accepts capital letter for TRACE level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino({
|
||||
level: 'TRACE'
|
||||
}, stream)
|
||||
|
||||
logger.trace('test')
|
||||
const { level } = await once(stream, 'data')
|
||||
equal(level, 10)
|
||||
})
|
||||
106
node_modules/pino/test/metadata.test.js
generated
vendored
Normal file
106
node_modules/pino/test/metadata.test.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
'use strict'
|
||||
|
||||
const os = require('node:os')
|
||||
const { test } = require('tap')
|
||||
const pino = require('../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
test('metadata works', async ({ ok, same, equal }) => {
|
||||
const now = Date.now()
|
||||
const instance = pino({}, {
|
||||
[Symbol.for('pino.metadata')]: true,
|
||||
write (chunk) {
|
||||
equal(instance, this.lastLogger)
|
||||
equal(30, this.lastLevel)
|
||||
equal('a msg', this.lastMsg)
|
||||
ok(Number(this.lastTime) >= now)
|
||||
same(this.lastObj, { hello: 'world' })
|
||||
const result = JSON.parse(chunk)
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
hello: 'world',
|
||||
msg: 'a msg'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
instance.info({ hello: 'world' }, 'a msg')
|
||||
})
|
||||
|
||||
test('child loggers works', async ({ ok, same, equal }) => {
|
||||
const instance = pino({}, {
|
||||
[Symbol.for('pino.metadata')]: true,
|
||||
write (chunk) {
|
||||
equal(child, this.lastLogger)
|
||||
equal(30, this.lastLevel)
|
||||
equal('a msg', this.lastMsg)
|
||||
same(this.lastObj, { from: 'child' })
|
||||
const result = JSON.parse(chunk)
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
hello: 'world',
|
||||
from: 'child',
|
||||
msg: 'a msg'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const child = instance.child({ hello: 'world' })
|
||||
child.info({ from: 'child' }, 'a msg')
|
||||
})
|
||||
|
||||
test('without object', async ({ ok, same, equal }) => {
|
||||
const instance = pino({}, {
|
||||
[Symbol.for('pino.metadata')]: true,
|
||||
write (chunk) {
|
||||
equal(instance, this.lastLogger)
|
||||
equal(30, this.lastLevel)
|
||||
equal('a msg', this.lastMsg)
|
||||
same({ }, this.lastObj)
|
||||
const result = JSON.parse(chunk)
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'a msg'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('a msg')
|
||||
})
|
||||
|
||||
test('without msg', async ({ ok, same, equal }) => {
|
||||
const instance = pino({}, {
|
||||
[Symbol.for('pino.metadata')]: true,
|
||||
write (chunk) {
|
||||
equal(instance, this.lastLogger)
|
||||
equal(30, this.lastLevel)
|
||||
equal(undefined, this.lastMsg)
|
||||
same({ hello: 'world' }, this.lastObj)
|
||||
const result = JSON.parse(chunk)
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
hello: 'world'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
instance.info({ hello: 'world' })
|
||||
})
|
||||
55
node_modules/pino/test/mixin-merge-strategy.test.js
generated
vendored
Normal file
55
node_modules/pino/test/mixin-merge-strategy.test.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const level = 50
|
||||
const name = 'error'
|
||||
|
||||
test('default merge strategy', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
base: {},
|
||||
mixin () {
|
||||
return { tag: 'k8s' }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({
|
||||
tag: 'local'
|
||||
}, 'test')
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
level,
|
||||
msg: 'test',
|
||||
tag: 'local'
|
||||
})
|
||||
})
|
||||
|
||||
test('custom merge strategy with mixin priority', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
base: {},
|
||||
mixin () {
|
||||
return { tag: 'k8s' }
|
||||
},
|
||||
mixinMergeStrategy (mergeObject, mixinObject) {
|
||||
return Object.assign(mergeObject, mixinObject)
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({
|
||||
tag: 'local'
|
||||
}, 'test')
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
level,
|
||||
msg: 'test',
|
||||
tag: 'k8s'
|
||||
})
|
||||
})
|
||||
218
node_modules/pino/test/mixin.test.js
generated
vendored
Normal file
218
node_modules/pino/test/mixin.test.js
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
'use strict'
|
||||
|
||||
const os = require('node:os')
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
const level = 50
|
||||
const name = 'error'
|
||||
|
||||
test('mixin object is included', async ({ ok, same }) => {
|
||||
let n = 0
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin () {
|
||||
return { hello: ++n }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]('test')
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
msg: 'test',
|
||||
hello: 1
|
||||
})
|
||||
})
|
||||
|
||||
test('mixin object is new every time', async ({ plan, ok, same }) => {
|
||||
plan(6)
|
||||
|
||||
let n = 0
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin () {
|
||||
return { hello: n }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
|
||||
while (++n < 4) {
|
||||
const msg = `test #${n}`
|
||||
stream.pause()
|
||||
instance[name](msg)
|
||||
stream.resume()
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
msg,
|
||||
hello: n
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('mixin object is not called if below log level', async ({ ok }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin () {
|
||||
ok(false, 'should not call mixin function')
|
||||
}
|
||||
}, stream)
|
||||
instance.level = 'error'
|
||||
instance.info('test')
|
||||
})
|
||||
|
||||
test('mixin object + logged object', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin () {
|
||||
return { foo: 1, bar: 2 }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({ bar: 3, baz: 4 })
|
||||
const result = await once(stream, 'data')
|
||||
ok(new Date(result.time) <= new Date(), 'time is greater than Date.now()')
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level,
|
||||
foo: 1,
|
||||
bar: 3,
|
||||
baz: 4
|
||||
})
|
||||
})
|
||||
|
||||
test('mixin not a function', async ({ throws }) => {
|
||||
const stream = sink()
|
||||
throws(function () {
|
||||
pino({ mixin: 'not a function' }, stream)
|
||||
})
|
||||
})
|
||||
|
||||
test('mixin can use context', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin (context) {
|
||||
ok(context !== null, 'context should be defined')
|
||||
ok(context !== undefined, 'context should be defined')
|
||||
same(context, {
|
||||
message: '123',
|
||||
stack: 'stack'
|
||||
})
|
||||
return Object.assign({
|
||||
error: context.message,
|
||||
stack: context.stack
|
||||
})
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({
|
||||
message: '123',
|
||||
stack: 'stack'
|
||||
}, 'test')
|
||||
})
|
||||
|
||||
test('mixin works without context', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin (context) {
|
||||
ok(context !== null, 'context is still defined w/o passing mergeObject')
|
||||
ok(context !== undefined, 'context is still defined w/o passing mergeObject')
|
||||
same(context, {})
|
||||
return {
|
||||
something: true
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]('test')
|
||||
})
|
||||
|
||||
test('mixin can use level number', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin (context, num) {
|
||||
ok(num !== null, 'level should be defined')
|
||||
ok(num !== undefined, 'level should be defined')
|
||||
same(num, level)
|
||||
return Object.assign({
|
||||
error: context.message,
|
||||
stack: context.stack
|
||||
})
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({
|
||||
message: '123',
|
||||
stack: 'stack'
|
||||
}, 'test')
|
||||
})
|
||||
|
||||
test('mixin receives logger as third parameter', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
mixin (context, num, logger) {
|
||||
ok(logger !== null, 'logger should be defined')
|
||||
ok(logger !== undefined, 'logger should be defined')
|
||||
same(logger, instance)
|
||||
return { ...context, num }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance[name]({
|
||||
message: '123'
|
||||
}, 'test')
|
||||
})
|
||||
|
||||
test('mixin receives child logger', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
let child = null
|
||||
const instance = pino({
|
||||
mixin (context, num, logger) {
|
||||
ok(logger !== null, 'logger should be defined')
|
||||
ok(logger !== undefined, 'logger should be defined')
|
||||
same(logger.expected, child.expected)
|
||||
return { ...context, num }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance.expected = false
|
||||
child = instance.child({})
|
||||
child.expected = true
|
||||
child[name]({
|
||||
message: '123'
|
||||
}, 'test')
|
||||
})
|
||||
|
||||
test('mixin receives logger even if child exists', async ({ ok, same }) => {
|
||||
const stream = sink()
|
||||
let child = null
|
||||
const instance = pino({
|
||||
mixin (context, num, logger) {
|
||||
ok(logger !== null, 'logger should be defined')
|
||||
ok(logger !== undefined, 'logger should be defined')
|
||||
same(logger.expected, instance.expected)
|
||||
return { ...context, num }
|
||||
}
|
||||
}, stream)
|
||||
instance.level = name
|
||||
instance.expected = false
|
||||
child = instance.child({})
|
||||
child.expected = true
|
||||
instance[name]({
|
||||
message: '123'
|
||||
}, 'test')
|
||||
})
|
||||
723
node_modules/pino/test/multistream.test.js
generated
vendored
Normal file
723
node_modules/pino/test/multistream.test.js
generated
vendored
Normal file
@@ -0,0 +1,723 @@
|
||||
'use strict'
|
||||
|
||||
const writeStream = require('flush-write-stream')
|
||||
const { readFileSync } = require('node:fs')
|
||||
const { join } = require('node:path')
|
||||
const test = require('tap').test
|
||||
const pino = require('../')
|
||||
const multistream = pino.multistream
|
||||
const proxyquire = require('proxyquire')
|
||||
const strip = require('strip-ansi')
|
||||
const { file, sink } = require('./helper')
|
||||
|
||||
test('sends to multiple streams using string levels', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'debug', stream },
|
||||
{ level: 'trace', stream },
|
||||
{ level: 'fatal', stream },
|
||||
{ level: 'silent', stream }
|
||||
]
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream(streams))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 9)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('sends to multiple streams using custom levels', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'debug', stream },
|
||||
{ level: 'trace', stream },
|
||||
{ level: 'fatal', stream },
|
||||
{ level: 'silent', stream }
|
||||
]
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream(streams))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 9)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('sends to multiple streams using optionally predefined levels', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const opts = {
|
||||
levels: {
|
||||
silent: Infinity,
|
||||
fatal: 60,
|
||||
error: 50,
|
||||
warn: 50,
|
||||
info: 30,
|
||||
debug: 20,
|
||||
trace: 10
|
||||
}
|
||||
}
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'trace', stream },
|
||||
{ level: 'debug', stream },
|
||||
{ level: 'info', stream },
|
||||
{ level: 'warn', stream },
|
||||
{ level: 'error', stream },
|
||||
{ level: 'fatal', stream },
|
||||
{ level: 'silent', stream }
|
||||
]
|
||||
const mstream = multistream(streams, opts)
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, mstream)
|
||||
log.trace('trace stream')
|
||||
log.debug('debug stream')
|
||||
log.info('info stream')
|
||||
log.warn('warn stream')
|
||||
log.error('error stream')
|
||||
log.fatal('fatal stream')
|
||||
log.silent('silent stream')
|
||||
t.equal(messageCount, 24)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('sends to multiple streams using number levels', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 20, stream },
|
||||
{ level: 60, stream }
|
||||
]
|
||||
const log = pino({
|
||||
level: 'debug'
|
||||
}, multistream(streams))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 6)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('level include higher levels', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const log = pino({}, multistream([{ level: 'info', stream }]))
|
||||
log.fatal('message')
|
||||
t.equal(messageCount, 1)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('supports multiple arguments', function (t) {
|
||||
const messages = []
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messages.push(JSON.parse(data))
|
||||
if (messages.length === 2) {
|
||||
const msg1 = messages[0]
|
||||
t.equal(msg1.msg, 'foo bar baz foobar')
|
||||
|
||||
const msg2 = messages[1]
|
||||
t.equal(msg2.msg, 'foo bar baz foobar barfoo foofoo')
|
||||
|
||||
t.end()
|
||||
}
|
||||
cb()
|
||||
})
|
||||
const log = pino({}, multistream({ stream }))
|
||||
log.info('%s %s %s %s', 'foo', 'bar', 'baz', 'foobar') // apply not invoked
|
||||
log.info('%s %s %s %s %s %s', 'foo', 'bar', 'baz', 'foobar', 'barfoo', 'foofoo') // apply invoked
|
||||
})
|
||||
|
||||
test('supports children', function (t) {
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
const input = JSON.parse(data)
|
||||
t.equal(input.msg, 'child stream')
|
||||
t.equal(input.child, 'one')
|
||||
t.end()
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream }
|
||||
]
|
||||
const log = pino({}, multistream(streams)).child({ child: 'one' })
|
||||
log.info('child stream')
|
||||
})
|
||||
|
||||
test('supports grandchildren', function (t) {
|
||||
const messages = []
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messages.push(JSON.parse(data))
|
||||
if (messages.length === 3) {
|
||||
const msg1 = messages[0]
|
||||
t.equal(msg1.msg, 'grandchild stream')
|
||||
t.equal(msg1.child, 'one')
|
||||
t.equal(msg1.grandchild, 'two')
|
||||
|
||||
const msg2 = messages[1]
|
||||
t.equal(msg2.msg, 'grandchild stream')
|
||||
t.equal(msg2.child, 'one')
|
||||
t.equal(msg2.grandchild, 'two')
|
||||
|
||||
const msg3 = messages[2]
|
||||
t.equal(msg3.msg, 'debug grandchild')
|
||||
t.equal(msg3.child, 'one')
|
||||
t.equal(msg3.grandchild, 'two')
|
||||
|
||||
t.end()
|
||||
}
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'debug', stream }
|
||||
]
|
||||
const log = pino({
|
||||
level: 'debug'
|
||||
}, multistream(streams)).child({ child: 'one' }).child({ grandchild: 'two' })
|
||||
log.info('grandchild stream')
|
||||
log.debug('debug grandchild')
|
||||
})
|
||||
|
||||
test('supports custom levels', function (t) {
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
t.equal(JSON.parse(data).msg, 'bar')
|
||||
t.end()
|
||||
})
|
||||
const log = pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}, multistream([{ level: 35, stream }]))
|
||||
log.foo('bar')
|
||||
})
|
||||
|
||||
test('supports pretty print', function (t) {
|
||||
t.plan(2)
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
t.not(strip(data.toString()).match(/INFO.*: pretty print/), null)
|
||||
cb()
|
||||
})
|
||||
|
||||
const safeBoom = proxyquire('pino-pretty/lib/utils/build-safe-sonic-boom.js', {
|
||||
'sonic-boom': function () {
|
||||
t.pass('sonic created')
|
||||
stream.flushSync = () => {}
|
||||
stream.flush = () => {}
|
||||
return stream
|
||||
}
|
||||
})
|
||||
const nested = proxyquire('pino-pretty/lib/utils/index.js', {
|
||||
'./build-safe-sonic-boom.js': safeBoom
|
||||
})
|
||||
const pretty = proxyquire('pino-pretty', {
|
||||
'./lib/utils/index.js': nested
|
||||
})
|
||||
|
||||
const log = pino({
|
||||
level: 'debug',
|
||||
name: 'helloName'
|
||||
}, multistream([
|
||||
{ stream: pretty() }
|
||||
]))
|
||||
|
||||
log.info('pretty print')
|
||||
})
|
||||
|
||||
test('emit propagates events to each stream', function (t) {
|
||||
t.plan(3)
|
||||
const handler = function (data) {
|
||||
t.equal(data.msg, 'world')
|
||||
}
|
||||
const streams = [sink(), sink(), sink()]
|
||||
streams.forEach(function (s) {
|
||||
s.once('hello', handler)
|
||||
})
|
||||
const stream = multistream(streams)
|
||||
stream.emit('hello', { msg: 'world' })
|
||||
})
|
||||
|
||||
test('children support custom levels', function (t) {
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
t.equal(JSON.parse(data).msg, 'bar')
|
||||
t.end()
|
||||
})
|
||||
const parent = pino({
|
||||
customLevels: {
|
||||
foo: 35
|
||||
}
|
||||
}, multistream([{ level: 35, stream }]))
|
||||
const child = parent.child({ child: 'yes' })
|
||||
child.foo('bar')
|
||||
})
|
||||
|
||||
test('levelVal overrides level', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'blabla', levelVal: 15, stream },
|
||||
{ level: 60, stream }
|
||||
]
|
||||
const log = pino({
|
||||
level: 'debug'
|
||||
}, multistream(streams))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 6)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('forwards metadata', function (t) {
|
||||
t.plan(4)
|
||||
const streams = [
|
||||
{
|
||||
stream: {
|
||||
[Symbol.for('pino.metadata')]: true,
|
||||
write (chunk) {
|
||||
t.equal(log, this.lastLogger)
|
||||
t.equal(30, this.lastLevel)
|
||||
t.same({ hello: 'world' }, this.lastObj)
|
||||
t.same('a msg', this.lastMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const log = pino({
|
||||
level: 'debug'
|
||||
}, multistream(streams))
|
||||
|
||||
log.info({ hello: 'world' }, 'a msg')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('forward name', function (t) {
|
||||
t.plan(2)
|
||||
const streams = [
|
||||
{
|
||||
stream: {
|
||||
[Symbol.for('pino.metadata')]: true,
|
||||
write (chunk) {
|
||||
const line = JSON.parse(chunk)
|
||||
t.equal(line.name, 'helloName')
|
||||
t.equal(line.hello, 'world')
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const log = pino({
|
||||
level: 'debug',
|
||||
name: 'helloName'
|
||||
}, multistream(streams))
|
||||
|
||||
log.info({ hello: 'world' }, 'a msg')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('forward name with child', function (t) {
|
||||
t.plan(3)
|
||||
const streams = [
|
||||
{
|
||||
stream: {
|
||||
write (chunk) {
|
||||
const line = JSON.parse(chunk)
|
||||
t.equal(line.name, 'helloName')
|
||||
t.equal(line.hello, 'world')
|
||||
t.equal(line.component, 'aComponent')
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const log = pino({
|
||||
level: 'debug',
|
||||
name: 'helloName'
|
||||
}, multistream(streams)).child({ component: 'aComponent' })
|
||||
|
||||
log.info({ hello: 'world' }, 'a msg')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('clone generates a new multistream with all stream at the same level', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'debug', stream },
|
||||
{ level: 'trace', stream },
|
||||
{ level: 'fatal', stream }
|
||||
]
|
||||
const ms = multistream(streams)
|
||||
const clone = ms.clone(30)
|
||||
|
||||
t.not(clone, ms)
|
||||
|
||||
clone.streams.forEach((s, i) => {
|
||||
t.not(s, streams[i])
|
||||
t.equal(s.stream, streams[i].stream)
|
||||
t.equal(s.level, 30)
|
||||
})
|
||||
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, clone)
|
||||
|
||||
log.info('info stream')
|
||||
log.debug('debug message not counted')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 8)
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('one stream', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream({ stream, level: 'fatal' }))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 1)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('dedupe', function (t) {
|
||||
let messageCount = 0
|
||||
const stream1 = writeStream(function (data, enc, cb) {
|
||||
messageCount -= 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream2 = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const streams = [
|
||||
{
|
||||
stream: stream1,
|
||||
level: 'info'
|
||||
},
|
||||
{
|
||||
stream: stream2,
|
||||
level: 'fatal'
|
||||
}
|
||||
]
|
||||
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream(streams, { dedupe: true }))
|
||||
log.info('info stream')
|
||||
log.fatal('fatal stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 1)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('dedupe when logs have different levels', function (t) {
|
||||
let messageCount = 0
|
||||
const stream1 = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream2 = writeStream(function (data, enc, cb) {
|
||||
messageCount += 2
|
||||
cb()
|
||||
})
|
||||
|
||||
const streams = [
|
||||
{
|
||||
stream: stream1,
|
||||
level: 'info'
|
||||
},
|
||||
{
|
||||
stream: stream2,
|
||||
level: 'error'
|
||||
}
|
||||
]
|
||||
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream(streams, { dedupe: true }))
|
||||
|
||||
log.info('info stream')
|
||||
log.warn('warn stream')
|
||||
log.error('error streams')
|
||||
log.fatal('fatal streams')
|
||||
t.equal(messageCount, 6)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('dedupe when some streams has the same level', function (t) {
|
||||
let messageCount = 0
|
||||
const stream1 = writeStream(function (data, enc, cb) {
|
||||
messageCount -= 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream2 = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream3 = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const streams = [
|
||||
{
|
||||
stream: stream1,
|
||||
level: 'info'
|
||||
},
|
||||
{
|
||||
stream: stream2,
|
||||
level: 'fatal'
|
||||
},
|
||||
{
|
||||
stream: stream3,
|
||||
level: 'fatal'
|
||||
}
|
||||
]
|
||||
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream(streams, { dedupe: true }))
|
||||
log.info('info stream')
|
||||
log.fatal('fatal streams')
|
||||
log.fatal('fatal streams')
|
||||
t.equal(messageCount, 3)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('no stream', function (t) {
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream())
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('one stream', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream(stream))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 2)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('add a stream', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multistream().add(stream))
|
||||
log.info('info stream')
|
||||
log.debug('debug stream')
|
||||
log.fatal('fatal stream')
|
||||
t.equal(messageCount, 2)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('remove a stream', function (t) {
|
||||
let messageCount1 = 0
|
||||
let messageCount2 = 0
|
||||
let messageCount3 = 0
|
||||
|
||||
const stream1 = writeStream(function (data, enc, cb) {
|
||||
messageCount1 += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream2 = writeStream(function (data, enc, cb) {
|
||||
messageCount2 += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const stream3 = writeStream(function (data, enc, cb) {
|
||||
messageCount3 += 1
|
||||
cb()
|
||||
})
|
||||
|
||||
const multi = multistream()
|
||||
const log = pino({ level: 'trace', sync: true }, multi)
|
||||
|
||||
multi.add(stream1)
|
||||
const id1 = multi.lastId
|
||||
|
||||
multi.add(stream2)
|
||||
const id2 = multi.lastId
|
||||
|
||||
multi.add(stream3)
|
||||
const id3 = multi.lastId
|
||||
|
||||
log.info('line')
|
||||
multi.remove(id1)
|
||||
|
||||
log.info('line')
|
||||
multi.remove(id2)
|
||||
|
||||
log.info('line')
|
||||
multi.remove(id3)
|
||||
|
||||
log.info('line')
|
||||
multi.remove(Math.floor(Math.random() * 1000)) // non-existing id
|
||||
|
||||
t.equal(messageCount1, 1)
|
||||
t.equal(messageCount2, 2)
|
||||
t.equal(messageCount3, 3)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('multistream.add throws if not a stream', function (t) {
|
||||
try {
|
||||
pino({
|
||||
level: 'trace'
|
||||
}, multistream().add({}))
|
||||
} catch (_) {
|
||||
t.end()
|
||||
}
|
||||
})
|
||||
|
||||
test('multistream throws if not a stream', function (t) {
|
||||
try {
|
||||
pino({
|
||||
level: 'trace'
|
||||
}, multistream({}))
|
||||
} catch (_) {
|
||||
t.end()
|
||||
}
|
||||
})
|
||||
|
||||
test('multistream.write should not throw if one stream fails', function (t) {
|
||||
let messageCount = 0
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
messageCount += 1
|
||||
cb()
|
||||
})
|
||||
const noopStream = pino.transport({
|
||||
target: join(__dirname, 'fixtures', 'noop-transport.js')
|
||||
})
|
||||
// eslint-disable-next-line
|
||||
noopStream.on('error', function (err) {
|
||||
// something went wrong while writing to noop stream, ignoring!
|
||||
})
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
},
|
||||
multistream([
|
||||
{
|
||||
level: 'trace',
|
||||
stream
|
||||
},
|
||||
{
|
||||
level: 'debug',
|
||||
stream: noopStream
|
||||
}
|
||||
])
|
||||
)
|
||||
log.debug('0')
|
||||
noopStream.end()
|
||||
// noop stream is ending, should emit an error but not throw
|
||||
log.debug('1')
|
||||
log.debug('2')
|
||||
t.equal(messageCount, 3)
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('flushSync', function (t) {
|
||||
const tmp = file()
|
||||
const destination = pino.destination({ dest: tmp, sync: false, minLength: 4096 })
|
||||
const stream = multistream([{ level: 'info', stream: destination }])
|
||||
const log = pino({ level: 'info' }, stream)
|
||||
destination.on('ready', () => {
|
||||
log.info('foo')
|
||||
log.info('bar')
|
||||
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()
|
||||
})
|
||||
})
|
||||
|
||||
test('ends all streams', function (t) {
|
||||
t.plan(7)
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
t.pass('message')
|
||||
cb()
|
||||
})
|
||||
stream.flushSync = function () {
|
||||
t.pass('flushSync')
|
||||
}
|
||||
// stream2 has no flushSync
|
||||
const stream2 = writeStream(function (data, enc, cb) {
|
||||
t.pass('message2')
|
||||
cb()
|
||||
})
|
||||
const streams = [
|
||||
{ stream },
|
||||
{ level: 'debug', stream },
|
||||
{ level: 'trace', stream: stream2 },
|
||||
{ level: 'fatal', stream },
|
||||
{ level: 'silent', stream }
|
||||
]
|
||||
const multi = multistream(streams)
|
||||
const log = pino({
|
||||
level: 'trace'
|
||||
}, multi)
|
||||
log.info('info stream')
|
||||
multi.end()
|
||||
})
|
||||
46
node_modules/pino/test/pkg/index.js
generated
vendored
Normal file
46
node_modules/pino/test/pkg/index.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict'
|
||||
|
||||
const os = require('node:os')
|
||||
const { join } = require('node:path')
|
||||
const { readFile } = require('node:fs').promises
|
||||
const { watchFileCreated, file } = require('../helper')
|
||||
const { test } = require('tap')
|
||||
const pino = require('../../pino')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
/**
|
||||
* This file is packaged using pkg in order to test if transport-stream.js works in that context
|
||||
*/
|
||||
|
||||
test('pino.transport with worker destination overridden by bundler and mjs transport', async ({ same, teardown }) => {
|
||||
globalThis.__bundlerPathsOverrides = {
|
||||
'pino-worker': join(__dirname, '..', '..', 'lib/worker.js')
|
||||
}
|
||||
|
||||
const destination = file()
|
||||
const transport = pino.transport({
|
||||
targets: [
|
||||
{
|
||||
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.es2017.cjs'),
|
||||
options: { destination }
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
teardown(transport.end.bind(transport))
|
||||
const instance = pino(transport)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(destination)
|
||||
const result = JSON.parse(await readFile(destination))
|
||||
delete result.time
|
||||
same(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
|
||||
globalThis.__bundlerPathsOverrides = undefined
|
||||
})
|
||||
16
node_modules/pino/test/pkg/pkg.config.json
generated
vendored
Normal file
16
node_modules/pino/test/pkg/pkg.config.json
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"pkg": {
|
||||
"assets": [
|
||||
"../../lib/worker.js",
|
||||
"../../lib/transport-stream.js",
|
||||
"../../test/fixtures/ts/to-file-transport.es2017.cjs",
|
||||
"../../node_modules/pino-abstract-transport/index.js"
|
||||
],
|
||||
"targets": [
|
||||
"node18",
|
||||
"node20",
|
||||
"node22"
|
||||
],
|
||||
"outputPath": "test/pkg"
|
||||
}
|
||||
}
|
||||
58
node_modules/pino/test/pkg/pkg.test.js
generated
vendored
Normal file
58
node_modules/pino/test/pkg/pkg.test.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const config = require('./pkg.config.json')
|
||||
const { promisify } = require('node:util')
|
||||
const { unlink } = require('node:fs/promises')
|
||||
const { join } = require('node:path')
|
||||
const { platform } = require('node:process')
|
||||
const execFile = promisify(require('node:child_process').execFile)
|
||||
|
||||
const skip = process.env.PNPM_CI || process.env.CITGM || process.arch === 'ppc64'
|
||||
|
||||
/**
|
||||
* The following regex is for tesintg the deprecation warning that is thrown by the `punycode` module.
|
||||
* Exact text that it's matching is:
|
||||
* (node:1234) [DEP0040] DeprecationWarning: The `punycode` module is deprecated.
|
||||
Please use a userland alternative instead.
|
||||
|
||||
(Use `node --trace-deprecation ...` to show where the warning was created)
|
||||
*/
|
||||
const deprecationWarningRegex = /^\(\w+:\d+\)\s\[[\w|\d]+\]\sDeprecationWarning: The `punycode` module is deprecated\.\s+Please use a userland alternative instead\.\s+\(Use `node --trace-deprecation \.\.\.` to show where the warning was created\)\s+$/
|
||||
|
||||
test('worker test when packaged into executable using pkg', { skip }, async (t) => {
|
||||
const packageName = 'index'
|
||||
|
||||
// package the app into several node versions, check config for more info
|
||||
const filePath = `${join(__dirname, packageName)}.js`
|
||||
const configPath = join(__dirname, 'pkg.config.json')
|
||||
const { stderr } = await execFile('npx', ['pkg', filePath, '--config', configPath], { shell: true })
|
||||
|
||||
// there should be no error when packaging
|
||||
const expectedvalue = stderr === '' || deprecationWarningRegex.test(stderr)
|
||||
t.ok(expectedvalue)
|
||||
|
||||
// pkg outputs files in the following format by default: {filename}-{node version}
|
||||
for (const target of config.pkg.targets) {
|
||||
// execute the packaged test
|
||||
let executablePath = `${join(config.pkg.outputPath, packageName)}-${target}`
|
||||
|
||||
// when on windows, we need the .exe extension
|
||||
if (platform === 'win32') {
|
||||
executablePath = `${executablePath}.exe`
|
||||
} else {
|
||||
executablePath = `./${executablePath}`
|
||||
}
|
||||
|
||||
const { stderr } = await execFile(executablePath)
|
||||
|
||||
// check if there were no errors
|
||||
const expectedvalue = stderr === '' || deprecationWarningRegex.test(stderr)
|
||||
t.ok(expectedvalue)
|
||||
|
||||
// clean up afterwards
|
||||
await unlink(executablePath)
|
||||
}
|
||||
|
||||
t.end()
|
||||
})
|
||||
847
node_modules/pino/test/redact.test.js
generated
vendored
Normal file
847
node_modules/pino/test/redact.test.js
generated
vendored
Normal file
@@ -0,0 +1,847 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
test('redact option – throws if not array', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({ redact: 'req.headers.cookie' })
|
||||
})
|
||||
})
|
||||
|
||||
test('redact option – throws if array does not only contain strings', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({ redact: ['req.headers.cookie', {}] })
|
||||
})
|
||||
})
|
||||
|
||||
test('redact option – throws if array contains an invalid path', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({ redact: ['req,headers.cookie'] })
|
||||
})
|
||||
})
|
||||
|
||||
test('redact.paths option – throws if not array', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({ redact: { paths: 'req.headers.cookie' } })
|
||||
})
|
||||
})
|
||||
|
||||
test('redact.paths option – throws if array does not only contain strings', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({ redact: { paths: ['req.headers.cookie', {}] } })
|
||||
})
|
||||
})
|
||||
|
||||
test('redact.paths option – throws if array contains an invalid path', async ({ throws }) => {
|
||||
throws(() => {
|
||||
pino({ redact: { paths: ['req,headers.cookie'] } })
|
||||
})
|
||||
})
|
||||
|
||||
test('redact option – top level key', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['key'] }, stream)
|
||||
instance.info({
|
||||
key: { redact: 'me' }
|
||||
})
|
||||
const { key } = await once(stream, 'data')
|
||||
equal(key, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact option – top level key next level key', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['key', 'key.foo'] }, stream)
|
||||
instance.info({
|
||||
key: { redact: 'me' }
|
||||
})
|
||||
const { key } = await once(stream, 'data')
|
||||
equal(key, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact option – next level key then top level key', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['key.foo', 'key'] }, stream)
|
||||
instance.info({
|
||||
key: { redact: 'me' }
|
||||
})
|
||||
const { key } = await once(stream, 'data')
|
||||
equal(key, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact option – object', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact option – child object', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
|
||||
instance.child({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
}).info('message completed')
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact option – interpolated object', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
|
||||
|
||||
instance.info('test %j', {
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(JSON.parse(msg.replace(/test /, '')).req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact.paths option – object', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact.paths option – child object', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
|
||||
instance.child({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
}).info('message completed')
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact.paths option – interpolated object', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
|
||||
|
||||
instance.info('test %j', {
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { msg } = await once(stream, 'data')
|
||||
equal(JSON.parse(msg.replace(/test /, '')).req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact.censor option – sets the redact value', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: 'test' } }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, 'test')
|
||||
})
|
||||
|
||||
test('redact.censor option – can be a function that accepts value and path arguments', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['topLevel'], censor: (value, path) => value + ' ' + path.join('.') } }, stream)
|
||||
instance.info({
|
||||
topLevel: 'test'
|
||||
})
|
||||
const { topLevel } = await once(stream, 'data')
|
||||
equal(topLevel, 'test topLevel')
|
||||
})
|
||||
|
||||
test('redact.censor option – can be a function that accepts value and path arguments (nested path)', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: (value, path) => value + ' ' + path.join('.') } }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1; req.headers.cookie')
|
||||
})
|
||||
|
||||
test('redact.remove option – removes both key and value', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'], remove: true } }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal('cookie' in req.headers, false)
|
||||
})
|
||||
|
||||
test('redact.remove – top level key - object value', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
|
||||
instance.info({
|
||||
key: { redact: 'me' }
|
||||
})
|
||||
const o = await once(stream, 'data')
|
||||
equal('key' in o, false)
|
||||
})
|
||||
|
||||
test('redact.remove – top level key - number value', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
|
||||
instance.info({
|
||||
key: 1
|
||||
})
|
||||
const o = await once(stream, 'data')
|
||||
equal('key' in o, false)
|
||||
})
|
||||
|
||||
test('redact.remove – top level key - boolean value', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['key'], remove: true } }, stream)
|
||||
instance.info({
|
||||
key: false
|
||||
})
|
||||
const o = await once(stream, 'data')
|
||||
equal('key' in o, false)
|
||||
})
|
||||
|
||||
test('redact.remove – top level key in child logger', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const opts = { redact: { paths: ['key'], remove: true } }
|
||||
const instance = pino(opts, stream).child({ key: { redact: 'me' } })
|
||||
instance.info('test')
|
||||
const o = await once(stream, 'data')
|
||||
equal('key' in o, false)
|
||||
})
|
||||
|
||||
test('redact.paths preserves original object values after the log write', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.headers.cookie'] }, stream)
|
||||
const obj = {
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.req.headers.cookie, '[Redacted]')
|
||||
equal(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
|
||||
})
|
||||
|
||||
test('redact.paths preserves original object values after the log write', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'] } }, stream)
|
||||
const obj = {
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.req.headers.cookie, '[Redacted]')
|
||||
equal(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
|
||||
})
|
||||
|
||||
test('redact.censor preserves original object values after the log write', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'], censor: 'test' } }, stream)
|
||||
const obj = {
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.req.headers.cookie, 'test')
|
||||
equal(obj.req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
|
||||
})
|
||||
|
||||
test('redact.remove preserves original object values after the log write', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['req.headers.cookie'], remove: true } }, stream)
|
||||
const obj = {
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal('cookie' in o.req.headers, false)
|
||||
equal('cookie' in obj.req.headers, true)
|
||||
})
|
||||
|
||||
test('redact – supports last position wildcard paths', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.headers.*'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
equal(req.headers.host, '[Redacted]')
|
||||
equal(req.headers.connection, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports first position wildcard paths', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['*.headers'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports first position wildcards before other paths', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['*.headers.cookie', 'req.id'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
equal(req.id, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports first position wildcards after other paths', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.id', '*.headers.cookie'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
equal(req.id, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports first position wildcards after top level keys', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['key', '*.headers.cookie'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports top level wildcard', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['*'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports top level wildcard with a censor function', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({
|
||||
redact: {
|
||||
paths: ['*'],
|
||||
censor: () => '[Redacted]'
|
||||
}
|
||||
}, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports top level wildcard and leading wildcard', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['*', '*.req'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redact – supports intermediate wildcard paths', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.*.cookie'] }, stream)
|
||||
instance.info({
|
||||
req: {
|
||||
id: 7915,
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
host: 'localhost:3000',
|
||||
connection: 'keep-alive',
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
},
|
||||
remoteAddress: '::ffff:127.0.0.1',
|
||||
remotePort: 58022
|
||||
}
|
||||
})
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redacts numbers at the top level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['id'] }, stream)
|
||||
const obj = {
|
||||
id: 7915
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.id, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redacts booleans at the top level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['maybe'] }, stream)
|
||||
const obj = {
|
||||
maybe: true
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.maybe, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redacts strings at the top level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['s'] }, stream)
|
||||
const obj = {
|
||||
s: 's'
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.s, '[Redacted]')
|
||||
})
|
||||
|
||||
test('does not redact primitives if not objects', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['a.b'] }, stream)
|
||||
const obj = {
|
||||
a: 42
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.a, 42)
|
||||
})
|
||||
|
||||
test('redacts null at the top level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['n'] }, stream)
|
||||
const obj = {
|
||||
n: null
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.n, '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports bracket notation', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['a["b.b"]'] }, stream)
|
||||
const obj = {
|
||||
a: { 'b.b': 'c' }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.a['b.b'], '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports bracket notation with further nesting', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['a["b.b"].c'] }, stream)
|
||||
const obj = {
|
||||
a: { 'b.b': { c: 'd' } }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.a['b.b'].c, '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports bracket notation with empty string as path segment', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['a[""].c'] }, stream)
|
||||
const obj = {
|
||||
a: { '': { c: 'd' } }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.a[''].c, '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports leading bracket notation (single quote)', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['[\'a.a\'].b'] }, stream)
|
||||
const obj = {
|
||||
'a.a': { b: 'c' }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o['a.a'].b, '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports leading bracket notation (double quote)', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['["a.a"].b'] }, stream)
|
||||
const obj = {
|
||||
'a.a': { b: 'c' }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o['a.a'].b, '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports leading bracket notation (backtick quote)', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['[`a.a`].b'] }, stream)
|
||||
const obj = {
|
||||
'a.a': { b: 'c' }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o['a.a'].b, '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports leading bracket notation (single-segment path)', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['[`a.a`]'] }, stream)
|
||||
const obj = {
|
||||
'a.a': { b: 'c' }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o['a.a'], '[Redacted]')
|
||||
})
|
||||
|
||||
test('supports leading bracket notation (single-segment path, wildcard)', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['[*]'] }, stream)
|
||||
const obj = {
|
||||
'a.a': { b: 'c' }
|
||||
}
|
||||
instance.info(obj)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o['a.a'], '[Redacted]')
|
||||
})
|
||||
|
||||
test('child bindings are redacted using wildcard path', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['*.headers.cookie'] }, stream)
|
||||
instance.child({
|
||||
req: {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
}
|
||||
}
|
||||
}).info('message completed')
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
})
|
||||
|
||||
test('child bindings are redacted using wildcard and plain path keys', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.method', '*.headers.cookie'] }, stream)
|
||||
instance.child({
|
||||
req: {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
}
|
||||
}
|
||||
}).info('message completed')
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, '[Redacted]')
|
||||
equal(req.method, '[Redacted]')
|
||||
})
|
||||
|
||||
test('redacts boolean at the top level', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['msg'] }, stream)
|
||||
const obj = {
|
||||
s: 's'
|
||||
}
|
||||
instance.info(obj, true)
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.s, 's')
|
||||
equal(o.msg, '[Redacted]')
|
||||
})
|
||||
|
||||
test('child can customize redact', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.method', '*.headers.cookie'] }, stream)
|
||||
instance.child({
|
||||
req: {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
redact: ['req.url']
|
||||
}).info('message completed')
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
|
||||
equal(req.method, 'GET')
|
||||
equal(req.url, '[Redacted]')
|
||||
})
|
||||
|
||||
test('child can remove parent redact by array', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: ['req.method', '*.headers.cookie'] }, stream)
|
||||
instance.child({
|
||||
req: {
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
cookie: 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
redact: []
|
||||
}).info('message completed')
|
||||
const { req } = await once(stream, 'data')
|
||||
equal(req.headers.cookie, 'SESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1;')
|
||||
equal(req.method, 'GET')
|
||||
})
|
||||
|
||||
test('redact safe stringify', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ redact: { paths: ['that.secret'] } }, stream)
|
||||
|
||||
instance.info({
|
||||
that: {
|
||||
secret: 'please hide me',
|
||||
myBigInt: 123n
|
||||
},
|
||||
other: {
|
||||
mySecondBigInt: 222n
|
||||
}
|
||||
})
|
||||
const { that, other } = await once(stream, 'data')
|
||||
equal(that.secret, '[Redacted]')
|
||||
equal(that.myBigInt, 123)
|
||||
equal(other.mySecondBigInt, 222)
|
||||
})
|
||||
253
node_modules/pino/test/serializers.test.js
generated
vendored
Normal file
253
node_modules/pino/test/serializers.test.js
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
'use strict'
|
||||
const { test } = require('tap')
|
||||
const { sink, once } = require('./helper')
|
||||
const stdSerializers = require('pino-std-serializers')
|
||||
const pino = require('../')
|
||||
|
||||
const parentSerializers = {
|
||||
test: () => 'parent'
|
||||
}
|
||||
|
||||
const childSerializers = {
|
||||
test: () => 'child'
|
||||
}
|
||||
|
||||
test('default err namespace error serializer', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino(stream)
|
||||
|
||||
parent.info({ err: ReferenceError('test') })
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o.err, 'object')
|
||||
equal(o.err.type, 'ReferenceError')
|
||||
equal(o.err.message, 'test')
|
||||
equal(typeof o.err.stack, 'string')
|
||||
})
|
||||
|
||||
test('custom serializer overrides default err namespace error serializer', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({
|
||||
serializers: {
|
||||
err: (e) => ({
|
||||
t: e.constructor.name,
|
||||
m: e.message,
|
||||
s: e.stack
|
||||
})
|
||||
}
|
||||
}, stream)
|
||||
|
||||
parent.info({ err: ReferenceError('test') })
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o.err, 'object')
|
||||
equal(o.err.t, 'ReferenceError')
|
||||
equal(o.err.m, 'test')
|
||||
equal(typeof o.err.s, 'string')
|
||||
})
|
||||
|
||||
test('custom serializer overrides default err namespace error serializer when nestedKey is on', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({
|
||||
nestedKey: 'obj',
|
||||
serializers: {
|
||||
err: (e) => {
|
||||
return {
|
||||
t: e.constructor.name,
|
||||
m: e.message,
|
||||
s: e.stack
|
||||
}
|
||||
}
|
||||
}
|
||||
}, stream)
|
||||
|
||||
parent.info({ err: ReferenceError('test') })
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o.obj.err, 'object')
|
||||
equal(o.obj.err.t, 'ReferenceError')
|
||||
equal(o.obj.err.m, 'test')
|
||||
equal(typeof o.obj.err.s, 'string')
|
||||
})
|
||||
|
||||
test('null overrides default err namespace error serializer', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({ serializers: { err: null } }, stream)
|
||||
|
||||
parent.info({ err: ReferenceError('test') })
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o.err, 'object')
|
||||
equal(typeof o.err.type, 'undefined')
|
||||
equal(typeof o.err.message, 'undefined')
|
||||
equal(typeof o.err.stack, 'undefined')
|
||||
})
|
||||
|
||||
test('undefined overrides default err namespace error serializer', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({ serializers: { err: undefined } }, stream)
|
||||
|
||||
parent.info({ err: ReferenceError('test') })
|
||||
const o = await once(stream, 'data')
|
||||
equal(typeof o.err, 'object')
|
||||
equal(typeof o.err.type, 'undefined')
|
||||
equal(typeof o.err.message, 'undefined')
|
||||
equal(typeof o.err.stack, 'undefined')
|
||||
})
|
||||
|
||||
test('serializers override values', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({ serializers: parentSerializers }, stream)
|
||||
parent.child({}, { serializers: childSerializers })
|
||||
|
||||
parent.fatal({ test: 'test' })
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.test, 'parent')
|
||||
})
|
||||
|
||||
test('child does not overwrite parent serializers', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({ serializers: parentSerializers }, stream)
|
||||
const child = parent.child({}, { serializers: childSerializers })
|
||||
|
||||
parent.fatal({ test: 'test' })
|
||||
|
||||
const o = once(stream, 'data')
|
||||
equal((await o).test, 'parent')
|
||||
const o2 = once(stream, 'data')
|
||||
child.fatal({ test: 'test' })
|
||||
equal((await o2).test, 'child')
|
||||
})
|
||||
|
||||
test('Symbol.for(\'pino.serializers\')', async ({ equal, same, not }) => {
|
||||
const stream = sink()
|
||||
const expected = Object.assign({
|
||||
err: stdSerializers.err
|
||||
}, parentSerializers)
|
||||
const parent = pino({ serializers: parentSerializers }, stream)
|
||||
const child = parent.child({ a: 'property' })
|
||||
|
||||
same(parent[Symbol.for('pino.serializers')], expected)
|
||||
same(child[Symbol.for('pino.serializers')], expected)
|
||||
equal(parent[Symbol.for('pino.serializers')], child[Symbol.for('pino.serializers')])
|
||||
|
||||
const child2 = parent.child({}, {
|
||||
serializers: {
|
||||
a
|
||||
}
|
||||
})
|
||||
|
||||
function a () {
|
||||
return 'hello'
|
||||
}
|
||||
|
||||
not(child2[Symbol.for('pino.serializers')], parentSerializers)
|
||||
equal(child2[Symbol.for('pino.serializers')].a, a)
|
||||
equal(child2[Symbol.for('pino.serializers')].test, parentSerializers.test)
|
||||
})
|
||||
|
||||
test('children inherit parent serializers', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({ serializers: parentSerializers }, stream)
|
||||
|
||||
const child = parent.child({ a: 'property' })
|
||||
child.fatal({ test: 'test' })
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.test, 'parent')
|
||||
})
|
||||
|
||||
test('children inherit parent Symbol serializers', async ({ equal, same, not }) => {
|
||||
const stream = sink()
|
||||
const symbolSerializers = {
|
||||
[Symbol.for('b')]: b
|
||||
}
|
||||
const expected = Object.assign({
|
||||
err: stdSerializers.err
|
||||
}, symbolSerializers)
|
||||
const parent = pino({ serializers: symbolSerializers }, stream)
|
||||
|
||||
same(parent[Symbol.for('pino.serializers')], expected)
|
||||
|
||||
const child = parent.child({}, {
|
||||
serializers: {
|
||||
[Symbol.for('a')]: a,
|
||||
a
|
||||
}
|
||||
})
|
||||
|
||||
function a () {
|
||||
return 'hello'
|
||||
}
|
||||
|
||||
function b () {
|
||||
return 'world'
|
||||
}
|
||||
|
||||
same(child[Symbol.for('pino.serializers')].a, a)
|
||||
same(child[Symbol.for('pino.serializers')][Symbol.for('b')], b)
|
||||
same(child[Symbol.for('pino.serializers')][Symbol.for('a')], a)
|
||||
})
|
||||
|
||||
test('children serializers get called', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({
|
||||
test: 'this'
|
||||
}, stream)
|
||||
|
||||
const child = parent.child({ a: 'property' }, { serializers: childSerializers })
|
||||
|
||||
child.fatal({ test: 'test' })
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.test, 'child')
|
||||
})
|
||||
|
||||
test('children serializers get called when inherited from parent', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const parent = pino({
|
||||
test: 'this',
|
||||
serializers: parentSerializers
|
||||
}, stream)
|
||||
|
||||
const child = parent.child({}, { serializers: { test: function () { return 'pass' } } })
|
||||
|
||||
child.fatal({ test: 'fail' })
|
||||
const o = await once(stream, 'data')
|
||||
equal(o.test, 'pass')
|
||||
})
|
||||
|
||||
test('non-overridden serializers are available in the children', async ({ equal }) => {
|
||||
const stream = sink()
|
||||
const pSerializers = {
|
||||
onlyParent: function () { return 'parent' },
|
||||
shared: function () { return 'parent' }
|
||||
}
|
||||
|
||||
const cSerializers = {
|
||||
shared: function () { return 'child' },
|
||||
onlyChild: function () { return 'child' }
|
||||
}
|
||||
|
||||
const parent = pino({ serializers: pSerializers }, stream)
|
||||
|
||||
const child = parent.child({}, { serializers: cSerializers })
|
||||
|
||||
const o = once(stream, 'data')
|
||||
child.fatal({ shared: 'test' })
|
||||
equal((await o).shared, 'child')
|
||||
const o2 = once(stream, 'data')
|
||||
child.fatal({ onlyParent: 'test' })
|
||||
equal((await o2).onlyParent, 'parent')
|
||||
const o3 = once(stream, 'data')
|
||||
child.fatal({ onlyChild: 'test' })
|
||||
equal((await o3).onlyChild, 'child')
|
||||
const o4 = once(stream, 'data')
|
||||
parent.fatal({ onlyChild: 'test' })
|
||||
equal((await o4).onlyChild, 'test')
|
||||
})
|
||||
|
||||
test('custom serializer for messageKey', async (t) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ serializers: { msg: () => '422' } }, stream)
|
||||
|
||||
const o = { num: NaN }
|
||||
instance.info(o, 42)
|
||||
|
||||
const { msg } = await once(stream, 'data')
|
||||
t.equal(msg, '422')
|
||||
})
|
||||
75
node_modules/pino/test/sinon-child-logger.test.js
generated
vendored
Normal file
75
node_modules/pino/test/sinon-child-logger.test.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
const sinon = require('sinon')
|
||||
const pino = require('../')
|
||||
|
||||
test('child logger methods should be independently wrappable with sinon when created with options', () => {
|
||||
// Create parent logger
|
||||
const parent = pino({ level: 'info' }, { write () {} })
|
||||
|
||||
// Wrap parent's info method with sinon
|
||||
sinon.spy(parent, 'info')
|
||||
|
||||
// Create child logger with options (same level)
|
||||
// This triggers the bug: child inherits parent's wrapped method
|
||||
const child = parent.child({ name: 'child' }, { level: 'info' })
|
||||
|
||||
// Try to wrap child's info method - this should NOT throw
|
||||
// In the bug, child.info is the same reference as parent.info (which is already wrapped)
|
||||
assert.doesNotThrow(() => {
|
||||
sinon.spy(child, 'info')
|
||||
}, 'should be able to wrap child logger methods independently')
|
||||
|
||||
// Verify they are different function references
|
||||
assert.strictEqual(child.info === parent.info, false, 'child and parent should have different method references')
|
||||
|
||||
// Cleanup
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
test('child logger info method should be independently wrappable after parent is spied', () => {
|
||||
// This closely mimics the real-world scenario from the bug report
|
||||
const parent = pino({ level: 'info' }, { write () {} })
|
||||
|
||||
// Spy on parent's info method
|
||||
sinon.spy(parent, 'info')
|
||||
|
||||
// Create child with explicit level option (even though it's the same)
|
||||
const child = parent.child({ name: 'child' }, { level: 'info' })
|
||||
|
||||
// Try to spy on child's info method - this should NOT throw
|
||||
assert.doesNotThrow(() => {
|
||||
sinon.spy(child, 'info')
|
||||
}, 'should be able to wrap child info method independently')
|
||||
|
||||
// Verify they are different function references
|
||||
assert.strictEqual(child.info === parent.info, false, 'child and parent should have different info method references')
|
||||
|
||||
// Cleanup
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
test('child logger without explicit level gets own methods when parent is tampered', () => {
|
||||
// When parent methods have been wrapped, child should get its own methods
|
||||
// even without explicit level option to prevent Sinon wrapping errors
|
||||
const parent = pino({ level: 'info' }, { write () {} })
|
||||
|
||||
// Spy on parent's info method (this makes it an own property)
|
||||
sinon.spy(parent, 'info')
|
||||
|
||||
// Create child WITHOUT level option
|
||||
const child = parent.child({ name: 'child' })
|
||||
|
||||
// Child should have different method reference due to tampering detection
|
||||
assert.strictEqual(child.info === parent.info, false, 'child should have own methods when parent is tampered')
|
||||
|
||||
// Should be able to wrap child's method independently
|
||||
assert.doesNotThrow(() => {
|
||||
sinon.spy(child, 'info')
|
||||
}, 'should be able to wrap child method independently')
|
||||
|
||||
// Cleanup
|
||||
sinon.restore()
|
||||
})
|
||||
39
node_modules/pino/test/stdout-protection.test.js
generated
vendored
Normal file
39
node_modules/pino/test/stdout-protection.test.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { join } = require('node:path')
|
||||
const { fork } = require('node:child_process')
|
||||
const { once } = require('./helper')
|
||||
const writer = require('flush-write-stream')
|
||||
const pino = require('..')
|
||||
|
||||
test('do not use SonicBoom is someone tampered with process.stdout.write', async ({ not }) => {
|
||||
let actual = ''
|
||||
const child = fork(join(__dirname, 'fixtures', 'stdout-hack-protection.js'), { silent: true })
|
||||
|
||||
child.stdout.pipe(writer((s, enc, cb) => {
|
||||
actual += s
|
||||
cb()
|
||||
}))
|
||||
await once(child, 'close')
|
||||
not(actual.match(/^hack/), null)
|
||||
})
|
||||
|
||||
test('do not use SonicBoom is someone has passed process.stdout to pino', async ({ equal }) => {
|
||||
const logger = pino(process.stdout)
|
||||
equal(logger[pino.symbols.streamSym], process.stdout)
|
||||
})
|
||||
|
||||
test('do not crash if process.stdout has no fd', async ({ teardown }) => {
|
||||
const fd = process.stdout.fd
|
||||
delete process.stdout.fd
|
||||
teardown(function () { process.stdout.fd = fd })
|
||||
pino()
|
||||
})
|
||||
|
||||
test('use fd=1 if process.stdout has no fd in pino.destination() (worker case)', async ({ teardown }) => {
|
||||
const fd = process.stdout.fd
|
||||
delete process.stdout.fd
|
||||
teardown(function () { process.stdout.fd = fd })
|
||||
pino.destination()
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user