pino-testkit 10.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nojekyll +0 -0
- package/.prettierignore +1 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +30 -0
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/SECURITY.md +87 -0
- package/benchmarks/basic.bench.js +95 -0
- package/benchmarks/child-child.bench.js +52 -0
- package/benchmarks/child-creation.bench.js +73 -0
- package/benchmarks/child.bench.js +62 -0
- package/benchmarks/deep-object.bench.js +88 -0
- package/benchmarks/formatters.bench.js +50 -0
- package/benchmarks/internal/custom-levels.js +67 -0
- package/benchmarks/internal/just-pino-heavy.bench.js +76 -0
- package/benchmarks/internal/just-pino.bench.js +182 -0
- package/benchmarks/internal/parent-vs-child.bench.js +75 -0
- package/benchmarks/internal/redact.bench.js +86 -0
- package/benchmarks/long-string.bench.js +81 -0
- package/benchmarks/multi-arg.bench.js +193 -0
- package/benchmarks/multistream.js +98 -0
- package/benchmarks/object.bench.js +82 -0
- package/benchmarks/utils/generate-benchmark-doc.js +36 -0
- package/benchmarks/utils/runbench.js +138 -0
- package/benchmarks/utils/wrap-log-level.js +55 -0
- package/bin.js +6 -0
- package/browser.js +547 -0
- package/build/sync-version.js +25 -0
- package/docs/api.md +1593 -0
- package/docs/asynchronous.md +40 -0
- package/docs/benchmarks.md +55 -0
- package/docs/browser.md +278 -0
- package/docs/bundling.md +40 -0
- package/docs/child-loggers.md +95 -0
- package/docs/diagnostics.md +16 -0
- package/docs/ecosystem.md +86 -0
- package/docs/help.md +345 -0
- package/docs/lts.md +64 -0
- package/docs/pretty.md +35 -0
- package/docs/redaction.md +135 -0
- package/docs/transports.md +1376 -0
- package/docs/web.md +309 -0
- package/eslint.config.js +28 -0
- package/examples/basic.js +43 -0
- package/examples/transport.js +68 -0
- package/favicon.ico +0 -0
- package/file.js +12 -0
- package/inc-version.sh +42 -0
- package/index.html +55 -0
- package/lib/caller.js +30 -0
- package/lib/constants.js +28 -0
- package/lib/contract.js +8 -0
- package/lib/deprecations.js +8 -0
- package/lib/levels.js +241 -0
- package/lib/meta.js +3 -0
- package/lib/multistream.js +203 -0
- package/lib/proto.js +256 -0
- package/lib/redaction.js +114 -0
- package/lib/symbols.js +74 -0
- package/lib/time.js +39 -0
- package/lib/tools.js +427 -0
- package/lib/transport-stream.js +56 -0
- package/lib/transport.js +289 -0
- package/lib/worker.js +194 -0
- package/package.json +119 -0
- package/pino.d.ts +908 -0
- package/pino.js +240 -0
- package/test/basic.test.js +886 -0
- package/test/broken-pipe.test.js +59 -0
- package/test/browser-child.test.js +132 -0
- package/test/browser-disabled.test.js +87 -0
- package/test/browser-early-console-freeze.test.js +12 -0
- package/test/browser-is-level-enabled.test.js +101 -0
- package/test/browser-levels.test.js +241 -0
- package/test/browser-serializers.test.js +352 -0
- package/test/browser-timestamp.test.js +88 -0
- package/test/browser-transmit.test.js +417 -0
- package/test/browser.test.js +698 -0
- package/test/complex-objects.test.js +36 -0
- package/test/crlf.test.js +34 -0
- package/test/custom-levels.test.js +267 -0
- package/test/diagnostics.test.js +107 -0
- package/test/error-key.test.js +37 -0
- package/test/error.test.js +403 -0
- package/test/escaping.test.js +93 -0
- package/test/esm/esm.mjs +14 -0
- package/test/esm/index.test.js +21 -0
- package/test/esm/named-exports.mjs +29 -0
- package/test/exit.test.js +79 -0
- package/test/fixtures/broken-pipe/basic.js +9 -0
- package/test/fixtures/broken-pipe/destination.js +10 -0
- package/test/fixtures/broken-pipe/syncfalse.js +12 -0
- package/test/fixtures/console-transport.js +13 -0
- package/test/fixtures/crashing-transport.js +13 -0
- package/test/fixtures/default-exit.js +8 -0
- package/test/fixtures/destination-exit.js +8 -0
- package/test/fixtures/eval/index.js +13 -0
- package/test/fixtures/eval/node_modules/14-files.js +3 -0
- package/test/fixtures/eval/node_modules/2-files.js +3 -0
- package/test/fixtures/eval/node_modules/file1.js +5 -0
- package/test/fixtures/eval/node_modules/file10.js +5 -0
- package/test/fixtures/eval/node_modules/file11.js +5 -0
- package/test/fixtures/eval/node_modules/file12.js +5 -0
- package/test/fixtures/eval/node_modules/file13.js +5 -0
- package/test/fixtures/eval/node_modules/file14.js +11 -0
- package/test/fixtures/eval/node_modules/file2.js +5 -0
- package/test/fixtures/eval/node_modules/file3.js +5 -0
- package/test/fixtures/eval/node_modules/file4.js +5 -0
- package/test/fixtures/eval/node_modules/file5.js +5 -0
- package/test/fixtures/eval/node_modules/file6.js +5 -0
- package/test/fixtures/eval/node_modules/file7.js +5 -0
- package/test/fixtures/eval/node_modules/file8.js +5 -0
- package/test/fixtures/eval/node_modules/file9.js +5 -0
- package/test/fixtures/noop-transport.js +10 -0
- package/test/fixtures/pretty/null-prototype.js +8 -0
- package/test/fixtures/stdout-hack-protection.js +11 -0
- package/test/fixtures/syncfalse-child.js +6 -0
- package/test/fixtures/syncfalse-exit.js +9 -0
- package/test/fixtures/syncfalse-flush-exit.js +10 -0
- package/test/fixtures/syncfalse.js +6 -0
- package/test/fixtures/syntax-error-esm.mjs +2 -0
- package/test/fixtures/to-file-transport-with-transform.js +20 -0
- package/test/fixtures/to-file-transport.js +13 -0
- package/test/fixtures/to-file-transport.mjs +8 -0
- package/test/fixtures/transport/index.js +12 -0
- package/test/fixtures/transport/package.json +5 -0
- package/test/fixtures/transport-exit-immediately-with-async-dest.js +16 -0
- package/test/fixtures/transport-exit-immediately.js +11 -0
- package/test/fixtures/transport-exit-on-ready.js +12 -0
- package/test/fixtures/transport-invalid-node-options.js +26 -0
- package/test/fixtures/transport-main.js +9 -0
- package/test/fixtures/transport-many-lines.js +29 -0
- package/test/fixtures/transport-preload-main.mjs +13 -0
- package/test/fixtures/transport-preload.mjs +13 -0
- package/test/fixtures/transport-string-stdout.js +9 -0
- package/test/fixtures/transport-transform.js +21 -0
- package/test/fixtures/transport-uses-pino-config.js +33 -0
- package/test/fixtures/transport-with-on-exit.js +12 -0
- package/test/fixtures/transport-worker-data.js +19 -0
- package/test/fixtures/transport-worker-name.js +24 -0
- package/test/fixtures/transport-worker.js +15 -0
- package/test/fixtures/transport-wrong-export-type.js +3 -0
- package/test/fixtures/ts/to-file-transport-native.mts +15 -0
- package/test/fixtures/ts/to-file-transport-with-transform.ts +18 -0
- package/test/fixtures/ts/to-file-transport.ts +11 -0
- package/test/fixtures/ts/transpile.cjs +36 -0
- package/test/fixtures/ts/transport-exit-immediately-with-async-dest.ts +15 -0
- package/test/fixtures/ts/transport-exit-immediately.ts +10 -0
- package/test/fixtures/ts/transport-exit-on-ready.ts +11 -0
- package/test/fixtures/ts/transport-main.ts +8 -0
- package/test/fixtures/ts/transport-string-stdout.ts +8 -0
- package/test/fixtures/ts/transport-worker.ts +14 -0
- package/test/formatters.test.js +364 -0
- package/test/helper.d.ts +4 -0
- package/test/helper.js +155 -0
- package/test/hooks.test.js +114 -0
- package/test/http.test.js +214 -0
- package/test/internals/version.test.js +17 -0
- package/test/is-level-enabled.test.js +179 -0
- package/test/jest/basic.spec.js +10 -0
- package/test/levels.test.js +810 -0
- package/test/metadata.test.js +120 -0
- package/test/mixin-merge-strategy.test.js +57 -0
- package/test/mixin.test.js +241 -0
- package/test/multistream.test.js +729 -0
- package/test/redact.test.js +893 -0
- package/test/serializers.test.js +257 -0
- package/test/stdout-protection.test.js +41 -0
- package/test/syncfalse.test.js +186 -0
- package/test/timestamp-nano.test.js +37 -0
- package/test/timestamp.test.js +124 -0
- package/test/transport/big.test.js +42 -0
- package/test/transport/bundlers-support.test.js +99 -0
- package/test/transport/caller.test.js +24 -0
- package/test/transport/core.test.js +733 -0
- package/test/transport/core.transpiled.test.ts +114 -0
- package/test/transport/crash.test.js +36 -0
- package/test/transport/module-link.test.js +241 -0
- package/test/transport/native-type-stripping.test.mjs +151 -0
- package/test/transport/node-options.test.js +116 -0
- package/test/transport/pipeline.test.js +137 -0
- package/test/transport/preload.test.js +54 -0
- package/test/transport/repl.test.js +15 -0
- package/test/transport/sync-false.test.js +67 -0
- package/test/transport/sync-true.test.js +57 -0
- package/test/transport/targets.test.js +48 -0
- package/test/transport/uses-pino-config.test.js +166 -0
- package/test/transport-stream.test.js +40 -0
- package/test/types/pino-import.test-d.cts +30 -0
- package/test/types/pino-multistream.test-d.ts +28 -0
- package/test/types/pino-top-export.test-d.ts +34 -0
- package/test/types/pino-transport.test-d.ts +156 -0
- package/test/types/pino-type-only.test-d.ts +75 -0
- package/test/types/pino.test-d.ts +683 -0
- package/test/types/pino.ts +91 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http'
|
|
2
|
+
import { mock } from 'node:test'
|
|
3
|
+
import { Socket } from 'net'
|
|
4
|
+
import { expectError, expectType } from 'tsd'
|
|
5
|
+
import pino, { LogFn, LoggerOptions } from '../../'
|
|
6
|
+
import Logger = pino.Logger
|
|
7
|
+
|
|
8
|
+
const log = pino()
|
|
9
|
+
const info = log.info
|
|
10
|
+
const error = log.error
|
|
11
|
+
|
|
12
|
+
info('hello world')
|
|
13
|
+
error('this is at error level')
|
|
14
|
+
|
|
15
|
+
// primitive types
|
|
16
|
+
info('simple string')
|
|
17
|
+
info(true)
|
|
18
|
+
info(42)
|
|
19
|
+
info(3.14)
|
|
20
|
+
info(null)
|
|
21
|
+
info(undefined)
|
|
22
|
+
|
|
23
|
+
// object types
|
|
24
|
+
info({ a: 1, b: '2' })
|
|
25
|
+
info(new Error())
|
|
26
|
+
info(new Date())
|
|
27
|
+
info([])
|
|
28
|
+
info(new Map())
|
|
29
|
+
info(new Set())
|
|
30
|
+
|
|
31
|
+
// placeholder messages
|
|
32
|
+
info('Hello %s', 'world')
|
|
33
|
+
info('The answer is %d', 42)
|
|
34
|
+
info('The object is %o', { a: 1, b: '2' })
|
|
35
|
+
info('The json is %j', { a: 1, b: '2' })
|
|
36
|
+
info('The object is %O', { a: 1, b: '2' })
|
|
37
|
+
info('The answer is %d and the question is %s with %o', 42, 'unknown', {
|
|
38
|
+
correct: 'order',
|
|
39
|
+
})
|
|
40
|
+
info('Missing placeholder is fine %s')
|
|
41
|
+
|
|
42
|
+
// %s placeholder supports all primitive types
|
|
43
|
+
info('Boolean %s', true)
|
|
44
|
+
info('Boolean %s', false)
|
|
45
|
+
info('Number %s', 123)
|
|
46
|
+
info('Number %s', 3.14)
|
|
47
|
+
info('BigInt %s', BigInt(123))
|
|
48
|
+
info('Null %s', null)
|
|
49
|
+
info('Undefined %s', undefined)
|
|
50
|
+
info('Symbol %s', Symbol('test'))
|
|
51
|
+
info('String %s', 'hello')
|
|
52
|
+
|
|
53
|
+
// %s placeholder with multiple primitives
|
|
54
|
+
info('Multiple primitives %s %s %s', true, 42, 'world')
|
|
55
|
+
info(
|
|
56
|
+
'All primitive types %s %s %s %s %s %s %s',
|
|
57
|
+
'string',
|
|
58
|
+
123,
|
|
59
|
+
true,
|
|
60
|
+
BigInt(123),
|
|
61
|
+
null,
|
|
62
|
+
undefined,
|
|
63
|
+
Symbol('test')
|
|
64
|
+
)
|
|
65
|
+
declare const errorOrString: string | Error
|
|
66
|
+
info(errorOrString)
|
|
67
|
+
|
|
68
|
+
// %o placeholder supports primitives too (except undefined)
|
|
69
|
+
info('Boolean %o', true)
|
|
70
|
+
info('Boolean %o', false)
|
|
71
|
+
info('Number %o', 123)
|
|
72
|
+
info('Number %o', 3.14)
|
|
73
|
+
info('BigInt %o', BigInt(123))
|
|
74
|
+
info('Null %o', null)
|
|
75
|
+
info('Symbol %o', Symbol('test'))
|
|
76
|
+
info('String %o', 'hello')
|
|
77
|
+
|
|
78
|
+
// placeholder messages type errors
|
|
79
|
+
expectError(info('The answer is %d', 'not a number'))
|
|
80
|
+
expectError(
|
|
81
|
+
info(
|
|
82
|
+
'The answer is %d and the question is %s with %o',
|
|
83
|
+
'unknown',
|
|
84
|
+
{ incorrect: 'order' },
|
|
85
|
+
42
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
expectError(info('Extra message %s', 'after placeholder', 'not allowed'))
|
|
89
|
+
|
|
90
|
+
// object types with messages
|
|
91
|
+
info({ obj: 42 }, 'hello world')
|
|
92
|
+
info({ obj: 42, b: 2 }, 'hello world')
|
|
93
|
+
info({ obj: { aa: 'bbb' } }, 'another')
|
|
94
|
+
info({ a: 1, b: '2' }, 'hello world with %s', 'extra data')
|
|
95
|
+
|
|
96
|
+
// Extra message after placeholder
|
|
97
|
+
expectError(info({ a: 1, b: '2' }, 'hello world with %d', 2, 'extra'))
|
|
98
|
+
|
|
99
|
+
// metadata with messages type passes, because of custom toString method
|
|
100
|
+
// We can't detect if the object has a custom toString method that returns a string
|
|
101
|
+
info({ a: 1, b: '2' }, 'hello world with %s', {})
|
|
102
|
+
|
|
103
|
+
// metadata after message
|
|
104
|
+
expectError(info('message', { a: 1, b: '2' }))
|
|
105
|
+
|
|
106
|
+
// multiple strings without placeholder
|
|
107
|
+
expectError(info('string1', 'string2'))
|
|
108
|
+
expectError(info('string1', 'string2', 'string3'))
|
|
109
|
+
|
|
110
|
+
setImmediate(info, 'after setImmediate')
|
|
111
|
+
error(new Error('an error'))
|
|
112
|
+
|
|
113
|
+
const writeSym = pino.symbols.writeSym
|
|
114
|
+
|
|
115
|
+
const testUniqSymbol = {
|
|
116
|
+
[pino.symbols.needsMetadataGsym]: true,
|
|
117
|
+
}[pino.symbols.needsMetadataGsym]
|
|
118
|
+
|
|
119
|
+
const log2: pino.Logger = pino({
|
|
120
|
+
name: 'myapp',
|
|
121
|
+
safe: true,
|
|
122
|
+
serializers: {
|
|
123
|
+
req: pino.stdSerializers.req,
|
|
124
|
+
res: pino.stdSerializers.res,
|
|
125
|
+
err: pino.stdSerializers.err,
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
pino({
|
|
130
|
+
write (o) {},
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
pino({
|
|
134
|
+
mixin () {
|
|
135
|
+
return { customName: 'unknown', customId: 111 }
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
pino({
|
|
140
|
+
mixin: () => ({ customName: 'unknown', customId: 111 }),
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
pino({
|
|
144
|
+
mixin: (context: object) => ({ customName: 'unknown', customId: 111 }),
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
pino({
|
|
148
|
+
mixin: (context: object, level: number) => ({
|
|
149
|
+
customName: 'unknown',
|
|
150
|
+
customId: 111,
|
|
151
|
+
}),
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
pino({
|
|
155
|
+
redact: { paths: [], censor: 'SECRET' },
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
pino({
|
|
159
|
+
redact: { paths: [], censor: () => 'SECRET' },
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
pino({
|
|
163
|
+
redact: { paths: [], censor: (value) => value },
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
pino({
|
|
167
|
+
redact: { paths: [], censor: (value, path) => path.join() },
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
pino({
|
|
171
|
+
redact: {
|
|
172
|
+
paths: [],
|
|
173
|
+
censor: (value): string => 'SECRET',
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
expectError(
|
|
178
|
+
pino({
|
|
179
|
+
redact: { paths: [], censor: (value: string) => value },
|
|
180
|
+
})
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
pino({
|
|
184
|
+
depthLimit: 1,
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
pino({
|
|
188
|
+
edgeLimit: 1,
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
pino({
|
|
192
|
+
browser: {
|
|
193
|
+
write (o) {},
|
|
194
|
+
},
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
pino({
|
|
198
|
+
browser: {
|
|
199
|
+
write: {
|
|
200
|
+
info (o) {},
|
|
201
|
+
error (o) {},
|
|
202
|
+
},
|
|
203
|
+
serialize: true,
|
|
204
|
+
asObject: true,
|
|
205
|
+
transmit: {
|
|
206
|
+
level: 'fatal',
|
|
207
|
+
send: (level, logEvent) => {
|
|
208
|
+
level
|
|
209
|
+
logEvent.bindings
|
|
210
|
+
logEvent.level
|
|
211
|
+
logEvent.ts
|
|
212
|
+
logEvent.messages
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
disabled: false,
|
|
216
|
+
},
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
pino({
|
|
220
|
+
browser: {
|
|
221
|
+
asObjectBindingsOnly: true,
|
|
222
|
+
},
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
pino({}, undefined)
|
|
226
|
+
|
|
227
|
+
pino({ base: null })
|
|
228
|
+
if ('pino' in log) console.log(`pino version: ${log.pino}`)
|
|
229
|
+
|
|
230
|
+
expectType<void>(log.flush())
|
|
231
|
+
log.flush((err?: Error) => undefined)
|
|
232
|
+
log.child({ a: 'property' }).info('hello child!')
|
|
233
|
+
log.level = 'error'
|
|
234
|
+
log.info('nope')
|
|
235
|
+
const child = log.child({ foo: 'bar' })
|
|
236
|
+
child.info('nope again')
|
|
237
|
+
child.level = 'info'
|
|
238
|
+
child.info('hooray')
|
|
239
|
+
log.info('nope nope nope')
|
|
240
|
+
log.child({ foo: 'bar' }, { level: 'debug' }).debug('debug!')
|
|
241
|
+
child.bindings()
|
|
242
|
+
const customSerializers = {
|
|
243
|
+
test () {
|
|
244
|
+
return 'this is my serializer'
|
|
245
|
+
},
|
|
246
|
+
}
|
|
247
|
+
pino()
|
|
248
|
+
.child({}, { serializers: customSerializers })
|
|
249
|
+
.info({ test: 'should not show up' })
|
|
250
|
+
const child2 = log.child({ father: true })
|
|
251
|
+
const childChild = child2.child({ baby: true })
|
|
252
|
+
const childRedacted = pino().child({}, { redact: ['path'] })
|
|
253
|
+
childRedacted.info({
|
|
254
|
+
msg: 'logged with redacted properties',
|
|
255
|
+
path: 'Not shown',
|
|
256
|
+
})
|
|
257
|
+
const childAnotherRedacted = pino().child(
|
|
258
|
+
{},
|
|
259
|
+
{
|
|
260
|
+
redact: {
|
|
261
|
+
paths: ['anotherPath'],
|
|
262
|
+
censor: 'Not the log you\re looking for',
|
|
263
|
+
},
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
childAnotherRedacted.info({
|
|
267
|
+
msg: 'another logged with redacted properties',
|
|
268
|
+
anotherPath: 'Not shown',
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
log.level = 'info'
|
|
272
|
+
if (log.levelVal === 30) {
|
|
273
|
+
console.log('logger level is `info`')
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const listener = (lvl: any, val: any, prevLvl: any, prevVal: any) => {
|
|
277
|
+
console.log(lvl, val, prevLvl, prevVal)
|
|
278
|
+
}
|
|
279
|
+
log.on('level-change', (lvl, val, prevLvl, prevVal, logger) => {
|
|
280
|
+
console.log(lvl, val, prevLvl, prevVal)
|
|
281
|
+
})
|
|
282
|
+
log.level = 'trace'
|
|
283
|
+
log.removeListener('level-change', listener)
|
|
284
|
+
log.level = 'info'
|
|
285
|
+
|
|
286
|
+
pino.levels.values.error === 50
|
|
287
|
+
pino.levels.labels[50] === 'error'
|
|
288
|
+
|
|
289
|
+
const logstderr: pino.Logger = pino(process.stderr)
|
|
290
|
+
logstderr.error('on stderr instead of stdout')
|
|
291
|
+
|
|
292
|
+
log.useLevelLabels = true
|
|
293
|
+
log.info('lol')
|
|
294
|
+
log.level === 'info'
|
|
295
|
+
const isEnabled: boolean = log.isLevelEnabled('info')
|
|
296
|
+
|
|
297
|
+
const redacted = pino({
|
|
298
|
+
redact: ['path'],
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
redacted.info({
|
|
302
|
+
msg: 'logged with redacted properties',
|
|
303
|
+
path: 'Not shown',
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
const anotherRedacted = pino({
|
|
307
|
+
redact: {
|
|
308
|
+
paths: ['anotherPath'],
|
|
309
|
+
censor: 'Not the log you\re looking for',
|
|
310
|
+
},
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
anotherRedacted.info({
|
|
314
|
+
msg: 'another logged with redacted properties',
|
|
315
|
+
anotherPath: 'Not shown',
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
const withTimeFn = pino({
|
|
319
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
const withRFC3339TimeFn = pino({
|
|
323
|
+
timestamp: pino.stdTimeFunctions.isoTimeNano,
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
const withNestedKey = pino({
|
|
327
|
+
nestedKey: 'payload',
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
const withHooks = pino({
|
|
331
|
+
hooks: {
|
|
332
|
+
logMethod (args, method, level) {
|
|
333
|
+
expectType<pino.Logger>(this)
|
|
334
|
+
return method.apply(this, args)
|
|
335
|
+
},
|
|
336
|
+
streamWrite (s) {
|
|
337
|
+
expectType<string>(s)
|
|
338
|
+
return s.replaceAll('secret-key', 'xxx')
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
// Properties/types imported from pino-std-serializers
|
|
344
|
+
const wrappedErrSerializer = pino.stdSerializers.wrapErrorSerializer(
|
|
345
|
+
(err: pino.SerializedError) => {
|
|
346
|
+
return { ...err, newProp: 'foo' }
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
const wrappedReqSerializer = pino.stdSerializers.wrapRequestSerializer(
|
|
350
|
+
(req: pino.SerializedRequest) => {
|
|
351
|
+
return { ...req, newProp: 'foo' }
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
const wrappedResSerializer = pino.stdSerializers.wrapResponseSerializer(
|
|
355
|
+
(res: pino.SerializedResponse) => {
|
|
356
|
+
return { ...res, newProp: 'foo' }
|
|
357
|
+
}
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
const socket = new Socket()
|
|
361
|
+
const incomingMessage = new IncomingMessage(socket)
|
|
362
|
+
const serverResponse = new ServerResponse(incomingMessage)
|
|
363
|
+
|
|
364
|
+
const mappedHttpRequest: { req: pino.SerializedRequest } =
|
|
365
|
+
pino.stdSerializers.mapHttpRequest(incomingMessage)
|
|
366
|
+
const mappedHttpResponse: { res: pino.SerializedResponse } =
|
|
367
|
+
pino.stdSerializers.mapHttpResponse(serverResponse)
|
|
368
|
+
|
|
369
|
+
const serializedErr: pino.SerializedError = pino.stdSerializers.err(
|
|
370
|
+
new Error()
|
|
371
|
+
)
|
|
372
|
+
const serializedReq: pino.SerializedRequest =
|
|
373
|
+
pino.stdSerializers.req(incomingMessage)
|
|
374
|
+
const serializedRes: pino.SerializedResponse =
|
|
375
|
+
pino.stdSerializers.res(serverResponse)
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Destination static method
|
|
379
|
+
*/
|
|
380
|
+
const destinationViaDefaultArgs = pino.destination()
|
|
381
|
+
const destinationViaStrFileDescriptor = pino.destination('/log/path')
|
|
382
|
+
const destinationViaNumFileDescriptor = pino.destination(2)
|
|
383
|
+
const destinationViaStream = pino.destination(process.stdout)
|
|
384
|
+
const destinationViaOptionsObject = pino.destination({
|
|
385
|
+
dest: '/log/path',
|
|
386
|
+
sync: false,
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
pino(destinationViaDefaultArgs)
|
|
390
|
+
pino({ name: 'my-logger' }, destinationViaDefaultArgs)
|
|
391
|
+
pino(destinationViaStrFileDescriptor)
|
|
392
|
+
pino({ name: 'my-logger' }, destinationViaStrFileDescriptor)
|
|
393
|
+
pino(destinationViaNumFileDescriptor)
|
|
394
|
+
pino({ name: 'my-logger' }, destinationViaNumFileDescriptor)
|
|
395
|
+
pino(destinationViaStream)
|
|
396
|
+
pino({ name: 'my-logger' }, destinationViaStream)
|
|
397
|
+
pino(destinationViaOptionsObject)
|
|
398
|
+
pino({ name: 'my-logger' }, destinationViaOptionsObject)
|
|
399
|
+
|
|
400
|
+
try {
|
|
401
|
+
throw new Error('Some error')
|
|
402
|
+
} catch (err) {
|
|
403
|
+
log.error(err)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface StrictShape {
|
|
407
|
+
activity: string;
|
|
408
|
+
err?: unknown;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
info<StrictShape>({
|
|
412
|
+
activity: 'Required property',
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
const logLine: pino.LogDescriptor = {
|
|
416
|
+
level: 20,
|
|
417
|
+
msg: 'A log message',
|
|
418
|
+
time: new Date().getTime(),
|
|
419
|
+
aCustomProperty: true,
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
interface CustomLogger extends pino.Logger {
|
|
423
|
+
customMethod(msg: string, ...args: unknown[]): void;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const serializerFunc: pino.SerializerFn = () => {}
|
|
427
|
+
const writeFunc: pino.WriteFn = () => {}
|
|
428
|
+
|
|
429
|
+
interface CustomBaseLogger extends pino.BaseLogger {
|
|
430
|
+
child(): CustomBaseLogger;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const customBaseLogger: CustomBaseLogger = {
|
|
434
|
+
level: 'info',
|
|
435
|
+
fatal () {},
|
|
436
|
+
error () {},
|
|
437
|
+
warn () {},
|
|
438
|
+
info () {},
|
|
439
|
+
debug () {},
|
|
440
|
+
trace () {},
|
|
441
|
+
silent () {},
|
|
442
|
+
child () {
|
|
443
|
+
return this
|
|
444
|
+
},
|
|
445
|
+
msgPrefix: 'prefix',
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// custom levels
|
|
449
|
+
const log3 = pino({ customLevels: { myLevel: 100 } })
|
|
450
|
+
expectError(log3.log())
|
|
451
|
+
log3.level = 'myLevel'
|
|
452
|
+
log3.myLevel('')
|
|
453
|
+
log3.child({}).myLevel('')
|
|
454
|
+
|
|
455
|
+
log3.on('level-change', (lvl, val, prevLvl, prevVal, instance) => {
|
|
456
|
+
instance.myLevel('foo')
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
const clog3 = log3.child({}, { customLevels: { childLevel: 120 } })
|
|
460
|
+
// child inherit parent
|
|
461
|
+
clog3.myLevel('')
|
|
462
|
+
// child itself
|
|
463
|
+
clog3.childLevel('')
|
|
464
|
+
const cclog3 = clog3.child({}, { customLevels: { childLevel2: 130 } })
|
|
465
|
+
// child inherit root
|
|
466
|
+
cclog3.myLevel('')
|
|
467
|
+
// child inherit parent
|
|
468
|
+
cclog3.childLevel('')
|
|
469
|
+
// child itself
|
|
470
|
+
cclog3.childLevel2('')
|
|
471
|
+
|
|
472
|
+
const ccclog3 = clog3.child({})
|
|
473
|
+
expectError(ccclog3.nonLevel(''))
|
|
474
|
+
|
|
475
|
+
const withChildCallback = pino({
|
|
476
|
+
onChild: (child: Logger) => {},
|
|
477
|
+
})
|
|
478
|
+
withChildCallback.onChild = (child: Logger) => {}
|
|
479
|
+
|
|
480
|
+
pino({
|
|
481
|
+
crlf: true,
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
const customLevels = { foo: 99, bar: 42 }
|
|
485
|
+
|
|
486
|
+
const customLevelLogger = pino({ customLevels })
|
|
487
|
+
|
|
488
|
+
type CustomLevelLogger = typeof customLevelLogger
|
|
489
|
+
type CustomLevelLoggerLevels = pino.Level | keyof typeof customLevels
|
|
490
|
+
|
|
491
|
+
const fn = (logger: Pick<CustomLevelLogger, CustomLevelLoggerLevels>) => {}
|
|
492
|
+
|
|
493
|
+
const customLevelChildLogger = customLevelLogger.child({ name: 'child' })
|
|
494
|
+
|
|
495
|
+
fn(customLevelChildLogger) // missing foo typing
|
|
496
|
+
|
|
497
|
+
// unknown option
|
|
498
|
+
expectError(
|
|
499
|
+
pino({
|
|
500
|
+
hello: 'world',
|
|
501
|
+
})
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
// unknown option
|
|
505
|
+
expectError(
|
|
506
|
+
pino({
|
|
507
|
+
hello: 'world',
|
|
508
|
+
customLevels: {
|
|
509
|
+
log: 30,
|
|
510
|
+
},
|
|
511
|
+
})
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
function dangerous () {
|
|
515
|
+
throw Error('foo')
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
try {
|
|
519
|
+
dangerous()
|
|
520
|
+
} catch (err) {
|
|
521
|
+
log.error(err)
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
try {
|
|
525
|
+
dangerous()
|
|
526
|
+
} catch (err) {
|
|
527
|
+
log.error({ err })
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const bLogger = pino({
|
|
531
|
+
customLevels: {
|
|
532
|
+
log: 5,
|
|
533
|
+
},
|
|
534
|
+
level: 'log',
|
|
535
|
+
transport: {
|
|
536
|
+
target: 'pino-pretty',
|
|
537
|
+
options: {
|
|
538
|
+
colorize: true,
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
})
|
|
542
|
+
|
|
543
|
+
// Test that we can properly extract parameters from the log fn type
|
|
544
|
+
type LogParam = Parameters<LogFn>
|
|
545
|
+
const [param1, param2, param3, param4]: LogParam = [
|
|
546
|
+
{ multiple: 'params' },
|
|
547
|
+
'should',
|
|
548
|
+
'be',
|
|
549
|
+
'accepted',
|
|
550
|
+
]
|
|
551
|
+
|
|
552
|
+
expectType<unknown>(param1)
|
|
553
|
+
expectType<string>(param2)
|
|
554
|
+
expectType<unknown>(param3)
|
|
555
|
+
expectType<unknown>(param4)
|
|
556
|
+
|
|
557
|
+
const logger = mock.fn<LogFn>()
|
|
558
|
+
logger.mock.calls[0].arguments[1]?.includes('I should be able to get params')
|
|
559
|
+
|
|
560
|
+
const hooks: LoggerOptions['hooks'] = {
|
|
561
|
+
logMethod (this, parameters, method) {
|
|
562
|
+
if (parameters.length >= 2) {
|
|
563
|
+
const [parameter1, parameter2, ...remainingParameters] = parameters
|
|
564
|
+
if (typeof parameter1 === 'string') {
|
|
565
|
+
return method.apply(this, [
|
|
566
|
+
parameter2,
|
|
567
|
+
parameter1,
|
|
568
|
+
...remainingParameters,
|
|
569
|
+
])
|
|
570
|
+
}
|
|
571
|
+
return method.apply(this, [parameter2])
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return method.apply(this, parameters)
|
|
575
|
+
},
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
expectType<Logger<'log'>>(
|
|
579
|
+
pino({
|
|
580
|
+
customLevels: {
|
|
581
|
+
log: 5,
|
|
582
|
+
},
|
|
583
|
+
level: 'log',
|
|
584
|
+
transport: {
|
|
585
|
+
target: 'pino-pretty',
|
|
586
|
+
options: {
|
|
587
|
+
colorize: true,
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
})
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
const parentLogger1 = pino(
|
|
594
|
+
{
|
|
595
|
+
customLevels: { myLevel: 90 },
|
|
596
|
+
onChild: (child) => {
|
|
597
|
+
const a = child.myLevel
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
process.stdout
|
|
601
|
+
)
|
|
602
|
+
parentLogger1.onChild = (child) => {
|
|
603
|
+
child.myLevel('')
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const childLogger1 = parentLogger1.child({})
|
|
607
|
+
childLogger1.myLevel('')
|
|
608
|
+
expectError(childLogger1.doesntExist(''))
|
|
609
|
+
|
|
610
|
+
const parentLogger2 = pino({}, process.stdin)
|
|
611
|
+
expectError(
|
|
612
|
+
(parentLogger2.onChild = (child) => {
|
|
613
|
+
const b = child.doesntExist
|
|
614
|
+
})
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
const childLogger2 = parentLogger2.child({})
|
|
618
|
+
expectError(childLogger2.doesntExist)
|
|
619
|
+
|
|
620
|
+
expectError(
|
|
621
|
+
pino(
|
|
622
|
+
{
|
|
623
|
+
onChild: (child) => {
|
|
624
|
+
const a = child.doesntExist
|
|
625
|
+
},
|
|
626
|
+
},
|
|
627
|
+
process.stdout
|
|
628
|
+
)
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
const pinoWithoutLevelsSorting = pino({})
|
|
632
|
+
const pinoWithDescSortingLevels = pino({ levelComparison: 'DESC' })
|
|
633
|
+
const pinoWithAscSortingLevels = pino({ levelComparison: 'ASC' })
|
|
634
|
+
const pinoWithCustomSortingLevels = pino({ levelComparison: () => false })
|
|
635
|
+
// with wrong level comparison direction
|
|
636
|
+
expectError(pino({ levelComparison: 'SOME' }), process.stdout)
|
|
637
|
+
// with wrong level comparison type
|
|
638
|
+
expectError(pino({ levelComparison: 123 }), process.stdout)
|
|
639
|
+
// with wrong custom level comparison return type
|
|
640
|
+
expectError(pino({ levelComparison: () => null }), process.stdout)
|
|
641
|
+
expectError(pino({ levelComparison: () => 1 }), process.stdout)
|
|
642
|
+
expectError(pino({ levelComparison: () => 'string' }), process.stdout)
|
|
643
|
+
|
|
644
|
+
const customLevelsOnlyOpts = {
|
|
645
|
+
useOnlyCustomLevels: true,
|
|
646
|
+
customLevels: {
|
|
647
|
+
customDebug: 10,
|
|
648
|
+
info: 20, // to make sure the default names are also available for override
|
|
649
|
+
customNetwork: 30,
|
|
650
|
+
customError: 40,
|
|
651
|
+
},
|
|
652
|
+
level: 'customDebug',
|
|
653
|
+
} satisfies LoggerOptions
|
|
654
|
+
|
|
655
|
+
const loggerWithCustomLevelOnly = pino(customLevelsOnlyOpts)
|
|
656
|
+
loggerWithCustomLevelOnly.customDebug('test3')
|
|
657
|
+
loggerWithCustomLevelOnly.info('test4')
|
|
658
|
+
loggerWithCustomLevelOnly.customError('test5')
|
|
659
|
+
loggerWithCustomLevelOnly.customNetwork('test6')
|
|
660
|
+
|
|
661
|
+
expectError(loggerWithCustomLevelOnly.fatal('test'))
|
|
662
|
+
expectError(loggerWithCustomLevelOnly.error('test'))
|
|
663
|
+
expectError(loggerWithCustomLevelOnly.warn('test'))
|
|
664
|
+
expectError(loggerWithCustomLevelOnly.debug('test'))
|
|
665
|
+
expectError(loggerWithCustomLevelOnly.trace('test'))
|
|
666
|
+
|
|
667
|
+
// Module extension
|
|
668
|
+
declare module '../../' {
|
|
669
|
+
interface LogFnFields {
|
|
670
|
+
bannedField?: never;
|
|
671
|
+
typeCheckedField?: string;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
info({ typeCheckedField: 'bar' })
|
|
676
|
+
expectError(info({ bannedField: 'bar' }))
|
|
677
|
+
expectError(info({ typeCheckedField: 123 }))
|
|
678
|
+
|
|
679
|
+
const someGenericFunction = <T extends string | number | symbol = never>(
|
|
680
|
+
arg: Record<T, unknown>
|
|
681
|
+
) => {
|
|
682
|
+
info(arg)
|
|
683
|
+
}
|