I am using pino-http to log requests with the code below
import { pino } from 'pino';
import { pinoHttp } from 'pino-http';
import { v4 } from 'uuid';
export const logger = pino({
enabled: process.env.LOG_ENABLED === 'true',
formatters: {
level: (label) => {
return { level: label };
},
},
level: process.env.LOG_LEVEL || 'info',
name: process.env.LOGGER_NAME,
redact: {
paths: ['email', 'password', 'token'],
},
timestamp: pino.stdTimeFunctions.isoTime,
});
export const requestLogger = pinoHttp({
logger,
genReqId: function (req) {
req.id = v4();
return req.id;
},
customLogLevel: function (req, res, err) {
if (res.statusCode >= 400 && res.statusCode < 500) {
return 'warn';
} else if (res.statusCode >= 500 || err) {
return 'error';
} else if (res.statusCode >= 300 && res.statusCode < 400) {
return 'silent';
}
return 'info';
},
customProps: (req, res) => {
const accountId = req.user ? req.user.id : null;
const adminId = (req.session || {}).adminUser
? req.session.adminUser.id
: null;
return {
accountId,
adminId,
};
},
});
I would like to be able to also track the request id through the other functions, so I created a proxied logger
const proxiedLogger = new Proxy(logger, {
get(target, property, receiver) {
target = context.getStore()?.get('logger') || target;
return Reflect.get(target, property, receiver);
},
});
const contextMiddleware = (req: Request, res: Response, next: NextFunction) => {
const child = logger.child({ requestId: v4() });
const store = new Map();
store.set('logger', child);
return context.run(store, next);
};
How do I make pino-http use this logger for all requests? The issue is that pino-http comes with its own genReqId method
A bit late but here's how I tackled that issue.
You can use pino-http's customProps for that, basically you want to pull the logger from the store, extract the requestId then return it.