Extend evlog
evlog is designed to be extended on both ends — you can observe what flows through (without altering the pipeline), plug into the pipeline (enrich, decide what to keep, react to lifecycle events), or build your own bricks (custom drains for unsupported destinations, your own framework integration). Each page in this section ships with a ::prompt block you can drop into Cursor / Windsurf to scaffold the integration in your own app.
Mental model
your app code
│
│ emit
▼
┌──────────────────────────────────────────────────────────────────┐
│ evlog pipeline │
│ │
│ request lifecycle → enrich → tail sample → drain │
│ │
└──────────────────────────────────────────────────────────────────┘
│ │
│ observe (no mutation) │ ship
▼ ▼
┌─────────────────────────────────────────┐ ┌─────────────────────┐
│ stream (in-process + SSE bridge) │ │ custom drains │
│ fs reader (NDJSON history) │ │ drain pipeline │
│ consumer recipes (devtools, dashboards)│ │ (batch + fanout) │
└─────────────────────────────────────────┘ └─────────────────────┘
Three ways to extend
Observe the pipeline (no mutation)
Subscribe to events without changing what gets emitted. The stream is the live feed, the fs reader is the historic log, and consumer recipes show you how to wire either to a devtool, dashboard, CLI tail, or curl + jq.
| You want to… | Use |
|---|---|
| Subscribe to live events (in-process or over SSE for browsers / CLIs) | Stream |
| Replay or tail historic events from disk | FS reader |
Build a small consumer panel, devtool, or pipe to curl + jq | Consumer recipes |
Plug into the pipeline
Hook into the pipeline at one or more of its lifecycle stages. The four pages below cover the entire extension surface — pick one when you have a single concern, pick definePlugin when you have several.
| You want to… | Use |
|---|---|
| React to lifecycle events from a single cohesive object (multiple hooks share state) | Plugins |
| Add a derived field on every event automatically | Custom enrichers |
| Decide post-hoc whether to keep an event (status, duration, custom logic) | Tail sampling |
Identify your evlog traffic on the receiver side (override User-Agent / X-Evlog-Source) | Identity headers |
Build your own bricks
When the built-in adapters or framework integrations don't cover what you need, the toolkit lets you build your own with the same shape and ergonomics.
| You want to… | Use |
|---|---|
| Ship events to a backend without a built-in adapter (HTTP or any other transport) | Custom drains |
| Wrap any drain in batch + retry + fanout for production | Drain pipeline |
| Support a framework that's not in the list, or a non-HTTP runtime | Custom framework integration |
What works where
Only the stream (in-process bus + SSE bridge) is local-only — it lives inside one Node / Bun / Deno process and does not work on serverless platforms (Vercel Functions, Cloudflare Workers, AWS Lambda). The stream page explains the constraint in detail.
Everything else — FS reader, plugins, custom enrichers, tail sampling, identity headers, custom drains, drain pipeline, custom framework integration — runs everywhere evlog runs.
Enrichers
Add derived context to every wide event automatically — user agent, geo, request size, and trace context. Built-in enrichers from evlog/enrichers, plus how to compose them with your own.
Stream
Subscribe to wide events flowing through evlog — in-process with createStreamDrain, or over the network with the local SSE stream server.