Koa Bunyan Logger Middleware

raw JSON →
2.1.0 verified Thu Apr 23 auth: no javascript

Koa-bunyan-logger is a Koa middleware designed for integrating structured logging into Koa v2.x applications, leveraging the popular Bunyan logging library. The current stable version is 2.1.0. While its release cadence has been infrequent, updates typically coincide with significant Koa version shifts or critical bug fixes. This library aims to be flexible and lightweight, allowing applications to customize logging behavior without excessive overhead. A key differentiator is its ability to provide flexible log context, request logging, and explicit support for ignoring specific paths, ensuring that only relevant requests generate log entries. It allows passing an existing Bunyan logger instance or creating a new one with options, and handles request IDs for tracing. It provides middleware specifically for setting request context and logging request/response cycles, including duration and status-based log levels. This package is built on CommonJS but can be imported into ESM projects via interop.

error TypeError: app.use is not a function
cause This error often occurs when initializing a Koa v2+ application using `koa()` instead of `new Koa()`. `koa-bunyan-logger` targets Koa v2.x.
fix
Ensure Koa is initialized correctly for v2.x: change const app = koa(); to const app = new Koa();
error Application logs appear as raw JSON objects in the console, instead of a human-readable format.
cause Bunyan outputs logs as structured JSON by default. To make them human-readable, you need to pipe your application's output through the Bunyan CLI formatter.
fix
Run your Node.js application and pipe its output to the bunyan command-line tool. For example: node your_app.js | npx bunyan -o short.
breaking Version 2.0.0 and above of `koa-bunyan-logger` are specifically designed for Koa v2.x applications. Attempting to use these versions with Koa v1.x will lead to compatibility issues.
fix Ensure your Koa application is running version 2.x or later. If you must use Koa v1.x, downgrade `koa-bunyan-logger` to a v1.x release.
breaking Starting with version 1.2.0, the `req` and `res` objects passed to the logger context changed from Koa's wrapper objects (`this.request`, `this.response`) to the native Node.js HTTP objects (`this.req`, `this.res`). This alters the available properties for logging (e.g., `res.statusCode` instead of `res.status`).
fix Review and update any custom log field accesses to use properties available on the native Node.js `req` and `res` objects.
gotcha Koa's default error handler will log raw error stack traces to `stderr` in a non-JSON format, which can interfere with structured logging. It is strongly recommended to disable it.
fix Add `app.on('error', () => {});` to your Koa application's initialization code to suppress the default error logging.
gotcha `koa-bunyan-logger` uses CommonJS module exports. When used in an ESM project, ensure you use the default import (`import koaBunyanLogger from 'koa-bunyan-logger';`) and access sub-middlewares as properties (`koaBunyanLogger.requestLogger()`), as direct named imports are not supported.
fix Adopt the pattern `import koaBunyanLogger from 'koa-bunyan-logger';` followed by `app.use(koaBunyanLogger.requestLogger());` instead of attempting named imports like `import { requestLogger } from 'koa-bunyan-logger';`.
npm install koa-bunyan-logger
yarn add koa-bunyan-logger
pnpm add koa-bunyan-logger

This quickstart demonstrates setting up a Koa v2 application with `koa-bunyan-logger`. It shows how to initialize the logger, apply request ID context and request/response logging middleware (including path ignoring), use `ctx.log` within custom middleware, and properly configure Koa's error handling for structured logs. The code uses modern ESM syntax.

import Koa from 'koa';
import bunyan from 'bunyan';
import koaBunyanLogger from 'koa-bunyan-logger';

const app = new Koa();

// Create a Bunyan logger instance, which koa-bunyan-logger will use
const appLogger = bunyan.createLogger({
  name: 'my-koa-app',
  level: 'info',
  serializers: bunyan.stdSerializers
});

// Apply the main logging middleware with the custom logger instance
app.use(koaBunyanLogger(appLogger));

// Add middleware for setting a request ID context
app.use(koaBunyanLogger.requestIdContext());

// Add middleware for logging request/response cycles
app.use(koaBunyanLogger.requestLogger({
  // Example option: ignore specific paths from detailed request logging
  ignorePath: ['/healthcheck', '/metrics']
}));

// Custom application middleware to use the logger in a request context
app.use(async (ctx, next) => {
  ctx.log.info('Received request from %s for %s', ctx.request.ip, ctx.path);
  await next();
  // Note: 'x-response-time' header might need to be set by another middleware if desired
  ctx.log.info({ status: ctx.status }, 'Handled request for %s', ctx.path);
});

// Simple route handling
app.use(async (ctx) => {
  if (ctx.path === '/healthcheck') {
    ctx.body = 'OK';
  } else {
    ctx.body = 'Hello World';
  }
});

// IMPORTANT: Disable Koa's default error handler to prevent raw stack traces
app.on('error', () => {});

const PORT = process.env.PORT ?? 8000;
app.listen(PORT, () => {
  console.log(`Server listening on http://localhost:${PORT}`);
  console.log('To view structured logs, pipe output to bunyan CLI: node yourfile.js | npx bunyan -o short');
});