Request Logging
A single router.on() subscription turns every finished request into a structured access log, with no logging code inside handlers.

Basic Access Log
Listen for request:completed and print one line per request:
typescript
import { Router } from '@neabyte/deserve'
const router = new Router({
routes: { directory: './routes' }
})
// One log line per finished request
router.on((event) => {
if (event.kind === 'request:completed') {
const { method, url, statusCode, durationMs } = event.metadata as {
method: string
url: string
statusCode: number
durationMs: number
}
console.log(`${method} ${url} ${statusCode} ${Math.round(durationMs)}ms`)
}
})
await router.serve(8000)Structured JSON Logs
Emit JSON when a log pipeline expects structured records:
typescript
router.on((event) => {
if (event.kind === 'request:completed') {
// Forward the full metadata as JSON
console.log(JSON.stringify({
at: event.timestamp,
...event.metadata
}))
}
})The metadata already includes OpenTelemetry-aligned fields like route, serverAddress, userAgent, and requestSize. See the Event Reference for the full list.
Logging Slow Requests
Filter by duration to surface only slow traffic:
typescript
router.on((event) => {
// Flag requests slower than 500ms
if (event.kind === 'request:completed') {
const { url, durationMs } = event.metadata as { url: string; durationMs: number }
if (durationMs > 500) {
console.warn(`SLOW ${url} ${Math.round(durationMs)}ms`)
}
}
})For failures, see Error Reporting.