pino-http
pino-http copied to clipboard
this.log should be replaced with req.log
I tried this:
req.log = req.log.child({ something: true });
but it didn't work. After digging into sourcecode I found this: https://github.com/pinojs/pino-http/blob/a7c82bc2d82847ba6692b20de1e7d2b65c4a1624/logger.js#L44
this
refers to res
object, so that would mean res.log
. After changing that code, something
appeared in my output.
This is very misleading since all examples suggest to use req.log
. Also there isn't res.log
doesn't have typescript type definition.
Can you add an example to reproduce the problem you are facing?
I have something like this:
router.use(pinoHttp(), (req, res, next) => {
req.log = req.log.child({ something: true })
next();
});
router.get("/example", (req, res) => {
req.log.info("some message")
res.json({ ok: true });
});
req.log.info("some message")
will have something: true
in its output, however, the request completed
will not have it, because that one relays on res
.
I hope this make it more clear.
if you're always binding the same value, this isn't a good pattern, instead do
const logger = require('pino')().child({ something: true })
const pinoHttp = require('pino-http')({ logger })
router.use(pinoHttp)
for injecting values on a per request basis use the serializers
Value changes per request. I tried setting that value on req
object, however that didn't show up in serializers from req.raw
.
I think it would be helpful to have a full example of what you are trying to do.
https://github.com/pinojs/pino-http/issues/74#issuecomment-559063426 This is almost the same thing as I'm doing, but here goes: 1.
app.use(pinoHttp());
const originalRouteMiddleware = (originalRoute) => (req, res, next) => {
req.log = req.log.child({ originalRoute });
next();
});
app.use(pinoHttp({
serializers: {
req(req) {
req.originalRoute = req.raw.originalRoute;
return req;
},
},
}));
const originalRouteMiddleware = (originalRoute) => (req, res, next) => {
req.originalRoute = originalRoute;
next();
});
Route:
router.get("/user/:userId", originalRouteMiddleware("/user/:userId"), (req, res) => {
req.log.info("some message");
res.json({ ok: true });
});
So the issues I'm facing:
- I would need to do
req.log = res.log = res.log.child({ originalRoute });
to make it work, which is misleading and not obvious if you don't take a look at sourcecode. Also, as suggested, not a good pattern. - In this case
req.raw
doesn't contain myoriginalRoute
, not sure why tho. Maybe.child
creates copy of original object? :thinking:
May I get a full example that I can run? Ideally without express (or maybe this is express-only).
Here it is: https://github.com/GuskiS/pino-express-failure
In this case req.raw doesn't contain my originalRoute, not sure why tho. Maybe .child creates copy of original object?
Child serializes the request object once at the time the log line is created. In order for that property to show up, you'd have to add it in a middleware before the pino-http one.
I do not think there is any other way than req.log = res.log = res.log.child({ originalRoute });
tbh.
You could potentially disable autoLogging
and log after you have set that value.