-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Allow multiple instances of middleware #263
Conversation
- scope pino loggers to lambda closures instead of function properties - set request and response log property to first middleware pino logger but capture additional middleware pino loggers in new allLogs request and response property - unit tests to confirm each middleware redact properties are independent
@@ -18,7 +18,6 @@ pinoHttp({ genReqId: (req: IncomingMessage, res: ServerResponse) => res.statusCo | |||
pinoHttp({ genReqId: (req: IncomingMessage, res: ServerResponse) => 'foo' }); | |||
pinoHttp({ genReqId: (req: IncomingMessage, res: ServerResponse) => Buffer.allocUnsafe(16) }); | |||
pinoHttp({ useLevel: 'error' }); | |||
pinoHttp({ prettyPrint: true }); // deprecated but still present in pino. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
git hooks, tests and compilation failed unless I removed this line; not sure still required and still present in upstream pino
@@ -80,6 +80,7 @@ declare module "http" { | |||
interface IncomingMessage { | |||
id: ReqId; | |||
log: pino.Logger; | |||
allLogs: pino.Logger[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when multiple pino-http middleware are registered, the first registered middleware's pino logger will be attached to the req.log property. The remaining middleware's pino loggers (as well as the first) will be available in this new allLogs property.
this.removeListener('close', onResFinished) | ||
this.removeListener('error', onResFinished) | ||
this.removeListener('finish', onResFinished) | ||
const result = (req, res, next) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of attaching the pino logger to the statically defined loggingMiddleware function and returning the single reference to it, we create a new closure called result and attach the pino logger to the result. Each call to pinoHttp will create a new result closure so each call gets it's own closure rather than sharing the loggingMiddleware function and it's logging property.
let shouldLogSuccess = true | ||
|
||
req.id = genReqId(req, res) | ||
req.id = req.id || genReqId(req, res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when multiple middleware are registered we have to decide how the req.id is to be set. Convention established here is that the first middleware's genReqId function will set the req.id, subsequent middleware's genReqId functions will be ignored, so the req.id will be set only once per request.
This may warrant additional discussion.
) | ||
} | ||
|
||
function loggingMiddleware (req, res, next) { | ||
function loggingMiddleware (logger, req, res, next) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the logger is attached to the result closure instead of this function, we pass the logger into the function as a param instead of assuming it is attached as function property.
if (err || this.err || this.statusCode >= 500) { | ||
const error = err || this.err || new Error('failed with status code ' + this.statusCode) | ||
if (err || res.err || res.statusCode >= 500) { | ||
const error = err || res.err || new Error('failed with status code ' + res.statusCode) | ||
|
||
log[level]( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the current implementation emits the final log message on the single logger attached to the response object. Instead we have passed the intended logger in as a parameter from a new closure onResponseComplete so that each middleware generates it's logs to its own pino logger, not relying on the logger attached to the response object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
- changing usage of modern js features to pass CICD tests
Looks like CICD had some tests that either don't run by default locally or at least aren't run the same way and they didn't like my usage of the nullish coalescing operator |
- reverting removal of prettyPrint property
@mcollina Whenever you have a free moment would you mind kicking off the workflow again? I don't seem to have permission but hoping that my fix has addressed the CICD issue. 🙏 |
- removing deprecated usage of prettyPrint as it is failing on CICD as well
@mcollina Oof; okay so what is the saying? Third time is the charm? I was worried that perhaps my removal of the prettyPrint property typescript test may have been premature and although it wasn't passing for me locally perhaps it would pass on CICD -- so I restored the line while fixing the |
- removing another instance of ??=
@@ -1,6 +1,7 @@ | |||
name: CI | |||
|
|||
on: | |||
workflow_dispatch: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows you to manually run your GItHub CICD workflow from the Actions tab without pushing a commit. If you would prefer me to revert this change I can. Just LMK.
@mcollina I just realized that I can enable the same GitHub Actions CICD pipeline on my fork. So I went ahead and did that and found another So feel free to start the CICD workflow whenever you are ready we should be green. =) |
@mcollina Latest failure seems to be a problem with how the test was written. The test assumes the sample server will always result in a 0 latency response time but in this particular test run. The response time turned out to be 1. I'll go ahead and update the test to match any digits instead of just 0 which should make the test more robust.
|
- update test to account for potential test server latency
Yay, finally an all green CICD run. Guess it's up to y'all (@mcollina) to decide when to merge and cut a release. Thanks again for releasing this project to OSS, it's proven very beneficial for our request / response logging. 🎉 |
People modify the req.log to add properties into log. #30 With this change, the properties are no longer logged. |
PR to address Issue #260