Bunyan HTTP Middleware Logger
bunyan-middleware is a Node.js middleware for logging HTTP requests and responses using the Bunyan logger. Currently at version 1.0.2, it appears to be a stable project, though its release cadence is not explicitly stated. This library offers robust features for integrating structured logging into Express, Connect, or pure HTTP servers. Key differentiators include automatic management of the `X-Request-Id` header (generating a UUID if not present), logging request-response duration, providing a request-scoped logger (`req.log`) for tracing individual requests throughout an application, and custom serializers for `req` and `res` objects. It also provides functionality to obscure sensitive headers in log outputs, enhancing security and compliance. It is a direct dependency of an existing Bunyan logger instance, allowing for consistent logging configuration.
Common errors
-
TypeError: bunyanMiddleware is not a function
cause Attempting to use `import bunyanMiddleware from 'bunyan-middleware'` in an ESM context without proper CommonJS interoperability configuration, leading to the module object being imported instead of the default export function.fixIn TypeScript or CommonJS, use `const bunyanMiddleware = require('bunyan-middleware')`. If forced to use ESM `import` in a modern Node.js environment, ensure your `tsconfig.json` or bundler settings handle CommonJS imports correctly, or wrap `require` in a utility function. -
Sensitive headers (e.g., Authorization, Cookie) are appearing in logs despite `obscureHeaders` being configured.
cause The `obscureHeaders` option is case-sensitive or not configured correctly, or the headers are being logged by other means before `bunyan-middleware` processes them.fixVerify that the header names in the `obscureHeaders` array exactly match the casing of the incoming HTTP headers. Double-check that `bunyan-middleware` is applied early in your middleware stack to obscure headers before other logging mechanisms capture them.
Warnings
- gotcha This package is distributed as a CommonJS module. In modern TypeScript or pure ESM projects, a direct `import bunyanMiddleware from 'bunyan-middleware'` will likely fail or require specific bundler configurations. The recommended TypeScript import is `import bunyanMiddleware = require('bunyan-middleware')`.
- gotcha The `logger` option is a required configuration. Failing to provide a valid Bunyan logger instance will result in runtime errors as the middleware attempts to use it.
- gotcha When using `bunyan-middleware` with Express mounted apps that rewrite `req.url`, the default Bunyan `req` serializer might log the rewritten URL instead of the original. `bunyan-middleware` provides its own serializer using `req.originalUrl` to mitigate this, but custom serializer overrides could reintroduce this behavior.
Install
-
npm install bunyan-middleware -
yarn add bunyan-middleware -
pnpm add bunyan-middleware
Imports
- bunyanMiddleware
import bunyanMiddleware from 'bunyan-middleware'
const bunyanMiddleware = require('bunyan-middleware') - BunyanMiddlewareOptions
import bunyanMiddleware = require('bunyan-middleware'); type Options = bunyanMiddleware.BunyanMiddlewareOptions;
Quickstart
const bunyan = require('bunyan')
const bunyanMiddleware = require('bunyan-middleware')
const express = require('express')
const app = express()
const logger = bunyan.createLogger({ name: 'My App', level: process.env.LOG_LEVEL || 'info' })
app.use(bunyanMiddleware(
{ headerName: 'X-Request-Id'
, propertyName: 'reqId'
, logName: 'req_id'
, obscureHeaders: ['authorization', 'cookie'] // Example: obscure sensitive headers
, logger: logger
, additionalRequestFinishData: function(req, res) {
// Add custom data to the 'request finish' log message
return { exampleCustomData: 'value' }
}
}
)
)
app.get('/', function (req, res) {
// Use `req.log` for request-specific logging, automatically including the request ID.
req.log.info({ user: 'guest' }, 'Accessed home route')
res.send('Hello, Bunyan Logger!')
})
const port = process.env.PORT || 3000;
app.listen(port, () => {
logger.info(`Server listening on port ${port}`);
});