fastify 4.15.0 → 4.16.1
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/README.md +3 -3
- package/docs/Guides/Database.md +7 -8
- package/docs/Guides/Ecosystem.md +16 -7
- package/docs/Guides/Getting-Started.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +21 -0
- package/docs/Guides/Plugins-Guide.md +1 -1
- package/docs/Guides/Prototype-Poisoning.md +31 -39
- package/docs/Guides/Recommendations.md +1 -1
- package/docs/Guides/Write-Type-Provider.md +3 -3
- package/docs/Reference/Hooks.md +42 -9
- package/docs/Reference/Reply.md +2 -2
- package/docs/Reference/Routes.md +13 -2
- package/docs/Reference/Server.md +19 -3
- package/docs/Reference/Type-Providers.md +1 -1
- package/docs/Reference/TypeScript.md +3 -3
- package/docs/index.md +2 -2
- package/examples/benchmark/parser.js +47 -0
- package/fastify.js +26 -23
- package/lib/error-serializer.js +9 -162
- package/lib/hooks.js +3 -0
- package/lib/server.js +9 -4
- package/lib/validation.js +10 -8
- package/lib/warnings.js +2 -0
- package/package.json +8 -7
- package/test/close.test.js +91 -0
- package/test/route-hooks.test.js +29 -0
- package/test/route.test.js +1 -1
- package/test/schema-feature.test.js +128 -35
- package/test/serial/logger.0.test.js +861 -0
- package/test/serial/logger.1.test.js +862 -0
- package/test/serial/tap-parallel-not-ok +0 -0
- package/test/server.test.js +10 -0
- package/test/types/hooks.test-d.ts +66 -11
- package/test/types/import.js +1 -1
- package/test/types/instance.test-d.ts +2 -0
- package/test/types/route.test-d.ts +106 -5
- package/test/types/type-provider.test-d.ts +77 -10
- package/types/hooks.d.ts +28 -0
- package/types/instance.d.ts +20 -1
- package/types/logger.d.ts +1 -1
- package/types/route.d.ts +41 -11
- package/test/logger.test.js +0 -1721
package/test/logger.test.js
DELETED
|
@@ -1,1721 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { test, teardown, before } = require('tap')
|
|
4
|
-
const http = require('http')
|
|
5
|
-
const stream = require('stream')
|
|
6
|
-
const split = require('split2')
|
|
7
|
-
const Fastify = require('..')
|
|
8
|
-
const pino = require('pino')
|
|
9
|
-
const path = require('path')
|
|
10
|
-
const os = require('os')
|
|
11
|
-
const fs = require('fs')
|
|
12
|
-
const sget = require('simple-get').concat
|
|
13
|
-
const dns = require('dns')
|
|
14
|
-
|
|
15
|
-
const helper = require('./helper')
|
|
16
|
-
const { FST_ERR_LOG_INVALID_LOGGER } = require('../lib/errors')
|
|
17
|
-
|
|
18
|
-
const files = []
|
|
19
|
-
let count = 0
|
|
20
|
-
let localhost
|
|
21
|
-
let localhostForURL
|
|
22
|
-
|
|
23
|
-
function file () {
|
|
24
|
-
const file = path.join(os.tmpdir(), `sonic-boom-${process.pid}-${process.hrtime().toString()}-${count++}`)
|
|
25
|
-
files.push(file)
|
|
26
|
-
return file
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
before(async function () {
|
|
30
|
-
[localhost, localhostForURL] = await helper.getLoopbackHost()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
if (process.env.CI) {
|
|
34
|
-
teardown(() => {
|
|
35
|
-
files.forEach((file) => {
|
|
36
|
-
try {
|
|
37
|
-
fs.unlinkSync(file)
|
|
38
|
-
} catch (e) {
|
|
39
|
-
console.log(e)
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
test('defaults to info level', t => {
|
|
46
|
-
let fastify = null
|
|
47
|
-
const stream = split(JSON.parse)
|
|
48
|
-
try {
|
|
49
|
-
fastify = Fastify({
|
|
50
|
-
logger: {
|
|
51
|
-
stream
|
|
52
|
-
}
|
|
53
|
-
})
|
|
54
|
-
} catch (e) {
|
|
55
|
-
t.fail()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
fastify.get('/', function (req, reply) {
|
|
59
|
-
t.ok(req.log)
|
|
60
|
-
reply.send({ hello: 'world' })
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
fastify.listen({ port: 0 }, err => {
|
|
64
|
-
t.error(err)
|
|
65
|
-
t.teardown(() => { fastify.close() })
|
|
66
|
-
|
|
67
|
-
dns.lookup('localhost', { all: true }, function (err, addresses) {
|
|
68
|
-
t.error(err)
|
|
69
|
-
let toSkip = addresses.length
|
|
70
|
-
|
|
71
|
-
function skip (data) {
|
|
72
|
-
if (--toSkip === 0) {
|
|
73
|
-
stream.removeListener('data', skip)
|
|
74
|
-
check()
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
stream.on('data', skip)
|
|
79
|
-
|
|
80
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port)
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
function check () {
|
|
85
|
-
stream.once('data', line => {
|
|
86
|
-
const id = line.reqId
|
|
87
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
88
|
-
t.ok(line.req, 'req is defined')
|
|
89
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
90
|
-
t.equal(line.req.method, 'GET', 'method is get')
|
|
91
|
-
|
|
92
|
-
stream.once('data', line => {
|
|
93
|
-
t.equal(line.reqId, id)
|
|
94
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
95
|
-
t.ok(line.res, 'res is defined')
|
|
96
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
97
|
-
t.equal(line.res.statusCode, 200, 'statusCode is 200')
|
|
98
|
-
t.ok(line.responseTime, 'responseTime is defined')
|
|
99
|
-
t.end()
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
test('test log stream', t => {
|
|
106
|
-
t.plan(12)
|
|
107
|
-
let fastify = null
|
|
108
|
-
const stream = split(JSON.parse)
|
|
109
|
-
try {
|
|
110
|
-
fastify = Fastify({
|
|
111
|
-
logger: {
|
|
112
|
-
stream,
|
|
113
|
-
level: 'info'
|
|
114
|
-
}
|
|
115
|
-
})
|
|
116
|
-
} catch (e) {
|
|
117
|
-
t.fail()
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
fastify.get('/', function (req, reply) {
|
|
121
|
-
t.ok(req.log)
|
|
122
|
-
reply.send({ hello: 'world' })
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
126
|
-
t.error(err)
|
|
127
|
-
t.teardown(() => { fastify.close() })
|
|
128
|
-
|
|
129
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port)
|
|
130
|
-
stream.once('data', listenAtLogLine => {
|
|
131
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
132
|
-
|
|
133
|
-
stream.once('data', line => {
|
|
134
|
-
const id = line.reqId
|
|
135
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
136
|
-
t.ok(line.req, 'req is defined')
|
|
137
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
138
|
-
t.equal(line.req.method, 'GET', 'method is get')
|
|
139
|
-
|
|
140
|
-
stream.once('data', line => {
|
|
141
|
-
t.equal(line.reqId, id)
|
|
142
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
143
|
-
t.ok(line.res, 'res is defined')
|
|
144
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
145
|
-
t.equal(line.res.statusCode, 200, 'statusCode is 200')
|
|
146
|
-
})
|
|
147
|
-
})
|
|
148
|
-
})
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
test('test error log stream', t => {
|
|
153
|
-
t.plan(11)
|
|
154
|
-
let fastify = null
|
|
155
|
-
const stream = split(JSON.parse)
|
|
156
|
-
try {
|
|
157
|
-
fastify = Fastify({
|
|
158
|
-
logger: {
|
|
159
|
-
stream,
|
|
160
|
-
level: 'info'
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
} catch (e) {
|
|
164
|
-
t.fail()
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
fastify.get('/error', function (req, reply) {
|
|
168
|
-
t.ok(req.log)
|
|
169
|
-
reply.send(new Error('kaboom'))
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
173
|
-
t.error(err)
|
|
174
|
-
t.teardown(() => { fastify.close() })
|
|
175
|
-
|
|
176
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
177
|
-
stream.once('data', listenAtLogLine => {
|
|
178
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
179
|
-
|
|
180
|
-
stream.once('data', line => {
|
|
181
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
182
|
-
t.ok(line.req, 'req is defined')
|
|
183
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
184
|
-
t.equal(line.req.method, 'GET', 'method is get')
|
|
185
|
-
|
|
186
|
-
stream.once('data', line => {
|
|
187
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
188
|
-
t.ok(line.res, 'res is defined')
|
|
189
|
-
t.equal(line.msg, 'kaboom', 'message is set')
|
|
190
|
-
t.equal(line.res.statusCode, 500, 'statusCode is 500')
|
|
191
|
-
})
|
|
192
|
-
})
|
|
193
|
-
})
|
|
194
|
-
})
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
test('can use external logger instance', t => {
|
|
198
|
-
const lines = [/^Server listening at /, /^incoming request$/, /^log success$/, /^request completed$/]
|
|
199
|
-
t.plan(lines.length + 2)
|
|
200
|
-
|
|
201
|
-
const splitStream = split(JSON.parse)
|
|
202
|
-
splitStream.on('data', (line) => {
|
|
203
|
-
const regex = lines.shift()
|
|
204
|
-
t.ok(regex.test(line.msg), '"' + line.msg + '" dont match "' + regex + '"')
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
const logger = require('pino')(splitStream)
|
|
208
|
-
|
|
209
|
-
const localFastify = Fastify({ logger })
|
|
210
|
-
|
|
211
|
-
localFastify.get('/foo', function (req, reply) {
|
|
212
|
-
t.ok(req.log)
|
|
213
|
-
req.log.info('log success')
|
|
214
|
-
reply.send({ hello: 'world' })
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
localFastify.listen({ port: 0, host: localhost }, err => {
|
|
218
|
-
t.error(err)
|
|
219
|
-
http.get(`http://${localhostForURL}:` + localFastify.server.address().port + '/foo', (res) => {
|
|
220
|
-
res.resume()
|
|
221
|
-
res.on('end', () => {
|
|
222
|
-
localFastify.server.close()
|
|
223
|
-
})
|
|
224
|
-
})
|
|
225
|
-
})
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
test('can use external logger instance with custom serializer', t => {
|
|
229
|
-
const lines = [['level', 30], ['req', { url: '/foo' }], ['level', 30], ['res', { statusCode: 200 }]]
|
|
230
|
-
t.plan(lines.length + 2)
|
|
231
|
-
|
|
232
|
-
const splitStream = split(JSON.parse)
|
|
233
|
-
splitStream.on('data', (line) => {
|
|
234
|
-
const check = lines.shift()
|
|
235
|
-
const key = check[0]
|
|
236
|
-
const value = check[1]
|
|
237
|
-
|
|
238
|
-
t.same(line[key], value)
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
const logger = require('pino')({
|
|
242
|
-
level: 'info',
|
|
243
|
-
serializers: {
|
|
244
|
-
req: function (req) {
|
|
245
|
-
return {
|
|
246
|
-
url: req.url
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}, splitStream)
|
|
251
|
-
|
|
252
|
-
const localFastify = Fastify({
|
|
253
|
-
logger
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
localFastify.get('/foo', function (req, reply) {
|
|
257
|
-
t.ok(req.log)
|
|
258
|
-
req.log.info('log success')
|
|
259
|
-
reply.send({ hello: 'world' })
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
localFastify.listen({ port: 0, host: localhost }, err => {
|
|
263
|
-
t.error(err)
|
|
264
|
-
http.get(`http://${localhostForURL}:` + localFastify.server.address().port + '/foo', (res) => {
|
|
265
|
-
res.resume()
|
|
266
|
-
res.on('end', () => {
|
|
267
|
-
localFastify.server.close()
|
|
268
|
-
})
|
|
269
|
-
})
|
|
270
|
-
})
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
test('should throw in case the external logger provided does not have a child method', t => {
|
|
274
|
-
t.plan(1)
|
|
275
|
-
const loggerInstance = {
|
|
276
|
-
info: console.info,
|
|
277
|
-
error: console.error,
|
|
278
|
-
debug: console.debug,
|
|
279
|
-
fatal: console.error,
|
|
280
|
-
warn: console.warn,
|
|
281
|
-
trace: console.trace
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
t.throws(
|
|
285
|
-
() => Fastify({ logger: loggerInstance }),
|
|
286
|
-
FST_ERR_LOG_INVALID_LOGGER,
|
|
287
|
-
"Invalid logger object provided. The logger instance should have these functions(s): 'child'."
|
|
288
|
-
)
|
|
289
|
-
})
|
|
290
|
-
|
|
291
|
-
test('should throw in case a partially matching logger is provided', t => {
|
|
292
|
-
t.plan(1)
|
|
293
|
-
|
|
294
|
-
t.throws(
|
|
295
|
-
() => Fastify({ logger: console }),
|
|
296
|
-
FST_ERR_LOG_INVALID_LOGGER,
|
|
297
|
-
"Invalid logger object provided. The logger instance should have these functions(s): 'fatal,child'."
|
|
298
|
-
)
|
|
299
|
-
})
|
|
300
|
-
|
|
301
|
-
test('expose the logger', t => {
|
|
302
|
-
t.plan(2)
|
|
303
|
-
let fastify = null
|
|
304
|
-
const stream = split(JSON.parse)
|
|
305
|
-
try {
|
|
306
|
-
fastify = Fastify({
|
|
307
|
-
logger: {
|
|
308
|
-
stream,
|
|
309
|
-
level: 'info'
|
|
310
|
-
}
|
|
311
|
-
})
|
|
312
|
-
} catch (e) {
|
|
313
|
-
t.fail()
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
t.ok(fastify.log)
|
|
317
|
-
t.same(typeof fastify.log, 'object')
|
|
318
|
-
})
|
|
319
|
-
|
|
320
|
-
test('The request id header key can be customized', t => {
|
|
321
|
-
t.plan(9)
|
|
322
|
-
const REQUEST_ID = '42'
|
|
323
|
-
|
|
324
|
-
const stream = split(JSON.parse)
|
|
325
|
-
const fastify = Fastify({
|
|
326
|
-
logger: { stream, level: 'info' },
|
|
327
|
-
requestIdHeader: 'my-custom-request-id'
|
|
328
|
-
})
|
|
329
|
-
t.teardown(() => fastify.close())
|
|
330
|
-
|
|
331
|
-
fastify.get('/', (req, reply) => {
|
|
332
|
-
t.equal(req.id, REQUEST_ID)
|
|
333
|
-
req.log.info('some log message')
|
|
334
|
-
reply.send({ id: req.id })
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
fastify.inject({
|
|
338
|
-
method: 'GET',
|
|
339
|
-
url: '/',
|
|
340
|
-
headers: {
|
|
341
|
-
'my-custom-request-id': REQUEST_ID
|
|
342
|
-
}
|
|
343
|
-
}, (err, res) => {
|
|
344
|
-
t.error(err)
|
|
345
|
-
const payload = JSON.parse(res.payload)
|
|
346
|
-
t.equal(payload.id, REQUEST_ID)
|
|
347
|
-
|
|
348
|
-
stream.once('data', line => {
|
|
349
|
-
t.equal(line.reqId, REQUEST_ID)
|
|
350
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
351
|
-
|
|
352
|
-
stream.once('data', line => {
|
|
353
|
-
t.equal(line.reqId, REQUEST_ID)
|
|
354
|
-
t.equal(line.msg, 'some log message', 'message is set')
|
|
355
|
-
|
|
356
|
-
stream.once('data', line => {
|
|
357
|
-
t.equal(line.reqId, REQUEST_ID)
|
|
358
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
359
|
-
})
|
|
360
|
-
})
|
|
361
|
-
})
|
|
362
|
-
})
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
test('The request id header key can be ignored', t => {
|
|
366
|
-
t.plan(9)
|
|
367
|
-
const REQUEST_ID = 'ignore-me'
|
|
368
|
-
|
|
369
|
-
const stream = split(JSON.parse)
|
|
370
|
-
const fastify = Fastify({
|
|
371
|
-
logger: { stream, level: 'info' },
|
|
372
|
-
requestIdHeader: false
|
|
373
|
-
})
|
|
374
|
-
t.teardown(() => fastify.close())
|
|
375
|
-
|
|
376
|
-
fastify.get('/', (req, reply) => {
|
|
377
|
-
t.equal(req.id, 'req-1')
|
|
378
|
-
req.log.info('some log message')
|
|
379
|
-
reply.send({ id: req.id })
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
fastify.inject({
|
|
383
|
-
method: 'GET',
|
|
384
|
-
url: '/',
|
|
385
|
-
headers: {
|
|
386
|
-
'request-id': REQUEST_ID
|
|
387
|
-
}
|
|
388
|
-
}, (err, res) => {
|
|
389
|
-
t.error(err)
|
|
390
|
-
const payload = JSON.parse(res.payload)
|
|
391
|
-
t.equal(payload.id, 'req-1')
|
|
392
|
-
|
|
393
|
-
stream.once('data', line => {
|
|
394
|
-
t.equal(line.reqId, 'req-1')
|
|
395
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
396
|
-
|
|
397
|
-
stream.once('data', line => {
|
|
398
|
-
t.equal(line.reqId, 'req-1')
|
|
399
|
-
t.equal(line.msg, 'some log message', 'message is set')
|
|
400
|
-
|
|
401
|
-
stream.once('data', line => {
|
|
402
|
-
t.equal(line.reqId, 'req-1')
|
|
403
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
404
|
-
})
|
|
405
|
-
})
|
|
406
|
-
})
|
|
407
|
-
})
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
test('The request id header key can be customized along with a custom id generator', t => {
|
|
411
|
-
t.plan(12)
|
|
412
|
-
const REQUEST_ID = '42'
|
|
413
|
-
|
|
414
|
-
const stream = split(JSON.parse)
|
|
415
|
-
const fastify = Fastify({
|
|
416
|
-
logger: { stream, level: 'info' },
|
|
417
|
-
requestIdHeader: 'my-custom-request-id',
|
|
418
|
-
genReqId (req) {
|
|
419
|
-
return 'foo'
|
|
420
|
-
}
|
|
421
|
-
})
|
|
422
|
-
t.teardown(() => fastify.close())
|
|
423
|
-
|
|
424
|
-
fastify.get('/one', (req, reply) => {
|
|
425
|
-
t.equal(req.id, REQUEST_ID)
|
|
426
|
-
req.log.info('some log message')
|
|
427
|
-
reply.send({ id: req.id })
|
|
428
|
-
})
|
|
429
|
-
|
|
430
|
-
fastify.get('/two', (req, reply) => {
|
|
431
|
-
t.equal(req.id, 'foo')
|
|
432
|
-
req.log.info('some log message 2')
|
|
433
|
-
reply.send({ id: req.id })
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
const matches = [
|
|
437
|
-
{ reqId: REQUEST_ID, msg: /incoming request/ },
|
|
438
|
-
{ reqId: REQUEST_ID, msg: /some log message/ },
|
|
439
|
-
{ reqId: REQUEST_ID, msg: /request completed/ },
|
|
440
|
-
{ reqId: 'foo', msg: /incoming request/ },
|
|
441
|
-
{ reqId: 'foo', msg: /some log message 2/ },
|
|
442
|
-
{ reqId: 'foo', msg: /request completed/ }
|
|
443
|
-
]
|
|
444
|
-
|
|
445
|
-
let i = 0
|
|
446
|
-
stream.on('data', line => {
|
|
447
|
-
t.match(line, matches[i])
|
|
448
|
-
i += 1
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
fastify.inject({
|
|
452
|
-
method: 'GET',
|
|
453
|
-
url: '/one',
|
|
454
|
-
headers: {
|
|
455
|
-
'my-custom-request-id': REQUEST_ID
|
|
456
|
-
}
|
|
457
|
-
}, (err, res) => {
|
|
458
|
-
t.error(err)
|
|
459
|
-
const payload = JSON.parse(res.payload)
|
|
460
|
-
t.equal(payload.id, REQUEST_ID)
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
fastify.inject({
|
|
464
|
-
method: 'GET',
|
|
465
|
-
url: '/two'
|
|
466
|
-
}, (err, res) => {
|
|
467
|
-
t.error(err)
|
|
468
|
-
const payload = JSON.parse(res.payload)
|
|
469
|
-
t.equal(payload.id, 'foo')
|
|
470
|
-
})
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
test('The request id header key can be ignored along with a custom id generator', t => {
|
|
474
|
-
t.plan(12)
|
|
475
|
-
const REQUEST_ID = 'ignore-me'
|
|
476
|
-
|
|
477
|
-
const stream = split(JSON.parse)
|
|
478
|
-
const fastify = Fastify({
|
|
479
|
-
logger: { stream, level: 'info' },
|
|
480
|
-
requestIdHeader: false,
|
|
481
|
-
genReqId (req) {
|
|
482
|
-
return 'foo'
|
|
483
|
-
}
|
|
484
|
-
})
|
|
485
|
-
t.teardown(() => fastify.close())
|
|
486
|
-
|
|
487
|
-
fastify.get('/one', (req, reply) => {
|
|
488
|
-
t.equal(req.id, 'foo')
|
|
489
|
-
req.log.info('some log message')
|
|
490
|
-
reply.send({ id: req.id })
|
|
491
|
-
})
|
|
492
|
-
|
|
493
|
-
fastify.get('/two', (req, reply) => {
|
|
494
|
-
t.equal(req.id, 'foo')
|
|
495
|
-
req.log.info('some log message 2')
|
|
496
|
-
reply.send({ id: req.id })
|
|
497
|
-
})
|
|
498
|
-
|
|
499
|
-
const matches = [
|
|
500
|
-
{ reqId: 'foo', msg: /incoming request/ },
|
|
501
|
-
{ reqId: 'foo', msg: /some log message/ },
|
|
502
|
-
{ reqId: 'foo', msg: /request completed/ },
|
|
503
|
-
{ reqId: 'foo', msg: /incoming request/ },
|
|
504
|
-
{ reqId: 'foo', msg: /some log message 2/ },
|
|
505
|
-
{ reqId: 'foo', msg: /request completed/ }
|
|
506
|
-
]
|
|
507
|
-
|
|
508
|
-
let i = 0
|
|
509
|
-
stream.on('data', line => {
|
|
510
|
-
t.match(line, matches[i])
|
|
511
|
-
i += 1
|
|
512
|
-
})
|
|
513
|
-
|
|
514
|
-
fastify.inject({
|
|
515
|
-
method: 'GET',
|
|
516
|
-
url: '/one',
|
|
517
|
-
headers: {
|
|
518
|
-
'request-id': REQUEST_ID
|
|
519
|
-
}
|
|
520
|
-
}, (err, res) => {
|
|
521
|
-
t.error(err)
|
|
522
|
-
const payload = JSON.parse(res.payload)
|
|
523
|
-
t.equal(payload.id, 'foo')
|
|
524
|
-
})
|
|
525
|
-
|
|
526
|
-
fastify.inject({
|
|
527
|
-
method: 'GET',
|
|
528
|
-
url: '/two'
|
|
529
|
-
}, (err, res) => {
|
|
530
|
-
t.error(err)
|
|
531
|
-
const payload = JSON.parse(res.payload)
|
|
532
|
-
t.equal(payload.id, 'foo')
|
|
533
|
-
})
|
|
534
|
-
})
|
|
535
|
-
|
|
536
|
-
test('The request id log label can be changed', t => {
|
|
537
|
-
t.plan(6)
|
|
538
|
-
const REQUEST_ID = '42'
|
|
539
|
-
|
|
540
|
-
const stream = split(JSON.parse)
|
|
541
|
-
const fastify = Fastify({
|
|
542
|
-
logger: { stream, level: 'info' },
|
|
543
|
-
requestIdHeader: 'my-custom-request-id',
|
|
544
|
-
requestIdLogLabel: 'traceId'
|
|
545
|
-
})
|
|
546
|
-
t.teardown(() => fastify.close())
|
|
547
|
-
|
|
548
|
-
fastify.get('/one', (req, reply) => {
|
|
549
|
-
t.equal(req.id, REQUEST_ID)
|
|
550
|
-
req.log.info('some log message')
|
|
551
|
-
reply.send({ id: req.id })
|
|
552
|
-
})
|
|
553
|
-
|
|
554
|
-
const matches = [
|
|
555
|
-
{ traceId: REQUEST_ID, msg: /incoming request/ },
|
|
556
|
-
{ traceId: REQUEST_ID, msg: /some log message/ },
|
|
557
|
-
{ traceId: REQUEST_ID, msg: /request completed/ }
|
|
558
|
-
]
|
|
559
|
-
|
|
560
|
-
let i = 0
|
|
561
|
-
stream.on('data', line => {
|
|
562
|
-
t.match(line, matches[i])
|
|
563
|
-
i += 1
|
|
564
|
-
})
|
|
565
|
-
|
|
566
|
-
fastify.inject({
|
|
567
|
-
method: 'GET',
|
|
568
|
-
url: '/one',
|
|
569
|
-
headers: {
|
|
570
|
-
'my-custom-request-id': REQUEST_ID
|
|
571
|
-
}
|
|
572
|
-
}, (err, res) => {
|
|
573
|
-
t.error(err)
|
|
574
|
-
const payload = JSON.parse(res.payload)
|
|
575
|
-
t.equal(payload.id, REQUEST_ID)
|
|
576
|
-
})
|
|
577
|
-
})
|
|
578
|
-
|
|
579
|
-
test('The logger should accept custom serializer', t => {
|
|
580
|
-
t.plan(9)
|
|
581
|
-
|
|
582
|
-
const stream = split(JSON.parse)
|
|
583
|
-
const fastify = Fastify({
|
|
584
|
-
logger: {
|
|
585
|
-
stream,
|
|
586
|
-
level: 'info',
|
|
587
|
-
serializers: {
|
|
588
|
-
req: function (req) {
|
|
589
|
-
return {
|
|
590
|
-
url: req.url
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
})
|
|
596
|
-
|
|
597
|
-
fastify.get('/custom', function (req, reply) {
|
|
598
|
-
t.ok(req.log)
|
|
599
|
-
reply.send(new Error('kaboom'))
|
|
600
|
-
})
|
|
601
|
-
|
|
602
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
603
|
-
t.error(err)
|
|
604
|
-
t.teardown(() => { fastify.close() })
|
|
605
|
-
|
|
606
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/custom')
|
|
607
|
-
stream.once('data', listenAtLogLine => {
|
|
608
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
609
|
-
|
|
610
|
-
stream.once('data', line => {
|
|
611
|
-
t.ok(line.req, 'req is defined')
|
|
612
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
613
|
-
t.same(line.req, { url: '/custom' }, 'custom req serializer is use')
|
|
614
|
-
|
|
615
|
-
stream.once('data', line => {
|
|
616
|
-
t.ok(line.res, 'res is defined')
|
|
617
|
-
t.equal(line.msg, 'kaboom', 'message is set')
|
|
618
|
-
t.same(line.res, { statusCode: 500 }, 'default res serializer is use')
|
|
619
|
-
})
|
|
620
|
-
})
|
|
621
|
-
})
|
|
622
|
-
})
|
|
623
|
-
})
|
|
624
|
-
|
|
625
|
-
test('reply.send logs an error if called twice in a row', t => {
|
|
626
|
-
const lines = ['incoming request', 'request completed', 'Reply already sent', 'Reply already sent']
|
|
627
|
-
t.plan(lines.length + 2)
|
|
628
|
-
|
|
629
|
-
const splitStream = split(JSON.parse)
|
|
630
|
-
splitStream.on('data', (line) => {
|
|
631
|
-
t.same(line.msg, lines.shift())
|
|
632
|
-
})
|
|
633
|
-
|
|
634
|
-
const logger = pino(splitStream)
|
|
635
|
-
|
|
636
|
-
const fastify = Fastify({
|
|
637
|
-
logger
|
|
638
|
-
})
|
|
639
|
-
|
|
640
|
-
fastify.get('/', (req, reply) => {
|
|
641
|
-
reply.send({ hello: 'world' })
|
|
642
|
-
reply.send({ hello: 'world2' })
|
|
643
|
-
reply.send({ hello: 'world3' })
|
|
644
|
-
})
|
|
645
|
-
|
|
646
|
-
fastify.inject({
|
|
647
|
-
method: 'GET',
|
|
648
|
-
url: '/'
|
|
649
|
-
}, (err, res) => {
|
|
650
|
-
t.error(err)
|
|
651
|
-
const payload = JSON.parse(res.payload)
|
|
652
|
-
t.same(payload, { hello: 'world' })
|
|
653
|
-
})
|
|
654
|
-
})
|
|
655
|
-
|
|
656
|
-
test('logger can be silented', t => {
|
|
657
|
-
t.plan(17)
|
|
658
|
-
const fastify = Fastify({
|
|
659
|
-
logger: false
|
|
660
|
-
})
|
|
661
|
-
t.ok(fastify.log)
|
|
662
|
-
t.same(typeof fastify.log, 'object')
|
|
663
|
-
t.same(typeof fastify.log.fatal, 'function')
|
|
664
|
-
t.same(typeof fastify.log.error, 'function')
|
|
665
|
-
t.same(typeof fastify.log.warn, 'function')
|
|
666
|
-
t.same(typeof fastify.log.info, 'function')
|
|
667
|
-
t.same(typeof fastify.log.debug, 'function')
|
|
668
|
-
t.same(typeof fastify.log.trace, 'function')
|
|
669
|
-
t.same(typeof fastify.log.child, 'function')
|
|
670
|
-
|
|
671
|
-
const childLog = fastify.log.child()
|
|
672
|
-
|
|
673
|
-
t.same(typeof childLog, 'object')
|
|
674
|
-
t.same(typeof childLog.fatal, 'function')
|
|
675
|
-
t.same(typeof childLog.error, 'function')
|
|
676
|
-
t.same(typeof childLog.warn, 'function')
|
|
677
|
-
t.same(typeof childLog.info, 'function')
|
|
678
|
-
t.same(typeof childLog.debug, 'function')
|
|
679
|
-
t.same(typeof childLog.trace, 'function')
|
|
680
|
-
t.same(typeof childLog.child, 'function')
|
|
681
|
-
})
|
|
682
|
-
|
|
683
|
-
test('Should set a custom logLevel for a plugin', t => {
|
|
684
|
-
const lines = ['incoming request', 'Hello', 'request completed']
|
|
685
|
-
t.plan(7)
|
|
686
|
-
|
|
687
|
-
const splitStream = split(JSON.parse)
|
|
688
|
-
splitStream.on('data', (line) => {
|
|
689
|
-
t.same(line.msg, lines.shift())
|
|
690
|
-
})
|
|
691
|
-
|
|
692
|
-
const logger = pino({ level: 'error' }, splitStream)
|
|
693
|
-
|
|
694
|
-
const fastify = Fastify({
|
|
695
|
-
logger
|
|
696
|
-
})
|
|
697
|
-
|
|
698
|
-
fastify.get('/', (req, reply) => {
|
|
699
|
-
req.log.info('Hello') // we should not see this log
|
|
700
|
-
reply.send({ hello: 'world' })
|
|
701
|
-
})
|
|
702
|
-
|
|
703
|
-
fastify.register(function (instance, opts, done) {
|
|
704
|
-
instance.get('/plugin', (req, reply) => {
|
|
705
|
-
req.log.info('Hello') // we should see this log
|
|
706
|
-
reply.send({ hello: 'world' })
|
|
707
|
-
})
|
|
708
|
-
done()
|
|
709
|
-
}, { logLevel: 'info' })
|
|
710
|
-
|
|
711
|
-
fastify.inject({
|
|
712
|
-
method: 'GET',
|
|
713
|
-
url: '/'
|
|
714
|
-
}, (err, res) => {
|
|
715
|
-
t.error(err)
|
|
716
|
-
const payload = JSON.parse(res.payload)
|
|
717
|
-
t.same(payload, { hello: 'world' })
|
|
718
|
-
})
|
|
719
|
-
|
|
720
|
-
fastify.inject({
|
|
721
|
-
method: 'GET',
|
|
722
|
-
url: '/plugin'
|
|
723
|
-
}, (err, res) => {
|
|
724
|
-
t.error(err)
|
|
725
|
-
const payload = JSON.parse(res.payload)
|
|
726
|
-
t.same(payload, { hello: 'world' })
|
|
727
|
-
})
|
|
728
|
-
})
|
|
729
|
-
|
|
730
|
-
test('Should set a custom logSerializers for a plugin', t => {
|
|
731
|
-
t.plan(3)
|
|
732
|
-
|
|
733
|
-
const splitStream = split(JSON.parse)
|
|
734
|
-
splitStream.on('data', (line) => {
|
|
735
|
-
if (line.test) {
|
|
736
|
-
t.same(line.test, 'XHello')
|
|
737
|
-
}
|
|
738
|
-
})
|
|
739
|
-
|
|
740
|
-
const logger = pino({ level: 'error' }, splitStream)
|
|
741
|
-
|
|
742
|
-
const fastify = Fastify({
|
|
743
|
-
logger
|
|
744
|
-
})
|
|
745
|
-
|
|
746
|
-
fastify.register(function (instance, opts, done) {
|
|
747
|
-
instance.get('/plugin', (req, reply) => {
|
|
748
|
-
req.log.info({ test: 'Hello' }) // we should see this log
|
|
749
|
-
reply.send({ hello: 'world' })
|
|
750
|
-
})
|
|
751
|
-
done()
|
|
752
|
-
}, { logLevel: 'info', logSerializers: { test: value => 'X' + value } })
|
|
753
|
-
|
|
754
|
-
fastify.inject({
|
|
755
|
-
method: 'GET',
|
|
756
|
-
url: '/plugin'
|
|
757
|
-
}, (err, res) => {
|
|
758
|
-
t.error(err)
|
|
759
|
-
const payload = JSON.parse(res.payload)
|
|
760
|
-
t.same(payload, { hello: 'world' })
|
|
761
|
-
})
|
|
762
|
-
})
|
|
763
|
-
|
|
764
|
-
test('Should set a custom logLevel for every plugin', t => {
|
|
765
|
-
const lines = ['incoming request', 'request completed', 'info', 'debug']
|
|
766
|
-
t.plan(18)
|
|
767
|
-
|
|
768
|
-
const splitStream = split(JSON.parse)
|
|
769
|
-
splitStream.on('data', (line) => {
|
|
770
|
-
t.ok(line.level === 30 || line.level === 20)
|
|
771
|
-
t.ok(lines.indexOf(line.msg) > -1)
|
|
772
|
-
})
|
|
773
|
-
|
|
774
|
-
const logger = pino({ level: 'error' }, splitStream)
|
|
775
|
-
|
|
776
|
-
const fastify = Fastify({
|
|
777
|
-
logger
|
|
778
|
-
})
|
|
779
|
-
|
|
780
|
-
fastify.get('/', (req, reply) => {
|
|
781
|
-
req.log.warn('Hello') // we should not see this log
|
|
782
|
-
reply.send({ hello: 'world' })
|
|
783
|
-
})
|
|
784
|
-
|
|
785
|
-
fastify.register(function (instance, opts, done) {
|
|
786
|
-
instance.get('/info', (req, reply) => {
|
|
787
|
-
req.log.info('info') // we should see this log
|
|
788
|
-
req.log.debug('hidden log')
|
|
789
|
-
reply.send({ hello: 'world' })
|
|
790
|
-
})
|
|
791
|
-
done()
|
|
792
|
-
}, { logLevel: 'info' })
|
|
793
|
-
|
|
794
|
-
fastify.register(function (instance, opts, done) {
|
|
795
|
-
instance.get('/debug', (req, reply) => {
|
|
796
|
-
req.log.debug('debug') // we should see this log
|
|
797
|
-
req.log.trace('hidden log')
|
|
798
|
-
reply.send({ hello: 'world' })
|
|
799
|
-
})
|
|
800
|
-
done()
|
|
801
|
-
}, { logLevel: 'debug' })
|
|
802
|
-
|
|
803
|
-
fastify.inject({
|
|
804
|
-
method: 'GET',
|
|
805
|
-
url: '/'
|
|
806
|
-
}, (err, res) => {
|
|
807
|
-
t.error(err)
|
|
808
|
-
const payload = JSON.parse(res.payload)
|
|
809
|
-
t.same(payload, { hello: 'world' })
|
|
810
|
-
})
|
|
811
|
-
|
|
812
|
-
fastify.inject({
|
|
813
|
-
method: 'GET',
|
|
814
|
-
url: '/info'
|
|
815
|
-
}, (err, res) => {
|
|
816
|
-
t.error(err)
|
|
817
|
-
const payload = JSON.parse(res.payload)
|
|
818
|
-
t.same(payload, { hello: 'world' })
|
|
819
|
-
})
|
|
820
|
-
|
|
821
|
-
fastify.inject({
|
|
822
|
-
method: 'GET',
|
|
823
|
-
url: '/debug'
|
|
824
|
-
}, (err, res) => {
|
|
825
|
-
t.error(err)
|
|
826
|
-
const payload = JSON.parse(res.payload)
|
|
827
|
-
t.same(payload, { hello: 'world' })
|
|
828
|
-
})
|
|
829
|
-
})
|
|
830
|
-
|
|
831
|
-
test('Should set a custom logSerializers for every plugin', async t => {
|
|
832
|
-
const lines = ['Hello', 'XHello', 'ZHello']
|
|
833
|
-
t.plan(6)
|
|
834
|
-
|
|
835
|
-
const splitStream = split(JSON.parse)
|
|
836
|
-
splitStream.on('data', (line) => {
|
|
837
|
-
if (line.test) {
|
|
838
|
-
t.same(line.test, lines.shift())
|
|
839
|
-
}
|
|
840
|
-
})
|
|
841
|
-
|
|
842
|
-
const logger = pino({ level: 'info' }, splitStream)
|
|
843
|
-
const fastify = Fastify({
|
|
844
|
-
logger
|
|
845
|
-
})
|
|
846
|
-
|
|
847
|
-
fastify.get('/', (req, reply) => {
|
|
848
|
-
req.log.warn({ test: 'Hello' })
|
|
849
|
-
reply.send({ hello: 'world' })
|
|
850
|
-
})
|
|
851
|
-
|
|
852
|
-
fastify.register(function (instance, opts, done) {
|
|
853
|
-
instance.get('/test1', (req, reply) => {
|
|
854
|
-
req.log.info({ test: 'Hello' })
|
|
855
|
-
reply.send({ hello: 'world' })
|
|
856
|
-
})
|
|
857
|
-
done()
|
|
858
|
-
}, { logSerializers: { test: value => 'X' + value } })
|
|
859
|
-
|
|
860
|
-
fastify.register(function (instance, opts, done) {
|
|
861
|
-
instance.get('/test2', (req, reply) => {
|
|
862
|
-
req.log.info({ test: 'Hello' })
|
|
863
|
-
reply.send({ hello: 'world' })
|
|
864
|
-
})
|
|
865
|
-
done()
|
|
866
|
-
}, { logSerializers: { test: value => 'Z' + value } })
|
|
867
|
-
|
|
868
|
-
let res = await fastify.inject({
|
|
869
|
-
method: 'GET',
|
|
870
|
-
url: '/'
|
|
871
|
-
})
|
|
872
|
-
t.same(res.json(), { hello: 'world' })
|
|
873
|
-
|
|
874
|
-
res = await fastify.inject({
|
|
875
|
-
method: 'GET',
|
|
876
|
-
url: '/test1'
|
|
877
|
-
})
|
|
878
|
-
t.same(res.json(), { hello: 'world' })
|
|
879
|
-
|
|
880
|
-
res = await fastify.inject({
|
|
881
|
-
method: 'GET',
|
|
882
|
-
url: '/test2'
|
|
883
|
-
})
|
|
884
|
-
t.same(res.json(), { hello: 'world' })
|
|
885
|
-
})
|
|
886
|
-
|
|
887
|
-
test('Should override serializers from route', t => {
|
|
888
|
-
t.plan(3)
|
|
889
|
-
|
|
890
|
-
const splitStream = split(JSON.parse)
|
|
891
|
-
splitStream.on('data', (line) => {
|
|
892
|
-
if (line.test) {
|
|
893
|
-
t.same(line.test, 'ZHello')
|
|
894
|
-
}
|
|
895
|
-
})
|
|
896
|
-
|
|
897
|
-
const logger = pino({ level: 'info' }, splitStream)
|
|
898
|
-
const fastify = Fastify({
|
|
899
|
-
logger
|
|
900
|
-
})
|
|
901
|
-
|
|
902
|
-
fastify.register(function (instance, opts, done) {
|
|
903
|
-
instance.get('/', {
|
|
904
|
-
logSerializers: {
|
|
905
|
-
test: value => 'Z' + value // should override
|
|
906
|
-
}
|
|
907
|
-
}, (req, reply) => {
|
|
908
|
-
req.log.info({ test: 'Hello' })
|
|
909
|
-
reply.send({ hello: 'world' })
|
|
910
|
-
})
|
|
911
|
-
done()
|
|
912
|
-
}, { logSerializers: { test: value => 'X' + value } })
|
|
913
|
-
|
|
914
|
-
fastify.inject({
|
|
915
|
-
method: 'GET',
|
|
916
|
-
url: '/'
|
|
917
|
-
}, (err, res) => {
|
|
918
|
-
t.error(err)
|
|
919
|
-
const payload = JSON.parse(res.payload)
|
|
920
|
-
t.same(payload, { hello: 'world' })
|
|
921
|
-
})
|
|
922
|
-
})
|
|
923
|
-
|
|
924
|
-
test('Should override serializers from plugin', t => {
|
|
925
|
-
t.plan(3)
|
|
926
|
-
|
|
927
|
-
const splitStream = split(JSON.parse)
|
|
928
|
-
splitStream.on('data', (line) => {
|
|
929
|
-
if (line.test) {
|
|
930
|
-
t.same(line.test, 'ZHello')
|
|
931
|
-
}
|
|
932
|
-
})
|
|
933
|
-
|
|
934
|
-
const logger = pino({ level: 'info' }, splitStream)
|
|
935
|
-
const fastify = Fastify({
|
|
936
|
-
logger
|
|
937
|
-
})
|
|
938
|
-
|
|
939
|
-
fastify.register(function (instance, opts, done) {
|
|
940
|
-
instance.register(context1, {
|
|
941
|
-
logSerializers: {
|
|
942
|
-
test: value => 'Z' + value // should override
|
|
943
|
-
}
|
|
944
|
-
})
|
|
945
|
-
done()
|
|
946
|
-
}, { logSerializers: { test: value => 'X' + value } })
|
|
947
|
-
|
|
948
|
-
function context1 (instance, opts, done) {
|
|
949
|
-
instance.get('/', (req, reply) => {
|
|
950
|
-
req.log.info({ test: 'Hello' })
|
|
951
|
-
reply.send({ hello: 'world' })
|
|
952
|
-
})
|
|
953
|
-
done()
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
fastify.inject({
|
|
957
|
-
method: 'GET',
|
|
958
|
-
url: '/'
|
|
959
|
-
}, (err, res) => {
|
|
960
|
-
t.error(err)
|
|
961
|
-
const payload = JSON.parse(res.payload)
|
|
962
|
-
t.same(payload, { hello: 'world' })
|
|
963
|
-
})
|
|
964
|
-
})
|
|
965
|
-
|
|
966
|
-
test('Should use serializers from plugin and route', t => {
|
|
967
|
-
t.plan(4)
|
|
968
|
-
|
|
969
|
-
const splitStream = split(JSON.parse)
|
|
970
|
-
splitStream.on('data', (line) => {
|
|
971
|
-
if (line.test) {
|
|
972
|
-
t.same(line.test, 'XHello')
|
|
973
|
-
}
|
|
974
|
-
if (line.test2) {
|
|
975
|
-
t.same(line.test2, 'ZHello')
|
|
976
|
-
}
|
|
977
|
-
})
|
|
978
|
-
|
|
979
|
-
const logger = pino({ level: 'info' }, splitStream)
|
|
980
|
-
const fastify = Fastify({
|
|
981
|
-
logger
|
|
982
|
-
})
|
|
983
|
-
|
|
984
|
-
fastify.register(context1, {
|
|
985
|
-
logSerializers: { test: value => 'X' + value }
|
|
986
|
-
})
|
|
987
|
-
|
|
988
|
-
function context1 (instance, opts, done) {
|
|
989
|
-
instance.get('/', {
|
|
990
|
-
logSerializers: {
|
|
991
|
-
test2: value => 'Z' + value
|
|
992
|
-
}
|
|
993
|
-
}, (req, reply) => {
|
|
994
|
-
req.log.info({ test: 'Hello', test2: 'Hello' }) // { test: 'XHello', test2: 'ZHello' }
|
|
995
|
-
reply.send({ hello: 'world' })
|
|
996
|
-
})
|
|
997
|
-
done()
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
fastify.inject({
|
|
1001
|
-
method: 'GET',
|
|
1002
|
-
url: '/'
|
|
1003
|
-
}, (err, res) => {
|
|
1004
|
-
t.error(err)
|
|
1005
|
-
const payload = JSON.parse(res.payload)
|
|
1006
|
-
t.same(payload, { hello: 'world' })
|
|
1007
|
-
})
|
|
1008
|
-
})
|
|
1009
|
-
|
|
1010
|
-
test('Should use serializers from instance fastify and route', t => {
|
|
1011
|
-
t.plan(4)
|
|
1012
|
-
|
|
1013
|
-
const splitStream = split(JSON.parse)
|
|
1014
|
-
splitStream.on('data', (line) => {
|
|
1015
|
-
if (line.test) {
|
|
1016
|
-
t.same(line.test, 'XHello')
|
|
1017
|
-
}
|
|
1018
|
-
if (line.test2) {
|
|
1019
|
-
t.same(line.test2, 'ZHello')
|
|
1020
|
-
}
|
|
1021
|
-
})
|
|
1022
|
-
|
|
1023
|
-
const logger = pino({
|
|
1024
|
-
level: 'info',
|
|
1025
|
-
serializers: {
|
|
1026
|
-
test: value => 'X' + value,
|
|
1027
|
-
test2: value => 'This should be override - ' + value
|
|
1028
|
-
}
|
|
1029
|
-
}, splitStream)
|
|
1030
|
-
const fastify = Fastify({
|
|
1031
|
-
logger
|
|
1032
|
-
})
|
|
1033
|
-
|
|
1034
|
-
fastify.get('/', {
|
|
1035
|
-
logSerializers: {
|
|
1036
|
-
test2: value => 'Z' + value
|
|
1037
|
-
}
|
|
1038
|
-
}, (req, reply) => {
|
|
1039
|
-
req.log.info({ test: 'Hello', test2: 'Hello' }) // { test: 'XHello', test2: 'ZHello' }
|
|
1040
|
-
reply.send({ hello: 'world' })
|
|
1041
|
-
})
|
|
1042
|
-
|
|
1043
|
-
fastify.inject({
|
|
1044
|
-
method: 'GET',
|
|
1045
|
-
url: '/'
|
|
1046
|
-
}, (err, res) => {
|
|
1047
|
-
t.error(err)
|
|
1048
|
-
const payload = JSON.parse(res.payload)
|
|
1049
|
-
t.same(payload, { hello: 'world' })
|
|
1050
|
-
})
|
|
1051
|
-
})
|
|
1052
|
-
|
|
1053
|
-
test('Should use serializers inherit from contexts', t => {
|
|
1054
|
-
t.plan(5)
|
|
1055
|
-
|
|
1056
|
-
const splitStream = split(JSON.parse)
|
|
1057
|
-
splitStream.on('data', (line) => {
|
|
1058
|
-
if (line.test && line.test2 && line.test3) {
|
|
1059
|
-
t.same(line.test, 'XHello')
|
|
1060
|
-
t.same(line.test2, 'YHello')
|
|
1061
|
-
t.same(line.test3, 'ZHello')
|
|
1062
|
-
}
|
|
1063
|
-
})
|
|
1064
|
-
|
|
1065
|
-
const logger = pino({
|
|
1066
|
-
level: 'info',
|
|
1067
|
-
serializers: {
|
|
1068
|
-
test: value => 'X' + value
|
|
1069
|
-
}
|
|
1070
|
-
}, splitStream)
|
|
1071
|
-
|
|
1072
|
-
const fastify = Fastify({ logger })
|
|
1073
|
-
fastify.register(context1, { logSerializers: { test2: value => 'Y' + value } })
|
|
1074
|
-
|
|
1075
|
-
function context1 (instance, opts, done) {
|
|
1076
|
-
instance.get('/', {
|
|
1077
|
-
logSerializers: {
|
|
1078
|
-
test3: value => 'Z' + value
|
|
1079
|
-
}
|
|
1080
|
-
}, (req, reply) => {
|
|
1081
|
-
req.log.info({ test: 'Hello', test2: 'Hello', test3: 'Hello' }) // { test: 'XHello', test2: 'YHello', test3: 'ZHello' }
|
|
1082
|
-
reply.send({ hello: 'world' })
|
|
1083
|
-
})
|
|
1084
|
-
done()
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
fastify.inject({
|
|
1088
|
-
method: 'GET',
|
|
1089
|
-
url: '/'
|
|
1090
|
-
}, (err, res) => {
|
|
1091
|
-
t.error(err)
|
|
1092
|
-
const payload = JSON.parse(res.payload)
|
|
1093
|
-
t.same(payload, { hello: 'world' })
|
|
1094
|
-
})
|
|
1095
|
-
})
|
|
1096
|
-
|
|
1097
|
-
test('Should increase the log level for a specific plugin', t => {
|
|
1098
|
-
t.plan(4)
|
|
1099
|
-
|
|
1100
|
-
const splitStream = split(JSON.parse)
|
|
1101
|
-
splitStream.on('data', (line) => {
|
|
1102
|
-
t.same(line.msg, 'Hello')
|
|
1103
|
-
t.ok(line.level === 50)
|
|
1104
|
-
})
|
|
1105
|
-
|
|
1106
|
-
const logger = pino({ level: 'info' }, splitStream)
|
|
1107
|
-
|
|
1108
|
-
const fastify = Fastify({
|
|
1109
|
-
logger
|
|
1110
|
-
})
|
|
1111
|
-
|
|
1112
|
-
fastify.register(function (instance, opts, done) {
|
|
1113
|
-
instance.get('/', (req, reply) => {
|
|
1114
|
-
req.log.error('Hello') // we should see this log
|
|
1115
|
-
reply.send({ hello: 'world' })
|
|
1116
|
-
})
|
|
1117
|
-
done()
|
|
1118
|
-
}, { logLevel: 'error' })
|
|
1119
|
-
|
|
1120
|
-
fastify.inject({
|
|
1121
|
-
method: 'GET',
|
|
1122
|
-
url: '/'
|
|
1123
|
-
}, (err, res) => {
|
|
1124
|
-
t.error(err)
|
|
1125
|
-
const payload = JSON.parse(res.payload)
|
|
1126
|
-
t.same(payload, { hello: 'world' })
|
|
1127
|
-
})
|
|
1128
|
-
})
|
|
1129
|
-
|
|
1130
|
-
test('Should set the log level for the customized 404 handler', t => {
|
|
1131
|
-
t.plan(4)
|
|
1132
|
-
|
|
1133
|
-
const splitStream = split(JSON.parse)
|
|
1134
|
-
splitStream.on('data', (line) => {
|
|
1135
|
-
t.same(line.msg, 'Hello')
|
|
1136
|
-
t.ok(line.level === 50)
|
|
1137
|
-
})
|
|
1138
|
-
|
|
1139
|
-
const logger = pino({ level: 'warn' }, splitStream)
|
|
1140
|
-
|
|
1141
|
-
const fastify = Fastify({
|
|
1142
|
-
logger
|
|
1143
|
-
})
|
|
1144
|
-
|
|
1145
|
-
fastify.register(function (instance, opts, done) {
|
|
1146
|
-
instance.setNotFoundHandler(function (req, reply) {
|
|
1147
|
-
req.log.error('Hello')
|
|
1148
|
-
reply.code(404).send()
|
|
1149
|
-
})
|
|
1150
|
-
done()
|
|
1151
|
-
}, { logLevel: 'error' })
|
|
1152
|
-
|
|
1153
|
-
fastify.inject({
|
|
1154
|
-
method: 'GET',
|
|
1155
|
-
url: '/'
|
|
1156
|
-
}, (err, res) => {
|
|
1157
|
-
t.error(err)
|
|
1158
|
-
t.equal(res.statusCode, 404)
|
|
1159
|
-
})
|
|
1160
|
-
})
|
|
1161
|
-
|
|
1162
|
-
test('Should set the log level for the customized 500 handler', t => {
|
|
1163
|
-
t.plan(4)
|
|
1164
|
-
|
|
1165
|
-
const splitStream = split(JSON.parse)
|
|
1166
|
-
splitStream.on('data', (line) => {
|
|
1167
|
-
t.same(line.msg, 'Hello')
|
|
1168
|
-
t.ok(line.level === 60)
|
|
1169
|
-
})
|
|
1170
|
-
|
|
1171
|
-
const logger = pino({ level: 'warn' }, splitStream)
|
|
1172
|
-
|
|
1173
|
-
const fastify = Fastify({
|
|
1174
|
-
logger
|
|
1175
|
-
})
|
|
1176
|
-
|
|
1177
|
-
fastify.register(function (instance, opts, done) {
|
|
1178
|
-
instance.get('/', (req, reply) => {
|
|
1179
|
-
req.log.error('kaboom')
|
|
1180
|
-
reply.send(new Error('kaboom'))
|
|
1181
|
-
})
|
|
1182
|
-
|
|
1183
|
-
instance.setErrorHandler(function (e, request, reply) {
|
|
1184
|
-
reply.log.fatal('Hello')
|
|
1185
|
-
reply.code(500).send()
|
|
1186
|
-
})
|
|
1187
|
-
done()
|
|
1188
|
-
}, { logLevel: 'fatal' })
|
|
1189
|
-
|
|
1190
|
-
fastify.inject({
|
|
1191
|
-
method: 'GET',
|
|
1192
|
-
url: '/'
|
|
1193
|
-
}, (err, res) => {
|
|
1194
|
-
t.error(err)
|
|
1195
|
-
t.equal(res.statusCode, 500)
|
|
1196
|
-
})
|
|
1197
|
-
})
|
|
1198
|
-
|
|
1199
|
-
test('Should set a custom log level for a specific route', t => {
|
|
1200
|
-
const lines = ['incoming request', 'Hello', 'request completed']
|
|
1201
|
-
t.plan(7)
|
|
1202
|
-
|
|
1203
|
-
const splitStream = split(JSON.parse)
|
|
1204
|
-
splitStream.on('data', (line) => {
|
|
1205
|
-
t.same(line.msg, lines.shift())
|
|
1206
|
-
})
|
|
1207
|
-
|
|
1208
|
-
const logger = pino({ level: 'error' }, splitStream)
|
|
1209
|
-
|
|
1210
|
-
const fastify = Fastify({
|
|
1211
|
-
logger
|
|
1212
|
-
})
|
|
1213
|
-
|
|
1214
|
-
fastify.get('/log', { logLevel: 'info' }, (req, reply) => {
|
|
1215
|
-
req.log.info('Hello')
|
|
1216
|
-
reply.send({ hello: 'world' })
|
|
1217
|
-
})
|
|
1218
|
-
|
|
1219
|
-
fastify.get('/no-log', (req, reply) => {
|
|
1220
|
-
req.log.info('Hello')
|
|
1221
|
-
reply.send({ hello: 'world' })
|
|
1222
|
-
})
|
|
1223
|
-
|
|
1224
|
-
fastify.inject({
|
|
1225
|
-
method: 'GET',
|
|
1226
|
-
url: '/log'
|
|
1227
|
-
}, (err, res) => {
|
|
1228
|
-
t.error(err)
|
|
1229
|
-
const payload = JSON.parse(res.payload)
|
|
1230
|
-
t.same(payload, { hello: 'world' })
|
|
1231
|
-
})
|
|
1232
|
-
|
|
1233
|
-
fastify.inject({
|
|
1234
|
-
method: 'GET',
|
|
1235
|
-
url: '/no-log'
|
|
1236
|
-
}, (err, res) => {
|
|
1237
|
-
t.error(err)
|
|
1238
|
-
const payload = JSON.parse(res.payload)
|
|
1239
|
-
t.same(payload, { hello: 'world' })
|
|
1240
|
-
})
|
|
1241
|
-
})
|
|
1242
|
-
|
|
1243
|
-
test('The default 404 handler logs the incoming request', t => {
|
|
1244
|
-
t.plan(5)
|
|
1245
|
-
|
|
1246
|
-
const expectedMessages = [
|
|
1247
|
-
'incoming request',
|
|
1248
|
-
'Route GET:/not-found not found',
|
|
1249
|
-
'request completed'
|
|
1250
|
-
]
|
|
1251
|
-
|
|
1252
|
-
const splitStream = split(JSON.parse)
|
|
1253
|
-
splitStream.on('data', (line) => {
|
|
1254
|
-
t.same(line.msg, expectedMessages.shift())
|
|
1255
|
-
})
|
|
1256
|
-
|
|
1257
|
-
const logger = pino({ level: 'trace' }, splitStream)
|
|
1258
|
-
|
|
1259
|
-
const fastify = Fastify({
|
|
1260
|
-
logger
|
|
1261
|
-
})
|
|
1262
|
-
|
|
1263
|
-
fastify.inject({
|
|
1264
|
-
method: 'GET',
|
|
1265
|
-
url: '/not-found'
|
|
1266
|
-
}, (err, res) => {
|
|
1267
|
-
t.error(err)
|
|
1268
|
-
t.equal(res.statusCode, 404)
|
|
1269
|
-
})
|
|
1270
|
-
})
|
|
1271
|
-
|
|
1272
|
-
test('should serialize request and response', t => {
|
|
1273
|
-
t.plan(3)
|
|
1274
|
-
const lines = []
|
|
1275
|
-
const dest = new stream.Writable({
|
|
1276
|
-
write: function (chunk, enc, cb) {
|
|
1277
|
-
lines.push(JSON.parse(chunk))
|
|
1278
|
-
cb()
|
|
1279
|
-
}
|
|
1280
|
-
})
|
|
1281
|
-
const fastify = Fastify({ logger: { level: 'info', stream: dest } })
|
|
1282
|
-
|
|
1283
|
-
fastify.get('/500', (req, reply) => {
|
|
1284
|
-
reply.code(500).send(Error('500 error'))
|
|
1285
|
-
})
|
|
1286
|
-
|
|
1287
|
-
fastify.inject({
|
|
1288
|
-
url: '/500',
|
|
1289
|
-
method: 'GET'
|
|
1290
|
-
}, (e, res) => {
|
|
1291
|
-
const l = lines.find((line) => line.res && line.res.statusCode === 500)
|
|
1292
|
-
t.ok(l.req)
|
|
1293
|
-
t.same(l.req.method, 'GET')
|
|
1294
|
-
t.same(l.req.url, '/500')
|
|
1295
|
-
})
|
|
1296
|
-
})
|
|
1297
|
-
|
|
1298
|
-
{
|
|
1299
|
-
const interfaces = os.networkInterfaces()
|
|
1300
|
-
const ipv6 = Object.keys(interfaces)
|
|
1301
|
-
.filter(name => name.substr(0, 2) === 'lo')
|
|
1302
|
-
.map(name => interfaces[name])
|
|
1303
|
-
.reduce((list, set) => list.concat(set), [])
|
|
1304
|
-
.filter(info => info.family === 'IPv6')
|
|
1305
|
-
.map(info => info.address)
|
|
1306
|
-
.shift()
|
|
1307
|
-
|
|
1308
|
-
if (ipv6 !== undefined) {
|
|
1309
|
-
test('Wrap IPv6 address in listening log message', t => {
|
|
1310
|
-
t.plan(2)
|
|
1311
|
-
const stream = split(JSON.parse)
|
|
1312
|
-
const fastify = Fastify({
|
|
1313
|
-
logger: {
|
|
1314
|
-
stream,
|
|
1315
|
-
level: 'info'
|
|
1316
|
-
}
|
|
1317
|
-
})
|
|
1318
|
-
fastify.listen({ port: 0, host: ipv6 }, err => {
|
|
1319
|
-
t.error(err)
|
|
1320
|
-
stream.once('data', line => {
|
|
1321
|
-
const expected = 'Server listening at http://[' + ipv6 + ']:' +
|
|
1322
|
-
fastify.server.address().port
|
|
1323
|
-
t.same(line.msg, expected)
|
|
1324
|
-
fastify.close()
|
|
1325
|
-
})
|
|
1326
|
-
})
|
|
1327
|
-
})
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
test('Do not wrap IPv4 address', t => {
|
|
1332
|
-
t.plan(2)
|
|
1333
|
-
const stream = split(JSON.parse)
|
|
1334
|
-
const fastify = Fastify({
|
|
1335
|
-
logger: {
|
|
1336
|
-
stream,
|
|
1337
|
-
level: 'info'
|
|
1338
|
-
}
|
|
1339
|
-
})
|
|
1340
|
-
fastify.listen({ port: 0, host: '127.0.0.1' }, err => {
|
|
1341
|
-
t.error(err)
|
|
1342
|
-
stream.once('data', line => {
|
|
1343
|
-
const expected = 'Server listening at http://127.0.0.1:' +
|
|
1344
|
-
fastify.server.address().port
|
|
1345
|
-
t.same(line.msg, expected)
|
|
1346
|
-
fastify.close()
|
|
1347
|
-
})
|
|
1348
|
-
})
|
|
1349
|
-
})
|
|
1350
|
-
|
|
1351
|
-
test('file option', t => {
|
|
1352
|
-
t.plan(13)
|
|
1353
|
-
let fastify = null
|
|
1354
|
-
const dest = file()
|
|
1355
|
-
|
|
1356
|
-
fastify = Fastify({
|
|
1357
|
-
logger: {
|
|
1358
|
-
file: dest
|
|
1359
|
-
}
|
|
1360
|
-
})
|
|
1361
|
-
|
|
1362
|
-
fastify.get('/', function (req, reply) {
|
|
1363
|
-
t.ok(req.log)
|
|
1364
|
-
reply.send({ hello: 'world' })
|
|
1365
|
-
})
|
|
1366
|
-
|
|
1367
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1368
|
-
t.error(err)
|
|
1369
|
-
t.teardown(() => { fastify.close() })
|
|
1370
|
-
|
|
1371
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port, () => {
|
|
1372
|
-
const stream = fs.createReadStream(dest).pipe(split(JSON.parse))
|
|
1373
|
-
|
|
1374
|
-
stream.once('data', listenAtLogLine => {
|
|
1375
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1376
|
-
|
|
1377
|
-
stream.once('data', line => {
|
|
1378
|
-
const id = line.reqId
|
|
1379
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
1380
|
-
t.ok(line.req, 'req is defined')
|
|
1381
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
1382
|
-
t.equal(line.req.method, 'GET', 'method is get')
|
|
1383
|
-
|
|
1384
|
-
stream.once('data', line => {
|
|
1385
|
-
t.equal(line.reqId, id)
|
|
1386
|
-
t.ok(line.reqId, 'reqId is defined')
|
|
1387
|
-
t.ok(line.res, 'res is defined')
|
|
1388
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
1389
|
-
t.equal(line.res.statusCode, 200, 'statusCode is 200')
|
|
1390
|
-
t.ok(line.responseTime, 'responseTime is defined')
|
|
1391
|
-
stream.resume()
|
|
1392
|
-
})
|
|
1393
|
-
})
|
|
1394
|
-
})
|
|
1395
|
-
})
|
|
1396
|
-
})
|
|
1397
|
-
})
|
|
1398
|
-
|
|
1399
|
-
test('should log the error if no error handler is defined', t => {
|
|
1400
|
-
t.plan(8)
|
|
1401
|
-
const stream = split(JSON.parse)
|
|
1402
|
-
const fastify = Fastify({
|
|
1403
|
-
logger: {
|
|
1404
|
-
stream,
|
|
1405
|
-
level: 'info'
|
|
1406
|
-
}
|
|
1407
|
-
})
|
|
1408
|
-
fastify.get('/error', function (req, reply) {
|
|
1409
|
-
t.ok(req.log)
|
|
1410
|
-
reply.send(new Error('a generic error'))
|
|
1411
|
-
})
|
|
1412
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1413
|
-
t.error(err)
|
|
1414
|
-
t.teardown(() => { fastify.close() })
|
|
1415
|
-
|
|
1416
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
1417
|
-
stream.once('data', listenAtLogLine => {
|
|
1418
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1419
|
-
stream.once('data', line => {
|
|
1420
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
1421
|
-
stream.once('data', line => {
|
|
1422
|
-
t.equal(line.level, 50, 'level is correct')
|
|
1423
|
-
t.equal(line.msg, 'a generic error', 'message is set')
|
|
1424
|
-
stream.once('data', line => {
|
|
1425
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
1426
|
-
t.same(line.res, { statusCode: 500 }, 'status code is set')
|
|
1427
|
-
})
|
|
1428
|
-
})
|
|
1429
|
-
})
|
|
1430
|
-
})
|
|
1431
|
-
})
|
|
1432
|
-
})
|
|
1433
|
-
|
|
1434
|
-
test('should log as info if error status code >= 400 and < 500 if no error handler is defined', t => {
|
|
1435
|
-
t.plan(8)
|
|
1436
|
-
const stream = split(JSON.parse)
|
|
1437
|
-
const fastify = Fastify({
|
|
1438
|
-
logger: {
|
|
1439
|
-
stream,
|
|
1440
|
-
level: 'info'
|
|
1441
|
-
}
|
|
1442
|
-
})
|
|
1443
|
-
fastify.get('/400', function (req, reply) {
|
|
1444
|
-
t.ok(req.log)
|
|
1445
|
-
reply.send(Object.assign(new Error('a 400 error'), { statusCode: 400 }))
|
|
1446
|
-
})
|
|
1447
|
-
fastify.get('/503', function (req, reply) {
|
|
1448
|
-
t.ok(req.log)
|
|
1449
|
-
reply.send(Object.assign(new Error('a 503 error'), { statusCode: 503 }))
|
|
1450
|
-
})
|
|
1451
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1452
|
-
t.error(err)
|
|
1453
|
-
t.teardown(() => { fastify.close() })
|
|
1454
|
-
|
|
1455
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/400')
|
|
1456
|
-
stream.once('data', listenAtLogLine => {
|
|
1457
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1458
|
-
stream.once('data', line => {
|
|
1459
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
1460
|
-
stream.once('data', line => {
|
|
1461
|
-
t.equal(line.level, 30, 'level is correct')
|
|
1462
|
-
t.equal(line.msg, 'a 400 error', 'message is set')
|
|
1463
|
-
stream.once('data', line => {
|
|
1464
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
1465
|
-
t.same(line.res, { statusCode: 400 }, 'status code is set')
|
|
1466
|
-
})
|
|
1467
|
-
})
|
|
1468
|
-
})
|
|
1469
|
-
})
|
|
1470
|
-
})
|
|
1471
|
-
})
|
|
1472
|
-
|
|
1473
|
-
test('should log as error if error status code >= 500 if no error handler is defined', t => {
|
|
1474
|
-
t.plan(8)
|
|
1475
|
-
const stream = split(JSON.parse)
|
|
1476
|
-
const fastify = Fastify({
|
|
1477
|
-
logger: {
|
|
1478
|
-
stream,
|
|
1479
|
-
level: 'info'
|
|
1480
|
-
}
|
|
1481
|
-
})
|
|
1482
|
-
fastify.get('/503', function (req, reply) {
|
|
1483
|
-
t.ok(req.log)
|
|
1484
|
-
reply.send(Object.assign(new Error('a 503 error'), { statusCode: 503 }))
|
|
1485
|
-
})
|
|
1486
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1487
|
-
t.error(err)
|
|
1488
|
-
t.teardown(() => { fastify.close() })
|
|
1489
|
-
|
|
1490
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/503')
|
|
1491
|
-
stream.once('data', listenAtLogLine => {
|
|
1492
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1493
|
-
stream.once('data', line => {
|
|
1494
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
1495
|
-
stream.once('data', line => {
|
|
1496
|
-
t.equal(line.level, 50, 'level is correct')
|
|
1497
|
-
t.equal(line.msg, 'a 503 error', 'message is set')
|
|
1498
|
-
stream.once('data', line => {
|
|
1499
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
1500
|
-
t.same(line.res, { statusCode: 503 }, 'status code is set')
|
|
1501
|
-
})
|
|
1502
|
-
})
|
|
1503
|
-
})
|
|
1504
|
-
})
|
|
1505
|
-
})
|
|
1506
|
-
})
|
|
1507
|
-
|
|
1508
|
-
test('should not log the error if error handler is defined and it does not error', t => {
|
|
1509
|
-
t.plan(8)
|
|
1510
|
-
const stream = split(JSON.parse)
|
|
1511
|
-
const fastify = Fastify({
|
|
1512
|
-
logger: {
|
|
1513
|
-
stream,
|
|
1514
|
-
level: 'info'
|
|
1515
|
-
}
|
|
1516
|
-
})
|
|
1517
|
-
fastify.get('/error', function (req, reply) {
|
|
1518
|
-
t.ok(req.log)
|
|
1519
|
-
reply.send(new Error('something happened'))
|
|
1520
|
-
})
|
|
1521
|
-
fastify.setErrorHandler((err, req, reply) => {
|
|
1522
|
-
t.ok(err)
|
|
1523
|
-
reply.send('something bad happened')
|
|
1524
|
-
})
|
|
1525
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1526
|
-
t.error(err)
|
|
1527
|
-
t.teardown(() => { fastify.close() })
|
|
1528
|
-
|
|
1529
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
1530
|
-
stream.once('data', listenAtLogLine => {
|
|
1531
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1532
|
-
stream.once('data', line => {
|
|
1533
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
1534
|
-
stream.once('data', line => {
|
|
1535
|
-
t.equal(line.level, 30, 'level is correct')
|
|
1536
|
-
t.equal(line.msg, 'request completed', 'message is set')
|
|
1537
|
-
t.same(line.res, { statusCode: 200 }, 'status code is set')
|
|
1538
|
-
})
|
|
1539
|
-
})
|
|
1540
|
-
})
|
|
1541
|
-
})
|
|
1542
|
-
})
|
|
1543
|
-
|
|
1544
|
-
test('should not rely on raw request to log errors', t => {
|
|
1545
|
-
t.plan(7)
|
|
1546
|
-
const stream = split(JSON.parse)
|
|
1547
|
-
const fastify = Fastify({
|
|
1548
|
-
logger: {
|
|
1549
|
-
stream,
|
|
1550
|
-
level: 'info'
|
|
1551
|
-
}
|
|
1552
|
-
})
|
|
1553
|
-
fastify.get('/error', function (req, reply) {
|
|
1554
|
-
t.ok(req.log)
|
|
1555
|
-
reply.status(415).send(new Error('something happened'))
|
|
1556
|
-
})
|
|
1557
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1558
|
-
t.error(err)
|
|
1559
|
-
t.teardown(() => { fastify.close() })
|
|
1560
|
-
|
|
1561
|
-
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
1562
|
-
stream.once('data', listenAtLogLine => {
|
|
1563
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1564
|
-
stream.once('data', line => {
|
|
1565
|
-
t.equal(line.msg, 'incoming request', 'message is set')
|
|
1566
|
-
stream.once('data', line => {
|
|
1567
|
-
t.equal(line.level, 30, 'level is correct')
|
|
1568
|
-
t.equal(line.msg, 'something happened', 'message is set')
|
|
1569
|
-
t.same(line.res, { statusCode: 415 }, 'status code is set')
|
|
1570
|
-
})
|
|
1571
|
-
})
|
|
1572
|
-
})
|
|
1573
|
-
})
|
|
1574
|
-
})
|
|
1575
|
-
|
|
1576
|
-
test('should redact the authorization header if so specified', t => {
|
|
1577
|
-
t.plan(7)
|
|
1578
|
-
const stream = split(JSON.parse)
|
|
1579
|
-
const fastify = Fastify({
|
|
1580
|
-
logger: {
|
|
1581
|
-
stream,
|
|
1582
|
-
redact: ['req.headers.authorization'],
|
|
1583
|
-
level: 'info',
|
|
1584
|
-
serializers: {
|
|
1585
|
-
req (req) {
|
|
1586
|
-
return {
|
|
1587
|
-
method: req.method,
|
|
1588
|
-
url: req.url,
|
|
1589
|
-
headers: req.headers,
|
|
1590
|
-
hostname: req.hostname,
|
|
1591
|
-
remoteAddress: req.ip,
|
|
1592
|
-
remotePort: req.socket.remotePort
|
|
1593
|
-
}
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
})
|
|
1598
|
-
fastify.get('/', function (req, reply) {
|
|
1599
|
-
t.same(req.headers.authorization, 'Bearer abcde')
|
|
1600
|
-
reply.send({ hello: 'world' })
|
|
1601
|
-
})
|
|
1602
|
-
stream.once('data', listenAtLogLine => {
|
|
1603
|
-
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1604
|
-
stream.once('data', line => {
|
|
1605
|
-
t.equal(line.req.headers.authorization, '[Redacted]', 'authorization is redacted')
|
|
1606
|
-
})
|
|
1607
|
-
})
|
|
1608
|
-
fastify.listen({ port: 0, host: localhost }, err => {
|
|
1609
|
-
t.error(err)
|
|
1610
|
-
t.teardown(() => { fastify.close() })
|
|
1611
|
-
|
|
1612
|
-
sget({
|
|
1613
|
-
method: 'GET',
|
|
1614
|
-
url: `http://${localhostForURL}:` + fastify.server.address().port,
|
|
1615
|
-
headers: {
|
|
1616
|
-
authorization: 'Bearer abcde'
|
|
1617
|
-
}
|
|
1618
|
-
}, (err, response, body) => {
|
|
1619
|
-
t.error(err)
|
|
1620
|
-
t.equal(response.statusCode, 200)
|
|
1621
|
-
t.same(body.toString(), JSON.stringify({ hello: 'world' }))
|
|
1622
|
-
})
|
|
1623
|
-
})
|
|
1624
|
-
})
|
|
1625
|
-
|
|
1626
|
-
test('should not log incoming request and outgoing response when disabled', t => {
|
|
1627
|
-
t.plan(3)
|
|
1628
|
-
const lines = []
|
|
1629
|
-
const dest = new stream.Writable({
|
|
1630
|
-
write: function (chunk, enc, cb) {
|
|
1631
|
-
lines.push(JSON.parse(chunk))
|
|
1632
|
-
cb()
|
|
1633
|
-
}
|
|
1634
|
-
})
|
|
1635
|
-
const fastify = Fastify({ disableRequestLogging: true, logger: { level: 'info', stream: dest } })
|
|
1636
|
-
|
|
1637
|
-
fastify.get('/500', (req, reply) => {
|
|
1638
|
-
reply.code(500).send(Error('500 error'))
|
|
1639
|
-
})
|
|
1640
|
-
|
|
1641
|
-
fastify.inject({
|
|
1642
|
-
url: '/500',
|
|
1643
|
-
method: 'GET'
|
|
1644
|
-
}, (e, res) => {
|
|
1645
|
-
t.same(lines.length, 1)
|
|
1646
|
-
t.ok(lines[0].msg)
|
|
1647
|
-
t.same(lines[0].msg, '500 error')
|
|
1648
|
-
})
|
|
1649
|
-
})
|
|
1650
|
-
|
|
1651
|
-
test('should not log incoming request and outgoing response for 404 onBadUrl when disabled', t => {
|
|
1652
|
-
t.plan(1)
|
|
1653
|
-
const lines = []
|
|
1654
|
-
const dest = new stream.Writable({
|
|
1655
|
-
write: function (chunk, enc, cb) {
|
|
1656
|
-
lines.push(JSON.parse(chunk))
|
|
1657
|
-
cb()
|
|
1658
|
-
}
|
|
1659
|
-
})
|
|
1660
|
-
const fastify = Fastify({ disableRequestLogging: true, logger: { level: 'info', stream: dest } })
|
|
1661
|
-
|
|
1662
|
-
fastify.inject({
|
|
1663
|
-
url: '/%c0',
|
|
1664
|
-
method: 'GET'
|
|
1665
|
-
}, (e, res) => {
|
|
1666
|
-
// it will log 1 line only because of basic404
|
|
1667
|
-
t.same(lines.length, 1)
|
|
1668
|
-
})
|
|
1669
|
-
})
|
|
1670
|
-
|
|
1671
|
-
test('should pass when using unWritable props in the logger option', t => {
|
|
1672
|
-
t.plan(1)
|
|
1673
|
-
Fastify({
|
|
1674
|
-
logger: Object.defineProperty({}, 'level', { value: 'info' })
|
|
1675
|
-
})
|
|
1676
|
-
t.pass()
|
|
1677
|
-
})
|
|
1678
|
-
|
|
1679
|
-
test('should be able to use a custom logger', t => {
|
|
1680
|
-
t.plan(1)
|
|
1681
|
-
|
|
1682
|
-
const logger = {
|
|
1683
|
-
fatal: () => {},
|
|
1684
|
-
error: () => {},
|
|
1685
|
-
warn: () => {},
|
|
1686
|
-
info: () => {},
|
|
1687
|
-
debug: () => {},
|
|
1688
|
-
trace: () => {},
|
|
1689
|
-
child: () => {}
|
|
1690
|
-
}
|
|
1691
|
-
|
|
1692
|
-
Fastify({ logger })
|
|
1693
|
-
|
|
1694
|
-
t.pass()
|
|
1695
|
-
})
|
|
1696
|
-
|
|
1697
|
-
test('should create a default logger if provided one is invalid', t => {
|
|
1698
|
-
t.plan(1)
|
|
1699
|
-
|
|
1700
|
-
const logger = new Date()
|
|
1701
|
-
|
|
1702
|
-
Fastify({ logger })
|
|
1703
|
-
|
|
1704
|
-
t.pass()
|
|
1705
|
-
})
|
|
1706
|
-
|
|
1707
|
-
test('should not throw error when serializing custom req', t => {
|
|
1708
|
-
t.plan(1)
|
|
1709
|
-
|
|
1710
|
-
const lines = []
|
|
1711
|
-
const dest = new stream.Writable({
|
|
1712
|
-
write: function (chunk, enc, cb) {
|
|
1713
|
-
lines.push(JSON.parse(chunk))
|
|
1714
|
-
cb()
|
|
1715
|
-
}
|
|
1716
|
-
})
|
|
1717
|
-
const fastify = Fastify({ logger: { level: 'info', stream: dest } })
|
|
1718
|
-
fastify.log.info({ req: {} })
|
|
1719
|
-
|
|
1720
|
-
t.same(lines[0].req, {})
|
|
1721
|
-
})
|