Pipeline overview
The pipeline is what evlog runs on every event between the moment your code calls log.info(...) (or a drain hook fires) and the moment a drain serializes the event for shipping. You extend it when you want to transform, enrich, drop, or react to events as they flow.
Built-in pipeline behavior covers head and tail sampling, redaction, built-in enrichers, and the drain pipeline.
Pages here
| What | When | |
|---|---|---|
| Plugins | definePlugin() — opt into any subset of the lifecycle hooks | You need to mix several behaviors (enrich + drain + tail-sampling) for one cohesive feature |
| Custom enrichers | defineEnricher() — derive context from request headers, env, etc. | You want to add a field on every event without touching every call site |
| Tail sampling | Decide post-hoc whether an event is kept based on the request outcome | You want to keep all errors / slow requests and drop the rest |
Mental model
emit enrich keep? drain(s)
───── ────▶ ──────── ────▶ ────────── ────▶ ─────────── ────▶ ─────────────
log.info() enricher hook tail sampling drain hook
(enrichers/plugins) (keep predicate) (drain/plugins)
Plugins can hook at every step through one unified contract, which is why they're the canonical extension point for anything more elaborate than a single-purpose enricher.
Going further
If you build something general-purpose, package it as an enricher npm so other projects can reuse it.
Recipes
Concrete copy-paste recipes — build your own minimal devtool, pipe to curl + jq, replay history then go live, and aggregate on the consumer side.
Plugins
definePlugin is the canonical extension contract for evlog. One plugin can opt into any subset of lifecycle hooks — enrich, drain, tail sampling, request lifecycle, client log observation.