lucide-node 0.0.1-security → 1.0.0
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.
Potentially problematic release.
This version of lucide-node might be problematic. Click here for more details.
- package/.eslintignore +2 -0
- package/.eslintrc +8 -0
- package/.github/dependabot.yml +13 -0
- package/.github/workflows/bench.yml +61 -0
- package/.github/workflows/ci.yml +88 -0
- package/.github/workflows/lock-threads.yml +30 -0
- package/.github/workflows/target-main.yml +23 -0
- package/.nojekyll +0 -0
- package/.prettierignore +1 -0
- package/.taprc.yaml +8 -0
- package/CNAME +1 -0
- package/CONTRIBUTING.md +30 -0
- package/LICENSE +21 -0
- package/README.md +159 -3
- package/SECURITY.md +68 -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 +484 -0
- package/build/sync-version.js +10 -0
- package/docs/api.md +1487 -0
- package/docs/asynchronous.md +40 -0
- package/docs/benchmarks.md +55 -0
- package/docs/browser.md +227 -0
- package/docs/bundling.md +40 -0
- package/docs/child-loggers.md +95 -0
- package/docs/ecosystem.md +84 -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 +1238 -0
- package/docs/web.md +269 -0
- package/docsify/sidebar.md +26 -0
- package/examples/basic.js +43 -0
- package/examples/transport.js +68 -0
- package/favicon-16x16.png +0 -0
- package/favicon-32x32.png +0 -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/deprecations.js +8 -0
- package/lib/levels.js +241 -0
- package/lib/meta.js +3 -0
- package/lib/multistream.js +188 -0
- package/lib/proto.js +234 -0
- package/lib/redaction.js +118 -0
- package/lib/symbols.js +74 -0
- package/lib/time.js +11 -0
- package/lib/tools.js +394 -0
- package/lib/transport-stream.js +56 -0
- package/lib/transport.js +167 -0
- package/lib/worker.js +194 -0
- package/lib/writer.js +42 -0
- package/package.json +117 -3
- package/pino-banner.png +0 -0
- package/pino-logo-hire.png +0 -0
- package/pino-tree.png +0 -0
- package/pino.d.ts +889 -0
- package/pino.js +236 -0
- package/pretty-demo.png +0 -0
- package/test/basic.test.js +874 -0
- package/test/broken-pipe.test.js +57 -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-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 +659 -0
- package/test/complex-objects.test.js +34 -0
- package/test/crlf.test.js +32 -0
- package/test/custom-levels.test.js +253 -0
- package/test/error.test.js +398 -0
- package/test/errorKey.test.js +34 -0
- package/test/escaping.test.js +91 -0
- package/test/esm/esm.mjs +12 -0
- package/test/esm/index.test.js +34 -0
- package/test/esm/named-exports.mjs +27 -0
- package/test/exit.test.js +77 -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/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-main.js +9 -0
- package/test/fixtures/transport-many-lines.js +29 -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.js +15 -0
- package/test/fixtures/transport-wrong-export-type.js +3 -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 +355 -0
- package/test/helper.d.ts +4 -0
- package/test/helper.js +128 -0
- package/test/hooks.test.js +118 -0
- package/test/http.test.js +242 -0
- package/test/internals/version.test.js +15 -0
- package/test/is-level-enabled.test.js +185 -0
- package/test/jest/basic.spec.js +10 -0
- package/test/levels.test.js +772 -0
- package/test/metadata.test.js +106 -0
- package/test/mixin-merge-strategy.test.js +55 -0
- package/test/mixin.test.js +218 -0
- package/test/multistream.test.js +673 -0
- package/test/pkg/index.js +46 -0
- package/test/pkg/pkg.config.json +17 -0
- package/test/pkg/pkg.test.js +56 -0
- package/test/redact.test.js +847 -0
- package/test/serializers.test.js +253 -0
- package/test/stdout-protection.test.js +39 -0
- package/test/syncfalse.test.js +188 -0
- package/test/timestamp.test.js +121 -0
- package/test/transport/big.test.js +43 -0
- package/test/transport/bundlers-support.test.js +97 -0
- package/test/transport/caller.test.js +23 -0
- package/test/transport/core.test.js +644 -0
- package/test/transport/core.test.ts +236 -0
- package/test/transport/core.transpiled.test.ts +112 -0
- package/test/transport/module-link.test.js +239 -0
- package/test/transport/pipeline.test.js +135 -0
- package/test/transport/repl.test.js +14 -0
- package/test/transport/syncTrue.test.js +55 -0
- package/test/transport/syncfalse.test.js +68 -0
- package/test/transport/targets.test.js +44 -0
- package/test/transport/uses-pino-config.test.js +167 -0
- package/test/transport-stream.test.js +26 -0
- package/test/types/pino-import.test-d.ts +29 -0
- package/test/types/pino-multistream.test-d.ts +28 -0
- package/test/types/pino-top-export.test-d.ts +35 -0
- package/test/types/pino-transport.test-d.ts +145 -0
- package/test/types/pino-type-only.test-d.ts +64 -0
- package/test/types/pino.test-d.ts +468 -0
- package/test/types/pino.ts +78 -0
- package/tsconfig.json +14 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
'use strict'
|
2
|
+
const { test } = require('tap')
|
3
|
+
const { sink, once } = require('./helper')
|
4
|
+
const stdSerializers = require('pino-std-serializers')
|
5
|
+
const pino = require('../')
|
6
|
+
|
7
|
+
const parentSerializers = {
|
8
|
+
test: () => 'parent'
|
9
|
+
}
|
10
|
+
|
11
|
+
const childSerializers = {
|
12
|
+
test: () => 'child'
|
13
|
+
}
|
14
|
+
|
15
|
+
test('default err namespace error serializer', async ({ equal }) => {
|
16
|
+
const stream = sink()
|
17
|
+
const parent = pino(stream)
|
18
|
+
|
19
|
+
parent.info({ err: ReferenceError('test') })
|
20
|
+
const o = await once(stream, 'data')
|
21
|
+
equal(typeof o.err, 'object')
|
22
|
+
equal(o.err.type, 'ReferenceError')
|
23
|
+
equal(o.err.message, 'test')
|
24
|
+
equal(typeof o.err.stack, 'string')
|
25
|
+
})
|
26
|
+
|
27
|
+
test('custom serializer overrides default err namespace error serializer', async ({ equal }) => {
|
28
|
+
const stream = sink()
|
29
|
+
const parent = pino({
|
30
|
+
serializers: {
|
31
|
+
err: (e) => ({
|
32
|
+
t: e.constructor.name,
|
33
|
+
m: e.message,
|
34
|
+
s: e.stack
|
35
|
+
})
|
36
|
+
}
|
37
|
+
}, stream)
|
38
|
+
|
39
|
+
parent.info({ err: ReferenceError('test') })
|
40
|
+
const o = await once(stream, 'data')
|
41
|
+
equal(typeof o.err, 'object')
|
42
|
+
equal(o.err.t, 'ReferenceError')
|
43
|
+
equal(o.err.m, 'test')
|
44
|
+
equal(typeof o.err.s, 'string')
|
45
|
+
})
|
46
|
+
|
47
|
+
test('custom serializer overrides default err namespace error serializer when nestedKey is on', async ({ equal }) => {
|
48
|
+
const stream = sink()
|
49
|
+
const parent = pino({
|
50
|
+
nestedKey: 'obj',
|
51
|
+
serializers: {
|
52
|
+
err: (e) => {
|
53
|
+
return {
|
54
|
+
t: e.constructor.name,
|
55
|
+
m: e.message,
|
56
|
+
s: e.stack
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}, stream)
|
61
|
+
|
62
|
+
parent.info({ err: ReferenceError('test') })
|
63
|
+
const o = await once(stream, 'data')
|
64
|
+
equal(typeof o.obj.err, 'object')
|
65
|
+
equal(o.obj.err.t, 'ReferenceError')
|
66
|
+
equal(o.obj.err.m, 'test')
|
67
|
+
equal(typeof o.obj.err.s, 'string')
|
68
|
+
})
|
69
|
+
|
70
|
+
test('null overrides default err namespace error serializer', async ({ equal }) => {
|
71
|
+
const stream = sink()
|
72
|
+
const parent = pino({ serializers: { err: null } }, stream)
|
73
|
+
|
74
|
+
parent.info({ err: ReferenceError('test') })
|
75
|
+
const o = await once(stream, 'data')
|
76
|
+
equal(typeof o.err, 'object')
|
77
|
+
equal(typeof o.err.type, 'undefined')
|
78
|
+
equal(typeof o.err.message, 'undefined')
|
79
|
+
equal(typeof o.err.stack, 'undefined')
|
80
|
+
})
|
81
|
+
|
82
|
+
test('undefined overrides default err namespace error serializer', async ({ equal }) => {
|
83
|
+
const stream = sink()
|
84
|
+
const parent = pino({ serializers: { err: undefined } }, stream)
|
85
|
+
|
86
|
+
parent.info({ err: ReferenceError('test') })
|
87
|
+
const o = await once(stream, 'data')
|
88
|
+
equal(typeof o.err, 'object')
|
89
|
+
equal(typeof o.err.type, 'undefined')
|
90
|
+
equal(typeof o.err.message, 'undefined')
|
91
|
+
equal(typeof o.err.stack, 'undefined')
|
92
|
+
})
|
93
|
+
|
94
|
+
test('serializers override values', async ({ equal }) => {
|
95
|
+
const stream = sink()
|
96
|
+
const parent = pino({ serializers: parentSerializers }, stream)
|
97
|
+
parent.child({}, { serializers: childSerializers })
|
98
|
+
|
99
|
+
parent.fatal({ test: 'test' })
|
100
|
+
const o = await once(stream, 'data')
|
101
|
+
equal(o.test, 'parent')
|
102
|
+
})
|
103
|
+
|
104
|
+
test('child does not overwrite parent serializers', async ({ equal }) => {
|
105
|
+
const stream = sink()
|
106
|
+
const parent = pino({ serializers: parentSerializers }, stream)
|
107
|
+
const child = parent.child({}, { serializers: childSerializers })
|
108
|
+
|
109
|
+
parent.fatal({ test: 'test' })
|
110
|
+
|
111
|
+
const o = once(stream, 'data')
|
112
|
+
equal((await o).test, 'parent')
|
113
|
+
const o2 = once(stream, 'data')
|
114
|
+
child.fatal({ test: 'test' })
|
115
|
+
equal((await o2).test, 'child')
|
116
|
+
})
|
117
|
+
|
118
|
+
test('Symbol.for(\'pino.serializers\')', async ({ equal, same, not }) => {
|
119
|
+
const stream = sink()
|
120
|
+
const expected = Object.assign({
|
121
|
+
err: stdSerializers.err
|
122
|
+
}, parentSerializers)
|
123
|
+
const parent = pino({ serializers: parentSerializers }, stream)
|
124
|
+
const child = parent.child({ a: 'property' })
|
125
|
+
|
126
|
+
same(parent[Symbol.for('pino.serializers')], expected)
|
127
|
+
same(child[Symbol.for('pino.serializers')], expected)
|
128
|
+
equal(parent[Symbol.for('pino.serializers')], child[Symbol.for('pino.serializers')])
|
129
|
+
|
130
|
+
const child2 = parent.child({}, {
|
131
|
+
serializers: {
|
132
|
+
a
|
133
|
+
}
|
134
|
+
})
|
135
|
+
|
136
|
+
function a () {
|
137
|
+
return 'hello'
|
138
|
+
}
|
139
|
+
|
140
|
+
not(child2[Symbol.for('pino.serializers')], parentSerializers)
|
141
|
+
equal(child2[Symbol.for('pino.serializers')].a, a)
|
142
|
+
equal(child2[Symbol.for('pino.serializers')].test, parentSerializers.test)
|
143
|
+
})
|
144
|
+
|
145
|
+
test('children inherit parent serializers', async ({ equal }) => {
|
146
|
+
const stream = sink()
|
147
|
+
const parent = pino({ serializers: parentSerializers }, stream)
|
148
|
+
|
149
|
+
const child = parent.child({ a: 'property' })
|
150
|
+
child.fatal({ test: 'test' })
|
151
|
+
const o = await once(stream, 'data')
|
152
|
+
equal(o.test, 'parent')
|
153
|
+
})
|
154
|
+
|
155
|
+
test('children inherit parent Symbol serializers', async ({ equal, same, not }) => {
|
156
|
+
const stream = sink()
|
157
|
+
const symbolSerializers = {
|
158
|
+
[Symbol.for('b')]: b
|
159
|
+
}
|
160
|
+
const expected = Object.assign({
|
161
|
+
err: stdSerializers.err
|
162
|
+
}, symbolSerializers)
|
163
|
+
const parent = pino({ serializers: symbolSerializers }, stream)
|
164
|
+
|
165
|
+
same(parent[Symbol.for('pino.serializers')], expected)
|
166
|
+
|
167
|
+
const child = parent.child({}, {
|
168
|
+
serializers: {
|
169
|
+
[Symbol.for('a')]: a,
|
170
|
+
a
|
171
|
+
}
|
172
|
+
})
|
173
|
+
|
174
|
+
function a () {
|
175
|
+
return 'hello'
|
176
|
+
}
|
177
|
+
|
178
|
+
function b () {
|
179
|
+
return 'world'
|
180
|
+
}
|
181
|
+
|
182
|
+
same(child[Symbol.for('pino.serializers')].a, a)
|
183
|
+
same(child[Symbol.for('pino.serializers')][Symbol.for('b')], b)
|
184
|
+
same(child[Symbol.for('pino.serializers')][Symbol.for('a')], a)
|
185
|
+
})
|
186
|
+
|
187
|
+
test('children serializers get called', async ({ equal }) => {
|
188
|
+
const stream = sink()
|
189
|
+
const parent = pino({
|
190
|
+
test: 'this'
|
191
|
+
}, stream)
|
192
|
+
|
193
|
+
const child = parent.child({ a: 'property' }, { serializers: childSerializers })
|
194
|
+
|
195
|
+
child.fatal({ test: 'test' })
|
196
|
+
const o = await once(stream, 'data')
|
197
|
+
equal(o.test, 'child')
|
198
|
+
})
|
199
|
+
|
200
|
+
test('children serializers get called when inherited from parent', async ({ equal }) => {
|
201
|
+
const stream = sink()
|
202
|
+
const parent = pino({
|
203
|
+
test: 'this',
|
204
|
+
serializers: parentSerializers
|
205
|
+
}, stream)
|
206
|
+
|
207
|
+
const child = parent.child({}, { serializers: { test: function () { return 'pass' } } })
|
208
|
+
|
209
|
+
child.fatal({ test: 'fail' })
|
210
|
+
const o = await once(stream, 'data')
|
211
|
+
equal(o.test, 'pass')
|
212
|
+
})
|
213
|
+
|
214
|
+
test('non-overridden serializers are available in the children', async ({ equal }) => {
|
215
|
+
const stream = sink()
|
216
|
+
const pSerializers = {
|
217
|
+
onlyParent: function () { return 'parent' },
|
218
|
+
shared: function () { return 'parent' }
|
219
|
+
}
|
220
|
+
|
221
|
+
const cSerializers = {
|
222
|
+
shared: function () { return 'child' },
|
223
|
+
onlyChild: function () { return 'child' }
|
224
|
+
}
|
225
|
+
|
226
|
+
const parent = pino({ serializers: pSerializers }, stream)
|
227
|
+
|
228
|
+
const child = parent.child({}, { serializers: cSerializers })
|
229
|
+
|
230
|
+
const o = once(stream, 'data')
|
231
|
+
child.fatal({ shared: 'test' })
|
232
|
+
equal((await o).shared, 'child')
|
233
|
+
const o2 = once(stream, 'data')
|
234
|
+
child.fatal({ onlyParent: 'test' })
|
235
|
+
equal((await o2).onlyParent, 'parent')
|
236
|
+
const o3 = once(stream, 'data')
|
237
|
+
child.fatal({ onlyChild: 'test' })
|
238
|
+
equal((await o3).onlyChild, 'child')
|
239
|
+
const o4 = once(stream, 'data')
|
240
|
+
parent.fatal({ onlyChild: 'test' })
|
241
|
+
equal((await o4).onlyChild, 'test')
|
242
|
+
})
|
243
|
+
|
244
|
+
test('custom serializer for messageKey', async (t) => {
|
245
|
+
const stream = sink()
|
246
|
+
const instance = pino({ serializers: { msg: () => '422' } }, stream)
|
247
|
+
|
248
|
+
const o = { num: NaN }
|
249
|
+
instance.info(o, 42)
|
250
|
+
|
251
|
+
const { msg } = await once(stream, 'data')
|
252
|
+
t.equal(msg, '422')
|
253
|
+
})
|
@@ -0,0 +1,39 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const { test } = require('tap')
|
4
|
+
const { join } = require('node:path')
|
5
|
+
const { fork } = require('node:child_process')
|
6
|
+
const { once } = require('./helper')
|
7
|
+
const writer = require('flush-write-stream')
|
8
|
+
const pino = require('..')
|
9
|
+
|
10
|
+
test('do not use SonicBoom is someone tampered with process.stdout.write', async ({ not }) => {
|
11
|
+
let actual = ''
|
12
|
+
const child = fork(join(__dirname, 'fixtures', 'stdout-hack-protection.js'), { silent: true })
|
13
|
+
|
14
|
+
child.stdout.pipe(writer((s, enc, cb) => {
|
15
|
+
actual += s
|
16
|
+
cb()
|
17
|
+
}))
|
18
|
+
await once(child, 'close')
|
19
|
+
not(actual.match(/^hack/), null)
|
20
|
+
})
|
21
|
+
|
22
|
+
test('do not use SonicBoom is someone has passed process.stdout to pino', async ({ equal }) => {
|
23
|
+
const logger = pino(process.stdout)
|
24
|
+
equal(logger[pino.symbols.streamSym], process.stdout)
|
25
|
+
})
|
26
|
+
|
27
|
+
test('do not crash if process.stdout has no fd', async ({ teardown }) => {
|
28
|
+
const fd = process.stdout.fd
|
29
|
+
delete process.stdout.fd
|
30
|
+
teardown(function () { process.stdout.fd = fd })
|
31
|
+
pino()
|
32
|
+
})
|
33
|
+
|
34
|
+
test('use fd=1 if process.stdout has no fd in pino.destination() (worker case)', async ({ teardown }) => {
|
35
|
+
const fd = process.stdout.fd
|
36
|
+
delete process.stdout.fd
|
37
|
+
teardown(function () { process.stdout.fd = fd })
|
38
|
+
pino.destination()
|
39
|
+
})
|
@@ -0,0 +1,188 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const os = require('node:os')
|
4
|
+
const { promises: { readFile }, createWriteStream } = require('node:fs')
|
5
|
+
const { join } = require('node:path')
|
6
|
+
const { test } = require('tap')
|
7
|
+
const { fork } = require('node:child_process')
|
8
|
+
const writer = require('flush-write-stream')
|
9
|
+
const {
|
10
|
+
once,
|
11
|
+
getPathToNull,
|
12
|
+
file,
|
13
|
+
watchFileCreated
|
14
|
+
} = require('./helper')
|
15
|
+
const { promisify } = require('node:util')
|
16
|
+
|
17
|
+
const sleep = promisify(setTimeout)
|
18
|
+
|
19
|
+
test('asynchronous logging', async ({
|
20
|
+
equal,
|
21
|
+
teardown
|
22
|
+
}) => {
|
23
|
+
const now = Date.now
|
24
|
+
const hostname = os.hostname
|
25
|
+
const proc = process
|
26
|
+
global.process = {
|
27
|
+
__proto__: process,
|
28
|
+
pid: 123456
|
29
|
+
}
|
30
|
+
Date.now = () => 1459875739796
|
31
|
+
os.hostname = () => 'abcdefghijklmnopqr'
|
32
|
+
delete require.cache[require.resolve('../')]
|
33
|
+
const pino = require('../')
|
34
|
+
let expected = ''
|
35
|
+
let actual = ''
|
36
|
+
const normal = pino(writer((s, enc, cb) => {
|
37
|
+
expected += s
|
38
|
+
cb()
|
39
|
+
}))
|
40
|
+
|
41
|
+
const dest = createWriteStream(getPathToNull())
|
42
|
+
dest.write = (s) => {
|
43
|
+
actual += s
|
44
|
+
}
|
45
|
+
const asyncLogger = pino(dest)
|
46
|
+
|
47
|
+
let i = 44
|
48
|
+
while (i--) {
|
49
|
+
normal.info('h')
|
50
|
+
asyncLogger.info('h')
|
51
|
+
}
|
52
|
+
|
53
|
+
const expected2 = expected.split('\n')[0]
|
54
|
+
let actual2 = ''
|
55
|
+
|
56
|
+
const child = fork(join(__dirname, '/fixtures/syncfalse.js'), { silent: true })
|
57
|
+
child.stdout.pipe(writer((s, enc, cb) => {
|
58
|
+
actual2 += s
|
59
|
+
cb()
|
60
|
+
}))
|
61
|
+
await once(child, 'close')
|
62
|
+
// Wait for the last write to be flushed
|
63
|
+
await sleep(100)
|
64
|
+
equal(actual, expected)
|
65
|
+
equal(actual2.trim(), expected2)
|
66
|
+
|
67
|
+
teardown(() => {
|
68
|
+
os.hostname = hostname
|
69
|
+
Date.now = now
|
70
|
+
global.process = proc
|
71
|
+
})
|
72
|
+
})
|
73
|
+
|
74
|
+
test('sync false with child', async ({
|
75
|
+
equal,
|
76
|
+
teardown
|
77
|
+
}) => {
|
78
|
+
const now = Date.now
|
79
|
+
const hostname = os.hostname
|
80
|
+
const proc = process
|
81
|
+
global.process = {
|
82
|
+
__proto__: process,
|
83
|
+
pid: 123456
|
84
|
+
}
|
85
|
+
Date.now = function () {
|
86
|
+
return 1459875739796
|
87
|
+
}
|
88
|
+
os.hostname = function () {
|
89
|
+
return 'abcdefghijklmnopqr'
|
90
|
+
}
|
91
|
+
delete require.cache[require.resolve('../')]
|
92
|
+
const pino = require('../')
|
93
|
+
let expected = ''
|
94
|
+
let actual = ''
|
95
|
+
const normal = pino(writer((s, enc, cb) => {
|
96
|
+
expected += s
|
97
|
+
cb()
|
98
|
+
})).child({ hello: 'world' })
|
99
|
+
|
100
|
+
const dest = createWriteStream(getPathToNull())
|
101
|
+
dest.write = function (s) {
|
102
|
+
actual += s
|
103
|
+
}
|
104
|
+
const asyncLogger = pino(dest).child({ hello: 'world' })
|
105
|
+
|
106
|
+
let i = 500
|
107
|
+
while (i--) {
|
108
|
+
normal.info('h')
|
109
|
+
asyncLogger.info('h')
|
110
|
+
}
|
111
|
+
|
112
|
+
asyncLogger.flush()
|
113
|
+
|
114
|
+
const expected2 = expected.split('\n')[0]
|
115
|
+
let actual2 = ''
|
116
|
+
|
117
|
+
const child = fork(join(__dirname, '/fixtures/syncfalse-child.js'), { silent: true })
|
118
|
+
child.stdout.pipe(writer((s, enc, cb) => {
|
119
|
+
actual2 += s
|
120
|
+
cb()
|
121
|
+
}))
|
122
|
+
await once(child, 'close')
|
123
|
+
equal(actual, expected)
|
124
|
+
equal(actual2.trim(), expected2)
|
125
|
+
|
126
|
+
teardown(() => {
|
127
|
+
os.hostname = hostname
|
128
|
+
Date.now = now
|
129
|
+
global.process = proc
|
130
|
+
})
|
131
|
+
})
|
132
|
+
|
133
|
+
test('flush does nothing with sync true (default)', async ({ equal }) => {
|
134
|
+
const instance = require('..')()
|
135
|
+
equal(instance.flush(), undefined)
|
136
|
+
})
|
137
|
+
|
138
|
+
test('should still call flush callback even when does nothing with sync true (default)', (t) => {
|
139
|
+
t.plan(3)
|
140
|
+
const instance = require('..')()
|
141
|
+
instance.flush((...args) => {
|
142
|
+
t.ok('flush called')
|
143
|
+
t.same(args, [])
|
144
|
+
|
145
|
+
// next tick to make flush not called more than once
|
146
|
+
process.nextTick(() => {
|
147
|
+
t.ok('flush next tick called')
|
148
|
+
})
|
149
|
+
})
|
150
|
+
})
|
151
|
+
|
152
|
+
test('should call the flush callback when flushed the data for async logger', async (t) => {
|
153
|
+
const outputPath = file()
|
154
|
+
async function getOutputLogLines () {
|
155
|
+
return (await readFile(outputPath)).toString().trim().split('\n').map(JSON.parse)
|
156
|
+
}
|
157
|
+
|
158
|
+
const pino = require('../')
|
159
|
+
|
160
|
+
const instance = pino({}, pino.destination({
|
161
|
+
dest: outputPath,
|
162
|
+
|
163
|
+
// to make sure it does not flush on its own
|
164
|
+
minLength: 4096
|
165
|
+
}))
|
166
|
+
const flushPromise = promisify(instance.flush).bind(instance)
|
167
|
+
|
168
|
+
instance.info('hello')
|
169
|
+
await flushPromise()
|
170
|
+
await watchFileCreated(outputPath)
|
171
|
+
|
172
|
+
const [firstFlushData] = await getOutputLogLines()
|
173
|
+
|
174
|
+
t.equal(firstFlushData.msg, 'hello')
|
175
|
+
|
176
|
+
// should not flush this as no data accumulated that's bigger than min length
|
177
|
+
instance.info('world')
|
178
|
+
|
179
|
+
// Making sure data is not flushed yet
|
180
|
+
const afterLogData = await getOutputLogLines()
|
181
|
+
t.equal(afterLogData.length, 1)
|
182
|
+
|
183
|
+
await flushPromise()
|
184
|
+
|
185
|
+
// Making sure data is not flushed yet
|
186
|
+
const afterSecondFlush = (await getOutputLogLines())[1]
|
187
|
+
t.equal(afterSecondFlush.msg, 'world')
|
188
|
+
})
|
@@ -0,0 +1,121 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
/* eslint no-prototype-builtins: 0 */
|
4
|
+
|
5
|
+
const { test } = require('tap')
|
6
|
+
const { sink, once } = require('./helper')
|
7
|
+
const pino = require('../')
|
8
|
+
|
9
|
+
test('pino exposes standard time functions', async ({ ok }) => {
|
10
|
+
ok(pino.stdTimeFunctions)
|
11
|
+
ok(pino.stdTimeFunctions.epochTime)
|
12
|
+
ok(pino.stdTimeFunctions.unixTime)
|
13
|
+
ok(pino.stdTimeFunctions.nullTime)
|
14
|
+
ok(pino.stdTimeFunctions.isoTime)
|
15
|
+
})
|
16
|
+
|
17
|
+
test('pino accepts external time functions', async ({ equal }) => {
|
18
|
+
const opts = {
|
19
|
+
timestamp: () => ',"time":"none"'
|
20
|
+
}
|
21
|
+
const stream = sink()
|
22
|
+
const instance = pino(opts, stream)
|
23
|
+
instance.info('foobar')
|
24
|
+
const result = await once(stream, 'data')
|
25
|
+
equal(result.hasOwnProperty('time'), true)
|
26
|
+
equal(result.time, 'none')
|
27
|
+
})
|
28
|
+
|
29
|
+
test('pino accepts external time functions with custom label', async ({ equal }) => {
|
30
|
+
const opts = {
|
31
|
+
timestamp: () => ',"custom-time-label":"none"'
|
32
|
+
}
|
33
|
+
const stream = sink()
|
34
|
+
const instance = pino(opts, stream)
|
35
|
+
instance.info('foobar')
|
36
|
+
const result = await once(stream, 'data')
|
37
|
+
equal(result.hasOwnProperty('custom-time-label'), true)
|
38
|
+
equal(result['custom-time-label'], 'none')
|
39
|
+
})
|
40
|
+
|
41
|
+
test('inserts timestamp by default', async ({ ok, equal }) => {
|
42
|
+
const stream = sink()
|
43
|
+
const instance = pino(stream)
|
44
|
+
instance.info('foobar')
|
45
|
+
const result = await once(stream, 'data')
|
46
|
+
equal(result.hasOwnProperty('time'), true)
|
47
|
+
ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
|
48
|
+
equal(result.msg, 'foobar')
|
49
|
+
})
|
50
|
+
|
51
|
+
test('omits timestamp when timestamp option is false', async ({ equal }) => {
|
52
|
+
const stream = sink()
|
53
|
+
const instance = pino({ timestamp: false }, stream)
|
54
|
+
instance.info('foobar')
|
55
|
+
const result = await once(stream, 'data')
|
56
|
+
equal(result.hasOwnProperty('time'), false)
|
57
|
+
equal(result.msg, 'foobar')
|
58
|
+
})
|
59
|
+
|
60
|
+
test('inserts timestamp when timestamp option is true', async ({ ok, equal }) => {
|
61
|
+
const stream = sink()
|
62
|
+
const instance = pino({ timestamp: true }, stream)
|
63
|
+
instance.info('foobar')
|
64
|
+
const result = await once(stream, 'data')
|
65
|
+
equal(result.hasOwnProperty('time'), true)
|
66
|
+
ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
|
67
|
+
equal(result.msg, 'foobar')
|
68
|
+
})
|
69
|
+
|
70
|
+
test('child inserts timestamp by default', async ({ ok, equal }) => {
|
71
|
+
const stream = sink()
|
72
|
+
const logger = pino(stream)
|
73
|
+
const instance = logger.child({ component: 'child' })
|
74
|
+
instance.info('foobar')
|
75
|
+
const result = await once(stream, 'data')
|
76
|
+
equal(result.hasOwnProperty('time'), true)
|
77
|
+
ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
|
78
|
+
equal(result.msg, 'foobar')
|
79
|
+
})
|
80
|
+
|
81
|
+
test('child omits timestamp with option', async ({ equal }) => {
|
82
|
+
const stream = sink()
|
83
|
+
const logger = pino({ timestamp: false }, stream)
|
84
|
+
const instance = logger.child({ component: 'child' })
|
85
|
+
instance.info('foobar')
|
86
|
+
const result = await once(stream, 'data')
|
87
|
+
equal(result.hasOwnProperty('time'), false)
|
88
|
+
equal(result.msg, 'foobar')
|
89
|
+
})
|
90
|
+
|
91
|
+
test('pino.stdTimeFunctions.unixTime returns seconds based timestamps', async ({ equal }) => {
|
92
|
+
const opts = {
|
93
|
+
timestamp: pino.stdTimeFunctions.unixTime
|
94
|
+
}
|
95
|
+
const stream = sink()
|
96
|
+
const instance = pino(opts, stream)
|
97
|
+
const now = Date.now
|
98
|
+
Date.now = () => 1531069919686
|
99
|
+
instance.info('foobar')
|
100
|
+
const result = await once(stream, 'data')
|
101
|
+
equal(result.hasOwnProperty('time'), true)
|
102
|
+
equal(result.time, 1531069920)
|
103
|
+
Date.now = now
|
104
|
+
})
|
105
|
+
|
106
|
+
test('pino.stdTimeFunctions.isoTime returns ISO 8601 timestamps', async ({ equal }) => {
|
107
|
+
const opts = {
|
108
|
+
timestamp: pino.stdTimeFunctions.isoTime
|
109
|
+
}
|
110
|
+
const stream = sink()
|
111
|
+
const instance = pino(opts, stream)
|
112
|
+
const ms = 1531069919686
|
113
|
+
const now = Date.now
|
114
|
+
Date.now = () => ms
|
115
|
+
const iso = new Date(ms).toISOString()
|
116
|
+
instance.info('foobar')
|
117
|
+
const result = await once(stream, 'data')
|
118
|
+
equal(result.hasOwnProperty('time'), true)
|
119
|
+
equal(result.time, iso)
|
120
|
+
Date.now = now
|
121
|
+
})
|
@@ -0,0 +1,43 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
3
|
+
const { test } = require('tap')
|
4
|
+
const { join } = require('node:path')
|
5
|
+
const { createReadStream } = require('node:fs')
|
6
|
+
const { promisify } = require('node:util')
|
7
|
+
const execa = require('execa')
|
8
|
+
const split = require('split2')
|
9
|
+
const stream = require('node:stream')
|
10
|
+
const { file } = require('../helper')
|
11
|
+
|
12
|
+
const pipeline = promisify(stream.pipeline)
|
13
|
+
const { Writable } = stream
|
14
|
+
const sleep = promisify(setTimeout)
|
15
|
+
|
16
|
+
const skip = process.env.CI || process.env.CITGM
|
17
|
+
|
18
|
+
test('eight million lines', { skip }, async ({ equal, comment }) => {
|
19
|
+
const destination = file()
|
20
|
+
await execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-many-lines.js'), destination])
|
21
|
+
|
22
|
+
if (process.platform !== 'win32') {
|
23
|
+
try {
|
24
|
+
await execa('sync') // Wait for the file to be written to disk
|
25
|
+
} catch {
|
26
|
+
// Just a fallback, this should be unreachable
|
27
|
+
}
|
28
|
+
}
|
29
|
+
await sleep(1000) // It seems that sync is not enough (even in POSIX systems)
|
30
|
+
|
31
|
+
const toWrite = 8 * 1000000
|
32
|
+
let count = 0
|
33
|
+
await pipeline(createReadStream(destination), split(), new Writable({
|
34
|
+
write (chunk, enc, cb) {
|
35
|
+
if (count % (toWrite / 10) === 0) {
|
36
|
+
comment(`read ${count}`)
|
37
|
+
}
|
38
|
+
count++
|
39
|
+
cb()
|
40
|
+
}
|
41
|
+
}))
|
42
|
+
equal(count, toWrite)
|
43
|
+
})
|