node-fastify 5.8.3
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/.borp.yaml +3 -0
- package/.markdownlint-cli2.yaml +22 -0
- package/.prettierignore +1 -0
- package/GOVERNANCE.md +4 -0
- package/LICENSE +21 -0
- package/PROJECT_CHARTER.md +126 -0
- package/README.md +423 -0
- package/SECURITY.md +220 -0
- package/SPONSORS.md +24 -0
- package/build/build-error-serializer.js +35 -0
- package/build/build-validation.js +169 -0
- package/build/sync-version.js +11 -0
- package/docs/Guides/Benchmarking.md +60 -0
- package/docs/Guides/Database.md +321 -0
- package/docs/Guides/Delay-Accepting-Requests.md +608 -0
- package/docs/Guides/Detecting-When-Clients-Abort.md +172 -0
- package/docs/Guides/Ecosystem.md +726 -0
- package/docs/Guides/Fluent-Schema.md +127 -0
- package/docs/Guides/Getting-Started.md +620 -0
- package/docs/Guides/Index.md +43 -0
- package/docs/Guides/Migration-Guide-V3.md +287 -0
- package/docs/Guides/Migration-Guide-V4.md +267 -0
- package/docs/Guides/Migration-Guide-V5.md +727 -0
- package/docs/Guides/Plugins-Guide.md +520 -0
- package/docs/Guides/Prototype-Poisoning.md +383 -0
- package/docs/Guides/Recommendations.md +378 -0
- package/docs/Guides/Serverless.md +604 -0
- package/docs/Guides/Style-Guide.md +246 -0
- package/docs/Guides/Testing.md +481 -0
- package/docs/Guides/Write-Plugin.md +103 -0
- package/docs/Guides/Write-Type-Provider.md +34 -0
- package/docs/Reference/ContentTypeParser.md +271 -0
- package/docs/Reference/Decorators.md +436 -0
- package/docs/Reference/Encapsulation.md +194 -0
- package/docs/Reference/Errors.md +377 -0
- package/docs/Reference/HTTP2.md +94 -0
- package/docs/Reference/Hooks.md +958 -0
- package/docs/Reference/Index.md +73 -0
- package/docs/Reference/LTS.md +86 -0
- package/docs/Reference/Lifecycle.md +99 -0
- package/docs/Reference/Logging.md +268 -0
- package/docs/Reference/Middleware.md +79 -0
- package/docs/Reference/Plugins.md +245 -0
- package/docs/Reference/Principles.md +73 -0
- package/docs/Reference/Reply.md +1001 -0
- package/docs/Reference/Request.md +295 -0
- package/docs/Reference/Routes.md +802 -0
- package/docs/Reference/Server.md +2389 -0
- package/docs/Reference/Type-Providers.md +256 -0
- package/docs/Reference/TypeScript.md +1729 -0
- package/docs/Reference/Validation-and-Serialization.md +1130 -0
- package/docs/Reference/Warnings.md +58 -0
- package/docs/index.md +24 -0
- package/docs/resources/encapsulation_context.drawio +1 -0
- package/docs/resources/encapsulation_context.svg +3 -0
- package/eslint.config.js +35 -0
- package/examples/asyncawait.js +38 -0
- package/examples/benchmark/body.json +3 -0
- package/examples/benchmark/hooks-benchmark-async-await.js +44 -0
- package/examples/benchmark/hooks-benchmark.js +52 -0
- package/examples/benchmark/parser.js +47 -0
- package/examples/benchmark/simple.js +30 -0
- package/examples/benchmark/webstream.js +27 -0
- package/examples/hooks.js +91 -0
- package/examples/http2.js +39 -0
- package/examples/https.js +38 -0
- package/examples/parser.js +53 -0
- package/examples/plugin.js +12 -0
- package/examples/route-prefix.js +38 -0
- package/examples/shared-schema.js +38 -0
- package/examples/simple-stream.js +20 -0
- package/examples/simple.js +32 -0
- package/examples/simple.mjs +27 -0
- package/examples/typescript-server.ts +79 -0
- package/examples/use-plugin.js +29 -0
- package/fastify.d.ts +253 -0
- package/fastify.js +985 -0
- package/integration/server.js +29 -0
- package/integration/test.sh +23 -0
- package/lib/config-validator.js +1266 -0
- package/lib/content-type-parser.js +413 -0
- package/lib/content-type.js +160 -0
- package/lib/context.js +98 -0
- package/lib/decorate.js +152 -0
- package/lib/error-handler.js +173 -0
- package/lib/error-serializer.js +134 -0
- package/lib/error-status.js +14 -0
- package/lib/errors.js +516 -0
- package/lib/four-oh-four.js +190 -0
- package/lib/handle-request.js +195 -0
- package/lib/head-route.js +45 -0
- package/lib/hooks.js +429 -0
- package/lib/initial-config-validation.js +37 -0
- package/lib/logger-factory.js +136 -0
- package/lib/logger-pino.js +68 -0
- package/lib/noop-set.js +10 -0
- package/lib/plugin-override.js +90 -0
- package/lib/plugin-utils.js +169 -0
- package/lib/promise.js +23 -0
- package/lib/reply.js +1030 -0
- package/lib/req-id-gen-factory.js +52 -0
- package/lib/request.js +391 -0
- package/lib/route.js +686 -0
- package/lib/schema-controller.js +164 -0
- package/lib/schemas.js +207 -0
- package/lib/server.js +441 -0
- package/lib/symbols.js +71 -0
- package/lib/validation.js +280 -0
- package/lib/warnings.js +57 -0
- package/lib/wrap-thenable.js +84 -0
- package/package.json +225 -0
- package/scripts/validate-ecosystem-links.js +179 -0
- package/test/404s.test.js +2035 -0
- package/test/500s.test.js +422 -0
- package/test/allow-unsafe-regex.test.js +92 -0
- package/test/als.test.js +65 -0
- package/test/async-await.test.js +705 -0
- package/test/async-dispose.test.js +20 -0
- package/test/async_hooks.test.js +52 -0
- package/test/body-limit.test.js +224 -0
- package/test/buffer.test.js +74 -0
- package/test/build/error-serializer.test.js +36 -0
- package/test/build/version.test.js +14 -0
- package/test/build-certificate.js +109 -0
- package/test/bundler/README.md +29 -0
- package/test/bundler/esbuild/bundler-test.js +32 -0
- package/test/bundler/esbuild/package.json +10 -0
- package/test/bundler/esbuild/src/fail-plugin-version.js +14 -0
- package/test/bundler/esbuild/src/index.js +9 -0
- package/test/bundler/webpack/bundler-test.js +32 -0
- package/test/bundler/webpack/package.json +11 -0
- package/test/bundler/webpack/src/fail-plugin-version.js +14 -0
- package/test/bundler/webpack/src/index.js +9 -0
- package/test/bundler/webpack/webpack.config.js +15 -0
- package/test/case-insensitive.test.js +102 -0
- package/test/chainable.test.js +40 -0
- package/test/child-logger-factory.test.js +128 -0
- package/test/client-timeout.test.js +38 -0
- package/test/close-pipelining.test.js +78 -0
- package/test/close.test.js +706 -0
- package/test/conditional-pino.test.js +47 -0
- package/test/connection-timeout.test.js +42 -0
- package/test/constrained-routes.test.js +1138 -0
- package/test/content-length.test.js +174 -0
- package/test/content-parser.test.js +739 -0
- package/test/content-type.test.js +181 -0
- package/test/context-config.test.js +164 -0
- package/test/custom-http-server.test.js +118 -0
- package/test/custom-parser-async.test.js +59 -0
- package/test/custom-parser.0.test.js +701 -0
- package/test/custom-parser.1.test.js +266 -0
- package/test/custom-parser.2.test.js +91 -0
- package/test/custom-parser.3.test.js +208 -0
- package/test/custom-parser.4.test.js +218 -0
- package/test/custom-parser.5.test.js +130 -0
- package/test/custom-querystring-parser.test.js +129 -0
- package/test/decorator.test.js +1330 -0
- package/test/delete.test.js +344 -0
- package/test/diagnostics-channel/404.test.js +49 -0
- package/test/diagnostics-channel/async-delay-request.test.js +65 -0
- package/test/diagnostics-channel/async-request.test.js +64 -0
- package/test/diagnostics-channel/error-before-handler.test.js +35 -0
- package/test/diagnostics-channel/error-request.test.js +53 -0
- package/test/diagnostics-channel/error-status.test.js +123 -0
- package/test/diagnostics-channel/init.test.js +50 -0
- package/test/diagnostics-channel/sync-delay-request.test.js +49 -0
- package/test/diagnostics-channel/sync-request-reply.test.js +51 -0
- package/test/diagnostics-channel/sync-request.test.js +54 -0
- package/test/encapsulated-child-logger-factory.test.js +69 -0
- package/test/encapsulated-error-handler.test.js +237 -0
- package/test/esm/errorCodes.test.mjs +10 -0
- package/test/esm/esm.test.mjs +13 -0
- package/test/esm/index.test.js +8 -0
- package/test/esm/named-exports.mjs +14 -0
- package/test/esm/other.mjs +8 -0
- package/test/esm/plugin.mjs +8 -0
- package/test/fastify-instance.test.js +300 -0
- package/test/find-route.test.js +152 -0
- package/test/fluent-schema.test.js +209 -0
- package/test/genReqId.test.js +426 -0
- package/test/handler-context.test.js +45 -0
- package/test/handler-timeout.test.js +367 -0
- package/test/has-route.test.js +88 -0
- package/test/header-overflow.test.js +55 -0
- package/test/helper.js +496 -0
- package/test/hooks-async.test.js +1099 -0
- package/test/hooks.on-listen.test.js +1162 -0
- package/test/hooks.on-ready.test.js +421 -0
- package/test/hooks.test.js +3578 -0
- package/test/http-methods/copy.test.js +35 -0
- package/test/http-methods/custom-http-methods.test.js +114 -0
- package/test/http-methods/get.test.js +412 -0
- package/test/http-methods/head.test.js +263 -0
- package/test/http-methods/lock.test.js +108 -0
- package/test/http-methods/mkcalendar.test.js +143 -0
- package/test/http-methods/mkcol.test.js +35 -0
- package/test/http-methods/move.test.js +42 -0
- package/test/http-methods/propfind.test.js +136 -0
- package/test/http-methods/proppatch.test.js +105 -0
- package/test/http-methods/report.test.js +142 -0
- package/test/http-methods/search.test.js +233 -0
- package/test/http-methods/trace.test.js +21 -0
- package/test/http-methods/unlock.test.js +38 -0
- package/test/http2/closing.test.js +270 -0
- package/test/http2/constraint.test.js +109 -0
- package/test/http2/head.test.js +34 -0
- package/test/http2/plain.test.js +68 -0
- package/test/http2/secure-with-fallback.test.js +113 -0
- package/test/http2/secure.test.js +67 -0
- package/test/http2/unknown-http-method.test.js +34 -0
- package/test/https/custom-https-server.test.js +58 -0
- package/test/https/https.test.js +136 -0
- package/test/imports.test.js +17 -0
- package/test/inject.test.js +502 -0
- package/test/input-validation.js +335 -0
- package/test/internals/all.test.js +38 -0
- package/test/internals/content-type-parser.test.js +111 -0
- package/test/internals/context.test.js +31 -0
- package/test/internals/decorator.test.js +156 -0
- package/test/internals/errors.test.js +982 -0
- package/test/internals/handle-request.test.js +270 -0
- package/test/internals/hook-runner.test.js +449 -0
- package/test/internals/hooks.test.js +96 -0
- package/test/internals/initial-config.test.js +383 -0
- package/test/internals/logger.test.js +163 -0
- package/test/internals/plugin.test.js +170 -0
- package/test/internals/promise.test.js +63 -0
- package/test/internals/reply-serialize.test.js +714 -0
- package/test/internals/reply.test.js +1920 -0
- package/test/internals/req-id-gen-factory.test.js +133 -0
- package/test/internals/request-validate.test.js +1402 -0
- package/test/internals/request.test.js +506 -0
- package/test/internals/schema-controller-perf.test.js +40 -0
- package/test/internals/server.test.js +91 -0
- package/test/internals/validation.test.js +352 -0
- package/test/issue-4959.test.js +118 -0
- package/test/keep-alive-timeout.test.js +42 -0
- package/test/listen.1.test.js +154 -0
- package/test/listen.2.test.js +113 -0
- package/test/listen.3.test.js +83 -0
- package/test/listen.4.test.js +168 -0
- package/test/listen.5.test.js +122 -0
- package/test/logger/instantiation.test.js +341 -0
- package/test/logger/logger-test-utils.js +47 -0
- package/test/logger/logging.test.js +460 -0
- package/test/logger/options.test.js +579 -0
- package/test/logger/request.test.js +292 -0
- package/test/logger/response.test.js +183 -0
- package/test/logger/tap-parallel-not-ok +0 -0
- package/test/max-requests-per-socket.test.js +113 -0
- package/test/middleware.test.js +37 -0
- package/test/noop-set.test.js +19 -0
- package/test/nullable-validation.test.js +187 -0
- package/test/options.error-handler.test.js +5 -0
- package/test/options.test.js +5 -0
- package/test/output-validation.test.js +140 -0
- package/test/patch.error-handler.test.js +5 -0
- package/test/patch.test.js +5 -0
- package/test/plugin.1.test.js +230 -0
- package/test/plugin.2.test.js +314 -0
- package/test/plugin.3.test.js +287 -0
- package/test/plugin.4.test.js +504 -0
- package/test/plugin.helper.js +8 -0
- package/test/plugin.name.display.js +10 -0
- package/test/post-empty-body.test.js +38 -0
- package/test/pretty-print.test.js +366 -0
- package/test/promises.test.js +125 -0
- package/test/proto-poisoning.test.js +145 -0
- package/test/put.error-handler.test.js +5 -0
- package/test/put.test.js +5 -0
- package/test/register.test.js +184 -0
- package/test/reply-code.test.js +148 -0
- package/test/reply-early-hints.test.js +100 -0
- package/test/reply-error.test.js +815 -0
- package/test/reply-trailers.test.js +445 -0
- package/test/reply-web-stream-locked.test.js +37 -0
- package/test/request-error.test.js +624 -0
- package/test/request-header-host.test.js +339 -0
- package/test/request-id.test.js +118 -0
- package/test/request-timeout.test.js +53 -0
- package/test/route-hooks.test.js +635 -0
- package/test/route-prefix.test.js +904 -0
- package/test/route-shorthand.test.js +48 -0
- package/test/route.1.test.js +259 -0
- package/test/route.2.test.js +100 -0
- package/test/route.3.test.js +213 -0
- package/test/route.4.test.js +127 -0
- package/test/route.5.test.js +211 -0
- package/test/route.6.test.js +306 -0
- package/test/route.7.test.js +406 -0
- package/test/route.8.test.js +225 -0
- package/test/router-options.test.js +1108 -0
- package/test/same-shape.test.js +124 -0
- package/test/schema-examples.test.js +661 -0
- package/test/schema-feature.test.js +2198 -0
- package/test/schema-serialization.test.js +1171 -0
- package/test/schema-special-usage.test.js +1348 -0
- package/test/schema-validation.test.js +1572 -0
- package/test/scripts/validate-ecosystem-links.test.js +339 -0
- package/test/serialize-response.test.js +186 -0
- package/test/server.test.js +347 -0
- package/test/set-error-handler.test.js +69 -0
- package/test/skip-reply-send.test.js +317 -0
- package/test/stream-serializers.test.js +40 -0
- package/test/stream.1.test.js +94 -0
- package/test/stream.2.test.js +129 -0
- package/test/stream.3.test.js +198 -0
- package/test/stream.4.test.js +176 -0
- package/test/stream.5.test.js +188 -0
- package/test/sync-routes.test.js +32 -0
- package/test/throw.test.js +359 -0
- package/test/toolkit.js +63 -0
- package/test/trust-proxy.test.js +162 -0
- package/test/type-provider.test.js +22 -0
- package/test/types/content-type-parser.test-d.ts +72 -0
- package/test/types/decorate-request-reply.test-d.ts +18 -0
- package/test/types/dummy-plugin.ts +9 -0
- package/test/types/errors.test-d.ts +90 -0
- package/test/types/fastify.test-d.ts +352 -0
- package/test/types/hooks.test-d.ts +550 -0
- package/test/types/import.ts +2 -0
- package/test/types/instance.test-d.ts +588 -0
- package/test/types/logger.test-d.ts +277 -0
- package/test/types/plugin.test-d.ts +97 -0
- package/test/types/register.test-d.ts +237 -0
- package/test/types/reply.test-d.ts +254 -0
- package/test/types/request.test-d.ts +188 -0
- package/test/types/route.test-d.ts +553 -0
- package/test/types/schema.test-d.ts +135 -0
- package/test/types/serverFactory.test-d.ts +37 -0
- package/test/types/type-provider.test-d.ts +1213 -0
- package/test/types/using.test-d.ts +17 -0
- package/test/upgrade.test.js +52 -0
- package/test/url-rewriting.test.js +122 -0
- package/test/use-semicolon-delimiter.test.js +168 -0
- package/test/validation-error-handling.test.js +900 -0
- package/test/versioned-routes.test.js +603 -0
- package/test/web-api.test.js +616 -0
- package/test/wrap-thenable.test.js +30 -0
- package/types/content-type-parser.d.ts +75 -0
- package/types/context.d.ts +22 -0
- package/types/errors.d.ts +92 -0
- package/types/hooks.d.ts +875 -0
- package/types/instance.d.ts +609 -0
- package/types/logger.d.ts +107 -0
- package/types/plugin.d.ts +44 -0
- package/types/register.d.ts +42 -0
- package/types/reply.d.ts +81 -0
- package/types/request.d.ts +95 -0
- package/types/route.d.ts +199 -0
- package/types/schema.d.ts +61 -0
- package/types/server-factory.d.ts +19 -0
- package/types/type-provider.d.ts +130 -0
- package/types/utils.d.ts +98 -0
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const stream = require('node:stream')
|
|
4
|
+
|
|
5
|
+
const t = require('node:test')
|
|
6
|
+
const split = require('split2')
|
|
7
|
+
const pino = require('pino')
|
|
8
|
+
|
|
9
|
+
const Fastify = require('../../fastify')
|
|
10
|
+
const { on } = stream
|
|
11
|
+
|
|
12
|
+
t.test('logger options', { timeout: 60000 }, async (t) => {
|
|
13
|
+
t.plan(16)
|
|
14
|
+
|
|
15
|
+
await t.test('logger can be silenced', (t) => {
|
|
16
|
+
t.plan(17)
|
|
17
|
+
const fastify = Fastify({
|
|
18
|
+
logger: false
|
|
19
|
+
})
|
|
20
|
+
t.after(() => fastify.close())
|
|
21
|
+
t.assert.ok(fastify.log)
|
|
22
|
+
t.assert.deepEqual(typeof fastify.log, 'object')
|
|
23
|
+
t.assert.deepEqual(typeof fastify.log.fatal, 'function')
|
|
24
|
+
t.assert.deepEqual(typeof fastify.log.error, 'function')
|
|
25
|
+
t.assert.deepEqual(typeof fastify.log.warn, 'function')
|
|
26
|
+
t.assert.deepEqual(typeof fastify.log.info, 'function')
|
|
27
|
+
t.assert.deepEqual(typeof fastify.log.debug, 'function')
|
|
28
|
+
t.assert.deepEqual(typeof fastify.log.trace, 'function')
|
|
29
|
+
t.assert.deepEqual(typeof fastify.log.child, 'function')
|
|
30
|
+
|
|
31
|
+
const childLog = fastify.log.child()
|
|
32
|
+
|
|
33
|
+
t.assert.deepEqual(typeof childLog, 'object')
|
|
34
|
+
t.assert.deepEqual(typeof childLog.fatal, 'function')
|
|
35
|
+
t.assert.deepEqual(typeof childLog.error, 'function')
|
|
36
|
+
t.assert.deepEqual(typeof childLog.warn, 'function')
|
|
37
|
+
t.assert.deepEqual(typeof childLog.info, 'function')
|
|
38
|
+
t.assert.deepEqual(typeof childLog.debug, 'function')
|
|
39
|
+
t.assert.deepEqual(typeof childLog.trace, 'function')
|
|
40
|
+
t.assert.deepEqual(typeof childLog.child, 'function')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
await t.test('Should set a custom logLevel for a plugin', async (t) => {
|
|
44
|
+
const lines = ['incoming request', 'Hello', 'request completed']
|
|
45
|
+
t.plan(lines.length + 2)
|
|
46
|
+
|
|
47
|
+
const stream = split(JSON.parse)
|
|
48
|
+
|
|
49
|
+
const loggerInstance = pino({ level: 'error' }, stream)
|
|
50
|
+
|
|
51
|
+
const fastify = Fastify({
|
|
52
|
+
loggerInstance
|
|
53
|
+
})
|
|
54
|
+
t.after(() => fastify.close())
|
|
55
|
+
|
|
56
|
+
fastify.get('/', (req, reply) => {
|
|
57
|
+
req.log.info('Not Exist') // we should not see this log
|
|
58
|
+
reply.send({ hello: 'world' })
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
fastify.register(function (instance, opts, done) {
|
|
62
|
+
instance.get('/plugin', (req, reply) => {
|
|
63
|
+
req.log.info('Hello') // we should see this log
|
|
64
|
+
reply.send({ hello: 'world' })
|
|
65
|
+
})
|
|
66
|
+
done()
|
|
67
|
+
}, { logLevel: 'info' })
|
|
68
|
+
|
|
69
|
+
await fastify.ready()
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
73
|
+
const body = await response.json()
|
|
74
|
+
t.assert.deepEqual(body.hello, 'world')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
const response = await fastify.inject({ method: 'GET', url: '/plugin' })
|
|
79
|
+
const body = await response.json()
|
|
80
|
+
t.assert.deepEqual(body.hello, 'world')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for await (const [line] of on(stream, 'data')) {
|
|
84
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
85
|
+
if (lines.length === 0) break
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
await t.test('Should set a custom logSerializers for a plugin', async (t) => {
|
|
90
|
+
const lines = ['incoming request', 'XHello', 'request completed']
|
|
91
|
+
t.plan(lines.length + 1)
|
|
92
|
+
|
|
93
|
+
const stream = split(JSON.parse)
|
|
94
|
+
|
|
95
|
+
const loggerInstance = pino({ level: 'error' }, stream)
|
|
96
|
+
|
|
97
|
+
const fastify = Fastify({
|
|
98
|
+
loggerInstance
|
|
99
|
+
})
|
|
100
|
+
t.after(() => fastify.close())
|
|
101
|
+
|
|
102
|
+
fastify.register(function (instance, opts, done) {
|
|
103
|
+
instance.get('/plugin', (req, reply) => {
|
|
104
|
+
req.log.info({ test: 'Hello' }) // we should see this log
|
|
105
|
+
reply.send({ hello: 'world' })
|
|
106
|
+
})
|
|
107
|
+
done()
|
|
108
|
+
}, { logLevel: 'info', logSerializers: { test: value => 'X' + value } })
|
|
109
|
+
|
|
110
|
+
await fastify.ready()
|
|
111
|
+
|
|
112
|
+
{
|
|
113
|
+
const response = await fastify.inject({ method: 'GET', url: '/plugin' })
|
|
114
|
+
const body = await response.json()
|
|
115
|
+
t.assert.deepEqual(body.hello, 'world')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for await (const [line] of on(stream, 'data')) {
|
|
119
|
+
// either test or msg
|
|
120
|
+
t.assert.deepEqual(line.test || line.msg, lines.shift())
|
|
121
|
+
if (lines.length === 0) break
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
await t.test('Should set a custom logLevel for every plugin', async (t) => {
|
|
126
|
+
const lines = ['incoming request', 'info', 'request completed', 'incoming request', 'debug', 'request completed']
|
|
127
|
+
t.plan(lines.length * 2 + 3)
|
|
128
|
+
|
|
129
|
+
const stream = split(JSON.parse)
|
|
130
|
+
|
|
131
|
+
const loggerInstance = pino({ level: 'error' }, stream)
|
|
132
|
+
|
|
133
|
+
const fastify = Fastify({
|
|
134
|
+
loggerInstance
|
|
135
|
+
})
|
|
136
|
+
t.after(() => fastify.close())
|
|
137
|
+
|
|
138
|
+
fastify.get('/', (req, reply) => {
|
|
139
|
+
req.log.warn('Hello') // we should not see this log
|
|
140
|
+
reply.send({ hello: 'world' })
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
fastify.register(function (instance, opts, done) {
|
|
144
|
+
instance.get('/info', (req, reply) => {
|
|
145
|
+
req.log.info('info') // we should see this log
|
|
146
|
+
req.log.debug('hidden log')
|
|
147
|
+
reply.send({ hello: 'world' })
|
|
148
|
+
})
|
|
149
|
+
done()
|
|
150
|
+
}, { logLevel: 'info' })
|
|
151
|
+
|
|
152
|
+
fastify.register(function (instance, opts, done) {
|
|
153
|
+
instance.get('/debug', (req, reply) => {
|
|
154
|
+
req.log.debug('debug') // we should see this log
|
|
155
|
+
req.log.trace('hidden log')
|
|
156
|
+
reply.send({ hello: 'world' })
|
|
157
|
+
})
|
|
158
|
+
done()
|
|
159
|
+
}, { logLevel: 'debug' })
|
|
160
|
+
|
|
161
|
+
await fastify.ready()
|
|
162
|
+
|
|
163
|
+
{
|
|
164
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
165
|
+
const body = await response.json()
|
|
166
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
{
|
|
170
|
+
const response = await fastify.inject({ method: 'GET', url: '/info' })
|
|
171
|
+
const body = await response.json()
|
|
172
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
{
|
|
176
|
+
const response = await fastify.inject({ method: 'GET', url: '/debug' })
|
|
177
|
+
const body = await response.json()
|
|
178
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for await (const [line] of on(stream, 'data')) {
|
|
182
|
+
t.assert.ok(line.level === 30 || line.level === 20)
|
|
183
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
184
|
+
if (lines.length === 0) break
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
await t.test('Should set a custom logSerializers for every plugin', async (t) => {
|
|
189
|
+
const lines = ['incoming request', 'Hello', 'request completed', 'incoming request', 'XHello', 'request completed', 'incoming request', 'ZHello', 'request completed']
|
|
190
|
+
t.plan(lines.length + 3)
|
|
191
|
+
|
|
192
|
+
const stream = split(JSON.parse)
|
|
193
|
+
|
|
194
|
+
const loggerInstance = pino({ level: 'info' }, stream)
|
|
195
|
+
const fastify = Fastify({
|
|
196
|
+
loggerInstance
|
|
197
|
+
})
|
|
198
|
+
t.after(() => fastify.close())
|
|
199
|
+
|
|
200
|
+
fastify.get('/', (req, reply) => {
|
|
201
|
+
req.log.warn({ test: 'Hello' })
|
|
202
|
+
reply.send({ hello: 'world' })
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
fastify.register(function (instance, opts, done) {
|
|
206
|
+
instance.get('/test1', (req, reply) => {
|
|
207
|
+
req.log.info({ test: 'Hello' })
|
|
208
|
+
reply.send({ hello: 'world' })
|
|
209
|
+
})
|
|
210
|
+
done()
|
|
211
|
+
}, { logSerializers: { test: value => 'X' + value } })
|
|
212
|
+
|
|
213
|
+
fastify.register(function (instance, opts, done) {
|
|
214
|
+
instance.get('/test2', (req, reply) => {
|
|
215
|
+
req.log.info({ test: 'Hello' })
|
|
216
|
+
reply.send({ hello: 'world' })
|
|
217
|
+
})
|
|
218
|
+
done()
|
|
219
|
+
}, { logSerializers: { test: value => 'Z' + value } })
|
|
220
|
+
|
|
221
|
+
await fastify.ready()
|
|
222
|
+
|
|
223
|
+
{
|
|
224
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
225
|
+
const body = await response.json()
|
|
226
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
{
|
|
230
|
+
const response = await fastify.inject({ method: 'GET', url: '/test1' })
|
|
231
|
+
const body = await response.json()
|
|
232
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
{
|
|
236
|
+
const response = await fastify.inject({ method: 'GET', url: '/test2' })
|
|
237
|
+
const body = await response.json()
|
|
238
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
for await (const [line] of on(stream, 'data')) {
|
|
242
|
+
t.assert.deepEqual(line.test || line.msg, lines.shift())
|
|
243
|
+
if (lines.length === 0) break
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
await t.test('Should override serializers from route', async (t) => {
|
|
248
|
+
const lines = ['incoming request', 'ZHello', 'request completed']
|
|
249
|
+
t.plan(lines.length + 1)
|
|
250
|
+
|
|
251
|
+
const stream = split(JSON.parse)
|
|
252
|
+
|
|
253
|
+
const loggerInstance = pino({ level: 'info' }, stream)
|
|
254
|
+
const fastify = Fastify({
|
|
255
|
+
loggerInstance
|
|
256
|
+
})
|
|
257
|
+
t.after(() => fastify.close())
|
|
258
|
+
|
|
259
|
+
fastify.register(function (instance, opts, done) {
|
|
260
|
+
instance.get('/', {
|
|
261
|
+
logSerializers: {
|
|
262
|
+
test: value => 'Z' + value // should override
|
|
263
|
+
}
|
|
264
|
+
}, (req, reply) => {
|
|
265
|
+
req.log.info({ test: 'Hello' })
|
|
266
|
+
reply.send({ hello: 'world' })
|
|
267
|
+
})
|
|
268
|
+
done()
|
|
269
|
+
}, { logSerializers: { test: value => 'X' + value } })
|
|
270
|
+
|
|
271
|
+
await fastify.ready()
|
|
272
|
+
|
|
273
|
+
{
|
|
274
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
275
|
+
const body = await response.json()
|
|
276
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
for await (const [line] of on(stream, 'data')) {
|
|
280
|
+
t.assert.deepEqual(line.test || line.msg, lines.shift())
|
|
281
|
+
if (lines.length === 0) break
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
await t.test('Should override serializers from plugin', async (t) => {
|
|
286
|
+
const lines = ['incoming request', 'ZHello', 'request completed']
|
|
287
|
+
t.plan(lines.length + 1)
|
|
288
|
+
|
|
289
|
+
const stream = split(JSON.parse)
|
|
290
|
+
|
|
291
|
+
const loggerInstance = pino({ level: 'info' }, stream)
|
|
292
|
+
const fastify = Fastify({
|
|
293
|
+
loggerInstance
|
|
294
|
+
})
|
|
295
|
+
t.after(() => fastify.close())
|
|
296
|
+
|
|
297
|
+
fastify.register(function (instance, opts, done) {
|
|
298
|
+
instance.register(context1, {
|
|
299
|
+
logSerializers: {
|
|
300
|
+
test: value => 'Z' + value // should override
|
|
301
|
+
}
|
|
302
|
+
})
|
|
303
|
+
done()
|
|
304
|
+
}, { logSerializers: { test: value => 'X' + value } })
|
|
305
|
+
|
|
306
|
+
function context1 (instance, opts, done) {
|
|
307
|
+
instance.get('/', (req, reply) => {
|
|
308
|
+
req.log.info({ test: 'Hello' })
|
|
309
|
+
reply.send({ hello: 'world' })
|
|
310
|
+
})
|
|
311
|
+
done()
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
await fastify.ready()
|
|
315
|
+
|
|
316
|
+
{
|
|
317
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
318
|
+
const body = await response.json()
|
|
319
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
for await (const [line] of on(stream, 'data')) {
|
|
323
|
+
t.assert.deepEqual(line.test || line.msg, lines.shift())
|
|
324
|
+
if (lines.length === 0) break
|
|
325
|
+
}
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
await t.test('Should increase the log level for a specific plugin', async (t) => {
|
|
329
|
+
const lines = ['Hello']
|
|
330
|
+
t.plan(lines.length * 2 + 1)
|
|
331
|
+
|
|
332
|
+
const stream = split(JSON.parse)
|
|
333
|
+
|
|
334
|
+
const loggerInstance = pino({ level: 'info' }, stream)
|
|
335
|
+
|
|
336
|
+
const fastify = Fastify({
|
|
337
|
+
loggerInstance
|
|
338
|
+
})
|
|
339
|
+
t.after(() => fastify.close())
|
|
340
|
+
|
|
341
|
+
fastify.register(function (instance, opts, done) {
|
|
342
|
+
instance.get('/', (req, reply) => {
|
|
343
|
+
req.log.error('Hello') // we should see this log
|
|
344
|
+
reply.send({ hello: 'world' })
|
|
345
|
+
})
|
|
346
|
+
done()
|
|
347
|
+
}, { logLevel: 'error' })
|
|
348
|
+
|
|
349
|
+
await fastify.ready()
|
|
350
|
+
|
|
351
|
+
{
|
|
352
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
353
|
+
const body = await response.json()
|
|
354
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
for await (const [line] of on(stream, 'data')) {
|
|
358
|
+
t.assert.deepEqual(line.level, 50)
|
|
359
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
360
|
+
if (lines.length === 0) break
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
await t.test('Should set the log level for the customized 404 handler', async (t) => {
|
|
365
|
+
const lines = ['Hello']
|
|
366
|
+
t.plan(lines.length * 2 + 1)
|
|
367
|
+
|
|
368
|
+
const stream = split(JSON.parse)
|
|
369
|
+
|
|
370
|
+
const loggerInstance = pino({ level: 'warn' }, stream)
|
|
371
|
+
|
|
372
|
+
const fastify = Fastify({
|
|
373
|
+
loggerInstance
|
|
374
|
+
})
|
|
375
|
+
t.after(() => fastify.close())
|
|
376
|
+
|
|
377
|
+
fastify.register(function (instance, opts, done) {
|
|
378
|
+
instance.setNotFoundHandler(function (req, reply) {
|
|
379
|
+
req.log.error('Hello')
|
|
380
|
+
reply.code(404).send()
|
|
381
|
+
})
|
|
382
|
+
done()
|
|
383
|
+
}, { logLevel: 'error' })
|
|
384
|
+
|
|
385
|
+
await fastify.ready()
|
|
386
|
+
|
|
387
|
+
{
|
|
388
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
389
|
+
t.assert.deepEqual(response.statusCode, 404)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
for await (const [line] of on(stream, 'data')) {
|
|
393
|
+
t.assert.deepEqual(line.level, 50)
|
|
394
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
395
|
+
if (lines.length === 0) break
|
|
396
|
+
}
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
await t.test('Should set the log level for the customized 500 handler', async (t) => {
|
|
400
|
+
const lines = ['Hello']
|
|
401
|
+
t.plan(lines.length * 2 + 1)
|
|
402
|
+
|
|
403
|
+
const stream = split(JSON.parse)
|
|
404
|
+
|
|
405
|
+
const loggerInstance = pino({ level: 'warn' }, stream)
|
|
406
|
+
|
|
407
|
+
const fastify = Fastify({
|
|
408
|
+
loggerInstance
|
|
409
|
+
})
|
|
410
|
+
t.after(() => fastify.close())
|
|
411
|
+
|
|
412
|
+
fastify.register(function (instance, opts, done) {
|
|
413
|
+
instance.get('/', (req, reply) => {
|
|
414
|
+
req.log.error('kaboom')
|
|
415
|
+
reply.send(new Error('kaboom'))
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
instance.setErrorHandler(function (e, request, reply) {
|
|
419
|
+
reply.log.fatal('Hello')
|
|
420
|
+
reply.code(500).send()
|
|
421
|
+
})
|
|
422
|
+
done()
|
|
423
|
+
}, { logLevel: 'fatal' })
|
|
424
|
+
|
|
425
|
+
await fastify.ready()
|
|
426
|
+
|
|
427
|
+
{
|
|
428
|
+
const response = await fastify.inject({ method: 'GET', url: '/' })
|
|
429
|
+
t.assert.deepEqual(response.statusCode, 500)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
for await (const [line] of on(stream, 'data')) {
|
|
433
|
+
t.assert.deepEqual(line.level, 60)
|
|
434
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
435
|
+
if (lines.length === 0) break
|
|
436
|
+
}
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
await t.test('Should set a custom log level for a specific route', async (t) => {
|
|
440
|
+
const lines = ['incoming request', 'Hello', 'request completed']
|
|
441
|
+
t.plan(lines.length + 2)
|
|
442
|
+
|
|
443
|
+
const stream = split(JSON.parse)
|
|
444
|
+
|
|
445
|
+
const loggerInstance = pino({ level: 'error' }, stream)
|
|
446
|
+
|
|
447
|
+
const fastify = Fastify({
|
|
448
|
+
loggerInstance
|
|
449
|
+
})
|
|
450
|
+
t.after(() => fastify.close())
|
|
451
|
+
|
|
452
|
+
fastify.get('/log', { logLevel: 'info' }, (req, reply) => {
|
|
453
|
+
req.log.info('Hello')
|
|
454
|
+
reply.send({ hello: 'world' })
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
fastify.get('/no-log', (req, reply) => {
|
|
458
|
+
req.log.info('Hello')
|
|
459
|
+
reply.send({ hello: 'world' })
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
await fastify.ready()
|
|
463
|
+
|
|
464
|
+
{
|
|
465
|
+
const response = await fastify.inject({ method: 'GET', url: '/log' })
|
|
466
|
+
const body = await response.json()
|
|
467
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
{
|
|
471
|
+
const response = await fastify.inject({ method: 'GET', url: '/no-log' })
|
|
472
|
+
const body = await response.json()
|
|
473
|
+
t.assert.deepEqual(body, { hello: 'world' })
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
for await (const [line] of on(stream, 'data')) {
|
|
477
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
478
|
+
if (lines.length === 0) break
|
|
479
|
+
}
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
await t.test('should pass when using unWritable props in the logger option', (t) => {
|
|
483
|
+
t.plan(8)
|
|
484
|
+
const fastify = Fastify({
|
|
485
|
+
logger: Object.defineProperty({}, 'level', { value: 'info' })
|
|
486
|
+
})
|
|
487
|
+
t.after(() => fastify.close())
|
|
488
|
+
|
|
489
|
+
t.assert.deepEqual(typeof fastify.log, 'object')
|
|
490
|
+
t.assert.deepEqual(typeof fastify.log.fatal, 'function')
|
|
491
|
+
t.assert.deepEqual(typeof fastify.log.error, 'function')
|
|
492
|
+
t.assert.deepEqual(typeof fastify.log.warn, 'function')
|
|
493
|
+
t.assert.deepEqual(typeof fastify.log.info, 'function')
|
|
494
|
+
t.assert.deepEqual(typeof fastify.log.debug, 'function')
|
|
495
|
+
t.assert.deepEqual(typeof fastify.log.trace, 'function')
|
|
496
|
+
t.assert.deepEqual(typeof fastify.log.child, 'function')
|
|
497
|
+
})
|
|
498
|
+
|
|
499
|
+
await t.test('Should throw an error if logger instance is passed to `logger`', async (t) => {
|
|
500
|
+
t.plan(2)
|
|
501
|
+
const stream = split(JSON.parse)
|
|
502
|
+
|
|
503
|
+
const logger = require('pino')(stream)
|
|
504
|
+
|
|
505
|
+
try {
|
|
506
|
+
Fastify({ logger })
|
|
507
|
+
} catch (err) {
|
|
508
|
+
t.assert.ok(err)
|
|
509
|
+
t.assert.deepEqual(err.code, 'FST_ERR_LOG_INVALID_LOGGER_CONFIG')
|
|
510
|
+
}
|
|
511
|
+
})
|
|
512
|
+
|
|
513
|
+
await t.test('Should throw an error if options are passed to `loggerInstance`', async (t) => {
|
|
514
|
+
t.plan(2)
|
|
515
|
+
try {
|
|
516
|
+
Fastify({ loggerInstance: { level: 'log' } })
|
|
517
|
+
} catch (err) {
|
|
518
|
+
t.assert.ok(err)
|
|
519
|
+
t.assert.strictEqual(err.code, 'FST_ERR_LOG_INVALID_LOGGER_INSTANCE')
|
|
520
|
+
}
|
|
521
|
+
})
|
|
522
|
+
|
|
523
|
+
await t.test('If both `loggerInstance` and `logger` are provided, an error should be thrown', async (t) => {
|
|
524
|
+
t.plan(2)
|
|
525
|
+
const loggerInstanceStream = split(JSON.parse)
|
|
526
|
+
const loggerInstance = pino({ level: 'error' }, loggerInstanceStream)
|
|
527
|
+
const loggerStream = split(JSON.parse)
|
|
528
|
+
try {
|
|
529
|
+
Fastify({
|
|
530
|
+
logger: {
|
|
531
|
+
stream: loggerStream,
|
|
532
|
+
level: 'info'
|
|
533
|
+
},
|
|
534
|
+
loggerInstance
|
|
535
|
+
})
|
|
536
|
+
} catch (err) {
|
|
537
|
+
t.assert.ok(err)
|
|
538
|
+
t.assert.deepEqual(err.code, 'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED')
|
|
539
|
+
}
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
await t.test('`logger` should take pino configuration and create a pino logger', async (t) => {
|
|
543
|
+
const lines = ['hello', 'world']
|
|
544
|
+
t.plan(2 * lines.length + 2)
|
|
545
|
+
const loggerStream = split(JSON.parse)
|
|
546
|
+
const fastify = Fastify({
|
|
547
|
+
logger: {
|
|
548
|
+
stream: loggerStream,
|
|
549
|
+
level: 'error'
|
|
550
|
+
}
|
|
551
|
+
})
|
|
552
|
+
t.after(() => fastify.close())
|
|
553
|
+
fastify.get('/hello', (req, reply) => {
|
|
554
|
+
req.log.error('hello')
|
|
555
|
+
reply.code(404).send()
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
fastify.get('/world', (req, reply) => {
|
|
559
|
+
req.log.error('world')
|
|
560
|
+
reply.code(201).send()
|
|
561
|
+
})
|
|
562
|
+
|
|
563
|
+
await fastify.ready()
|
|
564
|
+
{
|
|
565
|
+
const response = await fastify.inject({ method: 'GET', url: '/hello' })
|
|
566
|
+
t.assert.deepEqual(response.statusCode, 404)
|
|
567
|
+
}
|
|
568
|
+
{
|
|
569
|
+
const response = await fastify.inject({ method: 'GET', url: '/world' })
|
|
570
|
+
t.assert.deepEqual(response.statusCode, 201)
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
for await (const [line] of on(loggerStream, 'data')) {
|
|
574
|
+
t.assert.deepEqual(line.level, 50)
|
|
575
|
+
t.assert.deepEqual(line.msg, lines.shift())
|
|
576
|
+
if (lines.length === 0) break
|
|
577
|
+
}
|
|
578
|
+
})
|
|
579
|
+
})
|