@davaux/logger

HTTP request logging middleware for Davaux. In development it outputs colorized human-readable log lines to the terminal. In production (NODE_ENV=production) it emits newline-delimited JSON for consumption by log aggregators like Datadog, Loki, or CloudWatch.

Installation

npm install @davaux/logger

Basic usage

// davaux.config.ts
import { defineConfig } from 'davaux/config'
import { logger } from '@davaux/logger'

export default defineConfig({
  middleware: [logger()],
})

Development output

GET  /                      200  4ms
GET  /dashboard             302  2ms  → /login
POST /api/users             201  18ms
GET  /static/style.css      304  1ms
GET  /not-found             404  3ms

Each line shows the HTTP method, path, status code, response time, and (for redirects) the destination URL. Status codes are colored: 2xx green, 3xx cyan, 4xx yellow, 5xx red.

Production output (JSON)

{"ts":"2026-05-15T12:00:00.000Z","method":"GET","path":"/dashboard","status":302,"ms":2,"location":"/login"}
{"ts":"2026-05-15T12:00:01.000Z","method":"POST","path":"/api/users","status":201,"ms":18}

JSON logs include a timestamp (ts), method, path, status, duration in milliseconds, and an optional location for redirects.

Options

logger({
  format: 'combined',      // 'combined' | 'short' | 'json' | custom fn
  ignore: ['/health', '/favicon.ico'],  // skip logging these paths
})
OptionTypeDefaultDescription
format'combined' | 'short' | 'json' | FormatFnAuto (colored in dev, JSON in prod)Log format
ignorestring[] | ((ctx) => boolean)[]Paths or predicate to suppress

Format: 'short'

Single-line with minimal fields — useful when you want compact output in production too:

2026-05-15T12:00:00.000Z GET /dashboard 302 2ms

Format: 'combined'

Apache combined log format (path, status, size, referrer, user-agent):

::1 - - [15/May/2026:12:00:00 +0000] "GET /dashboard HTTP/1.1" 302 0 "-" "Mozilla/5.0"

Format: 'json'

Forces JSON output regardless of NODE_ENV:

logger({ format: 'json' })

Custom format function

Provide a function that receives a log record and returns a string:

logger({
  format: ({ method, path, status, ms, ts }) => {
    return `[${ts}] ${method} ${path}${status} (${ms}ms)`
  },
})

Ignoring paths

Skip noisy paths like health checks and static assets:

logger({
  ignore: ['/health', '/ping', '/favicon.ico'],
})

Or use a predicate for more control:

logger({
  ignore: (ctx) => {
    return ctx.url.pathname.startsWith('/_davaux/')
      || ctx.url.pathname.endsWith('.css')
      || ctx.url.pathname.endsWith('.js')
  },
})

Using with other middleware

Logger should be one of the first middleware in the chain so it captures the full response time:

export default defineConfig({
  middleware: [
    logger(),    // first — starts the timer
    helmet(),
    cors({ origin: '*' }),
    session({ secret: process.env.SESSION_SECRET! }),
  ],
})