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,137 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const os = require('node:os')
|
|
6
|
+
const { join } = require('node:path')
|
|
7
|
+
const { readFile } = require('node:fs').promises
|
|
8
|
+
|
|
9
|
+
const { watchFileCreated, file } = require('../helper')
|
|
10
|
+
const pino = require('../../')
|
|
11
|
+
const { DEFAULT_LEVELS } = require('../../lib/constants')
|
|
12
|
+
|
|
13
|
+
const { pid } = process
|
|
14
|
+
const hostname = os.hostname()
|
|
15
|
+
|
|
16
|
+
test('pino.transport with a pipeline', async (t) => {
|
|
17
|
+
const destination = file()
|
|
18
|
+
const transport = pino.transport({
|
|
19
|
+
pipeline: [{
|
|
20
|
+
target: join(__dirname, '..', 'fixtures', 'transport-transform.js')
|
|
21
|
+
}, {
|
|
22
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
23
|
+
options: { destination }
|
|
24
|
+
}]
|
|
25
|
+
})
|
|
26
|
+
t.after(transport.end.bind(transport))
|
|
27
|
+
const instance = pino(transport)
|
|
28
|
+
instance.info('hello')
|
|
29
|
+
await watchFileCreated(destination)
|
|
30
|
+
const result = JSON.parse(await readFile(destination))
|
|
31
|
+
delete result.time
|
|
32
|
+
assert.deepEqual(result, {
|
|
33
|
+
pid,
|
|
34
|
+
hostname,
|
|
35
|
+
level: DEFAULT_LEVELS.info,
|
|
36
|
+
msg: 'hello',
|
|
37
|
+
service: 'pino' // this property was added by the transform
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('pino.transport with targets containing pipelines', async (t) => {
|
|
42
|
+
const destinationA = file()
|
|
43
|
+
const destinationB = file()
|
|
44
|
+
const transport = pino.transport({
|
|
45
|
+
targets: [
|
|
46
|
+
{
|
|
47
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
48
|
+
options: { destination: destinationA }
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
pipeline: [
|
|
52
|
+
{
|
|
53
|
+
target: join(__dirname, '..', 'fixtures', 'transport-transform.js')
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
57
|
+
options: { destination: destinationB }
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
t.after(transport.end.bind(transport))
|
|
65
|
+
const instance = pino(transport)
|
|
66
|
+
instance.info('hello')
|
|
67
|
+
await watchFileCreated(destinationA)
|
|
68
|
+
await watchFileCreated(destinationB)
|
|
69
|
+
const resultA = JSON.parse(await readFile(destinationA))
|
|
70
|
+
const resultB = JSON.parse(await readFile(destinationB))
|
|
71
|
+
delete resultA.time
|
|
72
|
+
delete resultB.time
|
|
73
|
+
assert.deepEqual(resultA, {
|
|
74
|
+
pid,
|
|
75
|
+
hostname,
|
|
76
|
+
level: DEFAULT_LEVELS.info,
|
|
77
|
+
msg: 'hello'
|
|
78
|
+
})
|
|
79
|
+
assert.deepEqual(resultB, {
|
|
80
|
+
pid,
|
|
81
|
+
hostname,
|
|
82
|
+
level: DEFAULT_LEVELS.info,
|
|
83
|
+
msg: 'hello',
|
|
84
|
+
service: 'pino' // this property was added by the transform
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
test('pino.transport with targets containing pipelines with levels defined and dedupe', async (t) => {
|
|
89
|
+
const destinationA = file()
|
|
90
|
+
const destinationB = file()
|
|
91
|
+
const transport = pino.transport({
|
|
92
|
+
targets: [
|
|
93
|
+
{
|
|
94
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
95
|
+
options: { destination: destinationA },
|
|
96
|
+
level: DEFAULT_LEVELS.info
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
pipeline: [
|
|
100
|
+
{
|
|
101
|
+
target: join(__dirname, '..', 'fixtures', 'transport-transform.js')
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
105
|
+
options: { destination: destinationB }
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
level: DEFAULT_LEVELS.error
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
dedupe: true
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
t.after(transport.end.bind(transport))
|
|
115
|
+
const instance = pino(transport)
|
|
116
|
+
instance.info('hello info')
|
|
117
|
+
instance.error('hello error')
|
|
118
|
+
await watchFileCreated(destinationA)
|
|
119
|
+
await watchFileCreated(destinationB)
|
|
120
|
+
const resultA = JSON.parse(await readFile(destinationA))
|
|
121
|
+
const resultB = JSON.parse(await readFile(destinationB))
|
|
122
|
+
delete resultA.time
|
|
123
|
+
delete resultB.time
|
|
124
|
+
assert.deepEqual(resultA, {
|
|
125
|
+
pid,
|
|
126
|
+
hostname,
|
|
127
|
+
level: DEFAULT_LEVELS.info,
|
|
128
|
+
msg: 'hello info'
|
|
129
|
+
})
|
|
130
|
+
assert.deepEqual(resultB, {
|
|
131
|
+
pid,
|
|
132
|
+
hostname,
|
|
133
|
+
level: DEFAULT_LEVELS.error,
|
|
134
|
+
msg: 'hello error',
|
|
135
|
+
service: 'pino' // this property was added by the transform
|
|
136
|
+
})
|
|
137
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const { join } = require('node:path')
|
|
6
|
+
const { pathToFileURL } = require('node:url')
|
|
7
|
+
const { readFile } = require('node:fs').promises
|
|
8
|
+
const execa = require('execa')
|
|
9
|
+
|
|
10
|
+
const { file, watchFileCreated } = require('../helper')
|
|
11
|
+
|
|
12
|
+
test('pino.transport works when loaded via --import=preload', async () => {
|
|
13
|
+
const destination = file()
|
|
14
|
+
const preload = pathToFileURL(join(__dirname, '..', 'fixtures', 'transport-preload.mjs')).href
|
|
15
|
+
const main = join(__dirname, '..', 'fixtures', 'transport-preload-main.mjs')
|
|
16
|
+
|
|
17
|
+
await execa(process.argv[0], [
|
|
18
|
+
`--import=${preload}`,
|
|
19
|
+
main,
|
|
20
|
+
destination
|
|
21
|
+
], { timeout: 10000 })
|
|
22
|
+
|
|
23
|
+
await watchFileCreated(destination)
|
|
24
|
+
const result = JSON.parse(await readFile(destination))
|
|
25
|
+
assert.equal(result.msg, 'hello from main')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('pino.transport works when loaded via --import preload (space separated)', async () => {
|
|
29
|
+
const destination = file()
|
|
30
|
+
const preload = pathToFileURL(join(__dirname, '..', 'fixtures', 'transport-preload.mjs')).href
|
|
31
|
+
const main = join(__dirname, '..', 'fixtures', 'transport-preload-main.mjs')
|
|
32
|
+
|
|
33
|
+
await execa(process.argv[0], [
|
|
34
|
+
'--import',
|
|
35
|
+
preload,
|
|
36
|
+
main,
|
|
37
|
+
destination
|
|
38
|
+
], { timeout: 10000 })
|
|
39
|
+
|
|
40
|
+
await watchFileCreated(destination)
|
|
41
|
+
const result = JSON.parse(await readFile(destination))
|
|
42
|
+
assert.equal(result.msg, 'hello from main')
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('pino.transport ignores missing absolute preload from NODE_OPTIONS in worker', async () => {
|
|
46
|
+
const destination = file()
|
|
47
|
+
const main = join(__dirname, '..', 'fixtures', 'transport-invalid-node-options.js')
|
|
48
|
+
|
|
49
|
+
await execa(process.argv[0], [main, destination], { timeout: 10000 })
|
|
50
|
+
|
|
51
|
+
await watchFileCreated(destination)
|
|
52
|
+
const result = JSON.parse(await readFile(destination))
|
|
53
|
+
assert.equal(result.msg, 'hello with invalid node options preload')
|
|
54
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const proxyquire = require('proxyquire')
|
|
6
|
+
|
|
7
|
+
test('pino.transport resolves targets in REPL', async () => {
|
|
8
|
+
// Arrange
|
|
9
|
+
const transport = proxyquire('../../lib/transport', {
|
|
10
|
+
'./caller': () => ['node:repl']
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
// Act / Assert
|
|
14
|
+
assert.doesNotThrow(() => transport({ target: 'pino-pretty' }))
|
|
15
|
+
})
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const os = require('node:os')
|
|
6
|
+
const { join } = require('node:path')
|
|
7
|
+
const { readFile } = require('node:fs').promises
|
|
8
|
+
const { promisify } = require('node:util')
|
|
9
|
+
|
|
10
|
+
const pino = require('../..')
|
|
11
|
+
const { watchFileCreated, watchForWrite, file } = require('../helper')
|
|
12
|
+
|
|
13
|
+
const { pid } = process
|
|
14
|
+
const hostname = os.hostname()
|
|
15
|
+
|
|
16
|
+
test('thread-stream async flush', async () => {
|
|
17
|
+
const destination = file()
|
|
18
|
+
const transport = pino.transport({
|
|
19
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
20
|
+
options: { destination }
|
|
21
|
+
})
|
|
22
|
+
const instance = pino(transport)
|
|
23
|
+
instance.info('hello')
|
|
24
|
+
|
|
25
|
+
assert.equal(instance.flush(), undefined)
|
|
26
|
+
|
|
27
|
+
await watchFileCreated(destination)
|
|
28
|
+
const result = JSON.parse(await readFile(destination))
|
|
29
|
+
delete result.time
|
|
30
|
+
assert.deepEqual(result, {
|
|
31
|
+
pid,
|
|
32
|
+
hostname,
|
|
33
|
+
level: 30,
|
|
34
|
+
msg: 'hello'
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('thread-stream async flush should call the passed callback', async () => {
|
|
39
|
+
const outputPath = file()
|
|
40
|
+
async function getOutputLogLines () {
|
|
41
|
+
return (await readFile(outputPath)).toString().trim().split('\n').map(JSON.parse)
|
|
42
|
+
}
|
|
43
|
+
const transport = pino.transport({
|
|
44
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
45
|
+
options: { destination: outputPath }
|
|
46
|
+
})
|
|
47
|
+
const instance = pino(transport)
|
|
48
|
+
const flushPromise = promisify(instance.flush).bind(instance)
|
|
49
|
+
|
|
50
|
+
instance.info('hello')
|
|
51
|
+
await flushPromise()
|
|
52
|
+
await watchFileCreated(outputPath)
|
|
53
|
+
|
|
54
|
+
const [firstFlushData] = await getOutputLogLines()
|
|
55
|
+
|
|
56
|
+
assert.equal(firstFlushData.msg, 'hello')
|
|
57
|
+
|
|
58
|
+
instance.info('world')
|
|
59
|
+
|
|
60
|
+
await flushPromise()
|
|
61
|
+
await watchForWrite(outputPath, 'world')
|
|
62
|
+
|
|
63
|
+
// After flush, both messages should be present
|
|
64
|
+
const afterSecondFlush = await getOutputLogLines()
|
|
65
|
+
assert.equal(afterSecondFlush.length, 2)
|
|
66
|
+
assert.equal(afterSecondFlush[1].msg, 'world')
|
|
67
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const { join } = require('node:path')
|
|
6
|
+
const { readFileSync } = require('node:fs')
|
|
7
|
+
|
|
8
|
+
const { file } = require('../helper')
|
|
9
|
+
const pino = require('../..')
|
|
10
|
+
|
|
11
|
+
test('thread-stream sync true should log synchronously', async () => {
|
|
12
|
+
const outputPath = file()
|
|
13
|
+
|
|
14
|
+
function getOutputLogLines () {
|
|
15
|
+
return (readFileSync(outputPath)).toString().trim().split('\n').map(JSON.parse)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const transport = pino.transport({
|
|
19
|
+
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
|
20
|
+
options: { destination: outputPath, flush: true },
|
|
21
|
+
sync: true
|
|
22
|
+
})
|
|
23
|
+
const instance = pino(transport)
|
|
24
|
+
|
|
25
|
+
var value = { message: 'sync' }
|
|
26
|
+
instance.info(value)
|
|
27
|
+
instance.info(value)
|
|
28
|
+
instance.info(value)
|
|
29
|
+
instance.info(value)
|
|
30
|
+
instance.info(value)
|
|
31
|
+
instance.info(value)
|
|
32
|
+
let interrupt = false
|
|
33
|
+
let flushData
|
|
34
|
+
let loopCounter = 0
|
|
35
|
+
|
|
36
|
+
// Start a synchronous loop
|
|
37
|
+
while (!interrupt && loopCounter < (process.env.MAX_TEST_LOOP_ITERATION || 20000)) {
|
|
38
|
+
try {
|
|
39
|
+
loopCounter++
|
|
40
|
+
const data = getOutputLogLines()
|
|
41
|
+
flushData = data
|
|
42
|
+
if (data) {
|
|
43
|
+
interrupt = true
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// File may not exist yet
|
|
48
|
+
// Wait till MAX_TEST_LOOP_ITERATION iterations
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!interrupt) {
|
|
53
|
+
throw new Error('Sync loop did not get interrupt')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
assert.equal(flushData.length, 6)
|
|
57
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const { join } = require('node:path')
|
|
5
|
+
const Writable = require('node:stream').Writable
|
|
6
|
+
const proxyquire = require('proxyquire')
|
|
7
|
+
const tspl = require('@matteo.collina/tspl')
|
|
8
|
+
const pino = require('../../pino')
|
|
9
|
+
|
|
10
|
+
test('file-target mocked', async function (t) {
|
|
11
|
+
const plan = tspl(t, { plan: 1 })
|
|
12
|
+
let ret
|
|
13
|
+
const fileTarget = proxyquire('../../file', {
|
|
14
|
+
'./pino': {
|
|
15
|
+
destination (opts) {
|
|
16
|
+
plan.deepEqual(opts, { dest: 1, sync: false })
|
|
17
|
+
|
|
18
|
+
ret = new Writable()
|
|
19
|
+
ret.fd = opts.dest
|
|
20
|
+
|
|
21
|
+
process.nextTick(() => {
|
|
22
|
+
ret.emit('ready')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
return ret
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
await fileTarget()
|
|
31
|
+
await plan
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('pino.transport with syntax error', async (t) => {
|
|
35
|
+
const plan = tspl(t, { plan: 1 })
|
|
36
|
+
const transport = pino.transport({
|
|
37
|
+
targets: [{
|
|
38
|
+
target: join(__dirname, '..', 'fixtures', 'syntax-error-esm.mjs')
|
|
39
|
+
}]
|
|
40
|
+
})
|
|
41
|
+
t.after(transport.end.bind(transport))
|
|
42
|
+
|
|
43
|
+
transport.on('error', (err) => {
|
|
44
|
+
plan.deepEqual(err, new SyntaxError('Unexpected end of input'))
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
await plan
|
|
48
|
+
})
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
5
|
+
const os = require('node:os')
|
|
6
|
+
const { join } = require('node:path')
|
|
7
|
+
const { readFile } = require('node:fs').promises
|
|
8
|
+
const writeStream = require('flush-write-stream')
|
|
9
|
+
|
|
10
|
+
const { watchFileCreated, file } = require('../helper')
|
|
11
|
+
const pino = require('../../')
|
|
12
|
+
|
|
13
|
+
const { pid } = process
|
|
14
|
+
const hostname = os.hostname()
|
|
15
|
+
|
|
16
|
+
function serializeError (error) {
|
|
17
|
+
return {
|
|
18
|
+
type: error.name,
|
|
19
|
+
message: error.message,
|
|
20
|
+
stack: error.stack
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function parseLogs (buffer) {
|
|
25
|
+
return JSON.parse(`[${buffer.toString().replace(/}{/g, '},{')}]`)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
test('transport uses pino config', async (t) => {
|
|
29
|
+
const destination = file()
|
|
30
|
+
const transport = pino.transport({
|
|
31
|
+
pipeline: [{
|
|
32
|
+
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
|
|
33
|
+
}, {
|
|
34
|
+
target: 'pino/file',
|
|
35
|
+
options: { destination }
|
|
36
|
+
}]
|
|
37
|
+
})
|
|
38
|
+
t.after(transport.end.bind(transport))
|
|
39
|
+
const instance = pino({
|
|
40
|
+
messageKey: 'customMessageKey',
|
|
41
|
+
errorKey: 'customErrorKey',
|
|
42
|
+
customLevels: { custom: 35 }
|
|
43
|
+
}, transport)
|
|
44
|
+
|
|
45
|
+
const error = new Error('bar')
|
|
46
|
+
instance.custom('foo')
|
|
47
|
+
instance.error(error)
|
|
48
|
+
await watchFileCreated(destination)
|
|
49
|
+
const result = parseLogs(await readFile(destination))
|
|
50
|
+
|
|
51
|
+
assert.deepEqual(result, [{
|
|
52
|
+
severityText: 'custom',
|
|
53
|
+
body: 'foo',
|
|
54
|
+
attributes: {
|
|
55
|
+
pid,
|
|
56
|
+
hostname
|
|
57
|
+
}
|
|
58
|
+
}, {
|
|
59
|
+
severityText: 'error',
|
|
60
|
+
body: 'bar',
|
|
61
|
+
attributes: {
|
|
62
|
+
pid,
|
|
63
|
+
hostname
|
|
64
|
+
},
|
|
65
|
+
error: serializeError(error)
|
|
66
|
+
}])
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test('transport uses pino config without customizations', async (t) => {
|
|
70
|
+
const destination = file()
|
|
71
|
+
const transport = pino.transport({
|
|
72
|
+
pipeline: [{
|
|
73
|
+
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
|
|
74
|
+
}, {
|
|
75
|
+
target: 'pino/file',
|
|
76
|
+
options: { destination }
|
|
77
|
+
}]
|
|
78
|
+
})
|
|
79
|
+
t.after(transport.end.bind(transport))
|
|
80
|
+
const instance = pino(transport)
|
|
81
|
+
|
|
82
|
+
const error = new Error('qux')
|
|
83
|
+
instance.info('baz')
|
|
84
|
+
instance.error(error)
|
|
85
|
+
await watchFileCreated(destination)
|
|
86
|
+
const result = parseLogs(await readFile(destination))
|
|
87
|
+
|
|
88
|
+
assert.deepEqual(result, [{
|
|
89
|
+
severityText: 'info',
|
|
90
|
+
body: 'baz',
|
|
91
|
+
attributes: {
|
|
92
|
+
pid,
|
|
93
|
+
hostname
|
|
94
|
+
}
|
|
95
|
+
}, {
|
|
96
|
+
severityText: 'error',
|
|
97
|
+
body: 'qux',
|
|
98
|
+
attributes: {
|
|
99
|
+
pid,
|
|
100
|
+
hostname
|
|
101
|
+
},
|
|
102
|
+
error: serializeError(error)
|
|
103
|
+
}])
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('transport uses pino config with multistream', async (t) => {
|
|
107
|
+
const destination = file()
|
|
108
|
+
const messages = []
|
|
109
|
+
const stream = writeStream(function (data, enc, cb) {
|
|
110
|
+
const message = JSON.parse(data)
|
|
111
|
+
delete message.time
|
|
112
|
+
messages.push(message)
|
|
113
|
+
cb()
|
|
114
|
+
})
|
|
115
|
+
const transport = pino.transport({
|
|
116
|
+
pipeline: [{
|
|
117
|
+
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
|
|
118
|
+
}, {
|
|
119
|
+
target: 'pino/file',
|
|
120
|
+
options: { destination }
|
|
121
|
+
}]
|
|
122
|
+
})
|
|
123
|
+
t.after(transport.end.bind(transport))
|
|
124
|
+
const instance = pino({
|
|
125
|
+
messageKey: 'customMessageKey',
|
|
126
|
+
errorKey: 'customErrorKey',
|
|
127
|
+
customLevels: { custom: 35 }
|
|
128
|
+
}, pino.multistream([transport, { stream }]))
|
|
129
|
+
|
|
130
|
+
const error = new Error('buzz')
|
|
131
|
+
const serializedError = serializeError(error)
|
|
132
|
+
instance.custom('fizz')
|
|
133
|
+
instance.error(error)
|
|
134
|
+
await watchFileCreated(destination)
|
|
135
|
+
const result = parseLogs(await readFile(destination))
|
|
136
|
+
|
|
137
|
+
assert.deepEqual(result, [{
|
|
138
|
+
severityText: 'custom',
|
|
139
|
+
body: 'fizz',
|
|
140
|
+
attributes: {
|
|
141
|
+
pid,
|
|
142
|
+
hostname
|
|
143
|
+
}
|
|
144
|
+
}, {
|
|
145
|
+
severityText: 'error',
|
|
146
|
+
body: 'buzz',
|
|
147
|
+
attributes: {
|
|
148
|
+
pid,
|
|
149
|
+
hostname
|
|
150
|
+
},
|
|
151
|
+
error: serializedError
|
|
152
|
+
}])
|
|
153
|
+
|
|
154
|
+
assert.deepEqual(messages, [{
|
|
155
|
+
level: 35,
|
|
156
|
+
pid,
|
|
157
|
+
hostname,
|
|
158
|
+
customMessageKey: 'fizz'
|
|
159
|
+
}, {
|
|
160
|
+
level: 50,
|
|
161
|
+
pid,
|
|
162
|
+
hostname,
|
|
163
|
+
customErrorKey: serializedError,
|
|
164
|
+
customMessageKey: 'buzz'
|
|
165
|
+
}])
|
|
166
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const test = require('node:test')
|
|
4
|
+
const proxyquire = require('proxyquire')
|
|
5
|
+
const tspl = require('@matteo.collina/tspl')
|
|
6
|
+
|
|
7
|
+
test('should import', async (t) => {
|
|
8
|
+
const plan = tspl(t, { plan: 2 })
|
|
9
|
+
const mockRealRequire = (target) => {
|
|
10
|
+
return {
|
|
11
|
+
default: {
|
|
12
|
+
default: () => {
|
|
13
|
+
plan.equal(target, 'pino-pretty')
|
|
14
|
+
return Promise.resolve()
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const mockRealImport = async () => {
|
|
20
|
+
await Promise.resolve()
|
|
21
|
+
throw Object.assign(new Error(), { code: 'ERR_MODULE_NOT_FOUND' })
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const loadTransportStreamBuilder = proxyquire(
|
|
25
|
+
'../lib/transport-stream.js',
|
|
26
|
+
{
|
|
27
|
+
'real-require': {
|
|
28
|
+
realRequire: mockRealRequire,
|
|
29
|
+
realImport: mockRealImport
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
const fn = await loadTransportStreamBuilder('pino-pretty')
|
|
35
|
+
|
|
36
|
+
await fn()
|
|
37
|
+
plan.ok('returned promise resolved')
|
|
38
|
+
|
|
39
|
+
await plan
|
|
40
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { expectType } from "tsd";
|
|
2
|
+
|
|
3
|
+
import * as pinoStar from "../../pino";
|
|
4
|
+
import { default as P, default as pino, pino as pinoNamed } from '../../pino';
|
|
5
|
+
import pinoCjsImport = require ("../../pino");
|
|
6
|
+
const pinoCjs = require("../../pino");
|
|
7
|
+
const { P: pinoCjsNamed } = require('pino')
|
|
8
|
+
|
|
9
|
+
const log = pino();
|
|
10
|
+
expectType<P.LogFn>(log.info);
|
|
11
|
+
expectType<P.LogFn>(log.error);
|
|
12
|
+
|
|
13
|
+
expectType<pino.Logger>(pinoNamed());
|
|
14
|
+
expectType<P.Logger>(pinoNamed());
|
|
15
|
+
expectType<pino.Logger>(pinoStar.default());
|
|
16
|
+
expectType<pino.Logger>(pinoStar.pino());
|
|
17
|
+
// expectType<pino.Logger>(pinoCjsImport.default());
|
|
18
|
+
expectType<pino.Logger>(pinoCjsImport.pino());
|
|
19
|
+
expectType<any>(pinoCjsNamed());
|
|
20
|
+
expectType<any>(pinoCjs());
|
|
21
|
+
expectType<P.TimeFn>(pinoNamed.stdTimeFunctions.isoTimeNano)
|
|
22
|
+
expectType<string>(pinoNamed.stdTimeFunctions.isoTimeNano())
|
|
23
|
+
|
|
24
|
+
const levelChangeEventListener: P.LevelChangeEventListener = (
|
|
25
|
+
lvl: P.LevelWithSilent | string,
|
|
26
|
+
val: number,
|
|
27
|
+
prevLvl: P.LevelWithSilent | string,
|
|
28
|
+
prevVal: number,
|
|
29
|
+
) => {}
|
|
30
|
+
expectType<P.LevelChangeEventListener>(levelChangeEventListener)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { expectType, expectNotType } from 'tsd'
|
|
2
|
+
|
|
3
|
+
import { createWriteStream } from 'node:fs'
|
|
4
|
+
|
|
5
|
+
import pino, { multistream } from '../../pino'
|
|
6
|
+
|
|
7
|
+
const streams = [
|
|
8
|
+
{ stream: process.stdout },
|
|
9
|
+
{ stream: createWriteStream('') },
|
|
10
|
+
{ level: 'error' as const, stream: process.stderr },
|
|
11
|
+
{ level: 'fatal' as const, stream: process.stderr },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
expectType<pino.MultiStreamRes>(pino.multistream(process.stdout))
|
|
15
|
+
expectType<pino.MultiStreamRes>(pino.multistream([createWriteStream('')]))
|
|
16
|
+
expectType<pino.MultiStreamRes<'error'>>(pino.multistream({ level: 'error' as const, stream: process.stderr }))
|
|
17
|
+
expectType<pino.MultiStreamRes<'fatal'>>(pino.multistream([{ level: 'fatal' as const, stream: createWriteStream('') }]))
|
|
18
|
+
|
|
19
|
+
expectType<pino.MultiStreamRes<'error' | 'fatal'>>(pino.multistream(streams))
|
|
20
|
+
expectType<pino.MultiStreamRes<'error' | 'fatal'>>(pino.multistream(streams, {}))
|
|
21
|
+
expectType<pino.MultiStreamRes<'error' | 'fatal'>>(pino.multistream(streams, { levels: { info: 30 } }))
|
|
22
|
+
expectType<pino.MultiStreamRes<'error' | 'fatal'>>(pino.multistream(streams, { dedupe: true }))
|
|
23
|
+
expectType<pino.MultiStreamRes<'error' | 'fatal'>>(pino.multistream(streams[0]).add(streams[1]))
|
|
24
|
+
expectType<pino.MultiStreamRes<'error' | 'fatal'>>(multistream(streams))
|
|
25
|
+
expectType<pino.MultiStreamRes<'error'>>(multistream(streams).clone('error'))
|
|
26
|
+
expectNotType<pino.MultiStreamRes<string>>(multistream(streams).clone('error'))
|
|
27
|
+
|
|
28
|
+
expectType<pino.MultiStreamRes>(multistream(process.stdout))
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { expectType, expectAssignable } from 'tsd'
|
|
2
|
+
import type { SonicBoom } from 'sonic-boom'
|
|
3
|
+
|
|
4
|
+
import pino, {
|
|
5
|
+
destination,
|
|
6
|
+
type LevelMapping,
|
|
7
|
+
levels,
|
|
8
|
+
type Logger,
|
|
9
|
+
multistream,
|
|
10
|
+
type MultiStreamRes,
|
|
11
|
+
type SerializedError,
|
|
12
|
+
stdSerializers,
|
|
13
|
+
stdTimeFunctions,
|
|
14
|
+
symbols,
|
|
15
|
+
transport,
|
|
16
|
+
version,
|
|
17
|
+
} from '../../pino'
|
|
18
|
+
|
|
19
|
+
expectType<SonicBoom>(destination(''))
|
|
20
|
+
expectType<LevelMapping>(levels)
|
|
21
|
+
expectType<MultiStreamRes>(multistream(process.stdout))
|
|
22
|
+
expectType<SerializedError>(stdSerializers.err({} as any))
|
|
23
|
+
expectType<string>(stdTimeFunctions.isoTime())
|
|
24
|
+
expectType<string>(stdTimeFunctions.isoTimeNano())
|
|
25
|
+
expectType<string>(version)
|
|
26
|
+
|
|
27
|
+
// Can't test against `unique symbol`, see https://github.com/SamVerschueren/tsd/issues/49
|
|
28
|
+
expectAssignable<Symbol>(symbols.endSym)
|
|
29
|
+
|
|
30
|
+
// TODO: currently returns (aliased) `any`, waiting for strong typed `thread-stream`
|
|
31
|
+
transport({
|
|
32
|
+
target: '#pino/pretty',
|
|
33
|
+
options: { some: 'options for', the: 'transport' }
|
|
34
|
+
})
|