Framework integration
When the framework you use doesn't have an evlog/<framework> package yet, you build the integration yourself. evlog ships a small toolkit (createMiddlewareLogger, defineFrameworkIntegration) that handles the request-context plumbing — you only write the framework-specific glue.
Build an evlog integration for a custom framework
What you need to wire
The complete walkthrough lives in Custom integration. The short version:
| Surface | What it does | When to use |
|---|---|---|
defineFrameworkIntegration() | Declaratively wire request extraction + logger attachment | HTTP frameworks (Hono, Express, Fastify, Elysia, NestJS-shaped) |
createMiddlewareLogger() | Imperative path: create the logger at request start, emit on response end | When the framework's middleware shape doesn't fit declarative wiring |
createRequestLogger() | Lower-level: wrap any unit of work in a logger lifecycle | Non-HTTP runtimes (queue workers, CLI, cron, durable workflows) |
The mental model is always the same: request lifecycle → logger creation → enrich → drain. The toolkit gives you the request-context plumbing; you only write the framework-specific glue.
Non-HTTP runtimes
For queue workers, CLI drivers, cron jobs, or durable execution engines, skip the HTTP-shaped helpers and use createRequestLogger from evlog/toolkit directly:
import { createRequestLogger } from 'evlog/toolkit'
async function processJob(job: Job) {
const logger = createRequestLogger({
service: 'jobs',
context: { jobId: job.id, queue: job.queue },
})
try {
await runJob(job)
logger.set({ status: 'success' })
} catch (err) {
logger.error(err)
throw err
} finally {
await logger.emit()
}
}
Same enrichers, same drain hook, same identity headers — only the entry point shape changes.
Sinks
Build, batch, and fan out drains — write a custom drain for any backend, wrap it in createDrainPipeline for batch + retry, and compose multiple destinations through one pipeline.
Overview
Send your logs to external services with evlog adapters. Built-in support for popular observability platforms and custom destinations.