@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
})
| Option | Type | Default | Description |
|---|---|---|---|
format | 'combined' | 'short' | 'json' | FormatFn | Auto (colored in dev, JSON in prod) | Log format |
ignore | string[] | ((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! }),
],
})