Skip to content

Instantly share code, notes, and snippets.

@jwalton
Created May 7, 2020 21:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jwalton/974e0d7250ac42dce575210ac1e2fb1d to your computer and use it in GitHub Desktop.
Save jwalton/974e0d7250ac42dce575210ac1e2fb1d to your computer and use it in GitHub Desktop.
import * as http from 'http';
import onFinished from 'on-finished';
/**
* Create a middleware that logs all requests.
*
* @param log - Logger to log to.
* @param [options] - Options.
* @param [options.excludeUrls] - An array of endpoints which should not be
* logged. e.g. `['/status']` will make it so the /status endpoint is
* not logged. Endpoints will only be skipped if they return a 2xx response.
* @returns - Middleware function which logs all HTTP traffic to the log.
*/
export default function makeRequestLoggerMiddleware(
log: Logger,
options: { excludeUrls?: string[] } = {}
) {
const excludeUrls = options.excludeUrls || [];
return function requestLoggerMiddleware(
req: http.IncomingMessage,
res: http.ServerResponse,
next: (err?: Error) => void
) {
const start = Date.now();
onFinished(res, function() {
try {
const url = (req as any).originalUrl || req.url;
if (excludeUrls.includes(url) && res.statusCode >= 200 && res.statusCode <= 299) {
// Skip this endpoint.
return;
}
if (req.method === 'OPTIONS') {
// Don't bother logging OPTIONS requests.
return;
}
if (!('responseTime' in res)) {
(res as any).responseTime = Date.now() - start;
}
log({
level: 'info',
req,
res,
account: (req as any).account,
tags: ['http'],
});
} catch (err) {
log.error({ err }, 'Error logging request');
}
});
return next();
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment