Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Plugin to:
- `logger`, a child logger of app.log, with prepopulated header `x-request-id`;
- `reqId`, the request-id;

No options are required to register the plugin.
Optionally you can provide child logger options to customize the logger.

The `getRequestIdFastifyAppConfig()` method is exported and returns:

Expand Down
30 changes: 28 additions & 2 deletions lib/plugins/requestContextProviderPlugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@ import type { FastifyInstance } from 'fastify'
import fastify from 'fastify'
import type { RouteHandlerMethod } from 'fastify/types/route'

import type { RequireContextOptions } from './requestContextProviderPlugin'
import {
getRequestIdFastifyAppConfig,
requestContextProviderPlugin,
} from './requestContextProviderPlugin'

async function initApp(routeHandler: RouteHandlerMethod) {
async function initApp(
routeHandler: RouteHandlerMethod,
pluginOptions?: RequireContextOptions,
loggerEnabled: boolean = false,
) {
const app = fastify({
...getRequestIdFastifyAppConfig(),
logger: loggerEnabled,
})
await app.register(requestContextProviderPlugin)
await app.register(requestContextProviderPlugin, pluginOptions)

app.route({
method: 'GET',
Expand Down Expand Up @@ -55,4 +61,24 @@ describe('requestContextProviderPlugin', () => {
const response = await app.inject().get('/').end()
expect(response.statusCode).toBe(204)
})

it('redacts sensitive data from logs', async () => {
app = await initApp(
(req, res) => {
req.reqContext.logger.info({ password: 'sensitive' }, 'Dummy log message')
return res.status(204).send()
},
{
loggerOptions: {
redact: {
paths: ['password'],
},
},
},
true,
)

const response = await app.inject().get('/').end()
expect(response.statusCode).toBe(204)
})
})
16 changes: 12 additions & 4 deletions lib/plugins/requestContextProviderPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
FastifyServerOptions,
} from 'fastify'
import fp from 'fastify-plugin'
import type { ChildLoggerOptions } from 'pino'

// Augment existing FastifyRequest interface with new fields
declare module 'fastify' {
Expand Down Expand Up @@ -37,7 +38,11 @@ export function getRequestIdFastifyAppConfig(): Pick<
}
}

function plugin(fastify: FastifyInstance, opts: unknown, done: () => void) {
export type RequireContextOptions = {
loggerOptions?: ChildLoggerOptions
}

function plugin(fastify: FastifyInstance, opts: RequireContextOptions, done: () => void) {
fastify.addHook(
'onRequest',
function onRequestContextProvider(
Expand All @@ -46,9 +51,12 @@ function plugin(fastify: FastifyInstance, opts: unknown, done: () => void) {
next: HookHandlerDoneFunction,
) {
req.reqContext = {
logger: (req.log as CommonLogger).child({
'x-request-id': req.id,
}),
logger: (req.log as CommonLogger).child(
{
'x-request-id': req.id,
},
opts?.loggerOptions,
),
reqId: req.id,
}

Expand Down