Custom drains
A drain is a function that receives wide events and ships them somewhere terminal: an HTTP API, a message queue, a database, a webhook. evlog ships built-in drains for popular providers (Adapters overview). When you need a destination that isn't covered, write your own.
Canonical guide
Full reference at Custom adapters:
defineDrain()for arbitrary transports (queue, DB, native SDK)defineHttpDrain()for HTTP-based backends (auto timeouts + retries + identity headers)- Configuration resolution patterns (
runtimeConfig, env vars, overrides) - Error handling and retries
This page exists in the build-on-top section as a pointer — same content, classified by axis.
A 5-minute example — internal Loki drain
import { defineHttpDrain } from 'evlog/toolkit'
export function createLokiDrain(overrides?: { url?: string; token?: string }) {
return defineHttpDrain<{ url: string; token: string }>({
name: 'loki',
resolve: () => ({
url: overrides?.url ?? process.env.LOKI_URL!,
token: overrides?.token ?? process.env.LOKI_TOKEN!,
}),
encode: (events, config) => ({
url: `${config.url}/loki/api/v1/push`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${config.token}`,
},
body: JSON.stringify({
streams: events.map(e => ({
stream: { service: e.service, level: e.level },
values: [[String(Date.parse(e.timestamp) * 1e6), JSON.stringify(e)]],
})),
}),
}),
})
}
defineHttpDrain handles abort timeouts, exponential backoff on 5xx / network errors, and automatic identity headers — you only describe how to encode events into the request.
Going further
- Drain pipeline — wrap your drain in batch + retry + buffer overflow protection
- Identity headers — what your drain advertises on every request
- Drains as packages — publish your drain as
@my-org/evlog-loki
Overview
Sinks are where events leave evlog — built-in drain adapters, custom drains, the drain pipeline (batch + retry + fanout), and identity headers.
Drain pipeline
createDrainPipeline wraps any drain in batch + retry + buffer overflow protection. Required for non-trivial production volume; supports fanout to multiple drains in parallel.