Enrichers
Custom Enrichers
Write custom enrichers to add derived context to your wide events. Add deployment metadata, tenant IDs, feature flags, or any computed data.
Write custom enrichers to add any derived context to your wide events. An enricher is a function that receives an EnrichContext and mutates the event.
Basic Example
Add deployment metadata to every event:
server/plugins/evlog-enrich.ts
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:enrich', (ctx) => {
ctx.event.deploymentId = process.env.DEPLOYMENT_ID
ctx.event.deployedBy = process.env.DEPLOYED_BY
})
})
EnrichContext
The evlog:enrich hook receives an EnrichContext:
interface EnrichContext {
/** The emitted wide event (mutable) */
event: WideEvent
/** Request metadata */
request?: {
method?: string
path?: string
requestId?: string
}
/** Safe HTTP request headers (sensitive headers filtered out) */
headers?: Record<string, string>
/** Response metadata */
response?: {
status?: number
headers?: Record<string, string>
}
}
Factory Pattern
For reusable enrichers with options, use the factory pattern (same as built-in enrichers):
server/utils/enrichers.ts
import type { EnrichContext } from 'evlog'
interface TenantEnricherOptions {
headerName?: string
overwrite?: boolean
}
export function createTenantEnricher(options: TenantEnricherOptions = {}) {
const headerName = options.headerName ?? 'x-tenant-id'
return (ctx: EnrichContext) => {
if (!options.overwrite && ctx.event.tenantId !== undefined) return
const tenantId = ctx.headers?.[headerName]
if (tenantId) {
ctx.event.tenantId = tenantId
}
}
}
server/plugins/evlog-enrich.ts
import { createTenantEnricher } from '~/server/utils/enrichers'
export default defineNitroPlugin((nitroApp) => {
const enrichTenant = createTenantEnricher({ headerName: 'x-org-id' })
nitroApp.hooks.hook('evlog:enrich', (ctx) => {
enrichTenant(ctx)
})
})
Combining with Built-in Enrichers
Mix custom enrichers with built-in ones:
server/plugins/evlog-enrich.ts
import { createUserAgentEnricher, createGeoEnricher } from 'evlog/enrichers'
export default defineNitroPlugin((nitroApp) => {
const builtIn = [
createUserAgentEnricher(),
createGeoEnricher(),
]
nitroApp.hooks.hook('evlog:enrich', (ctx) => {
// Run built-in enrichers
for (const enricher of builtIn) enricher(ctx)
// Add custom context
ctx.event.region = process.env.FLY_REGION ?? process.env.AWS_REGION
ctx.event.instance = process.env.FLY_ALLOC_ID ?? process.env.HOSTNAME
})
})
More Examples
Feature Flags
nitroApp.hooks.hook('evlog:enrich', (ctx) => {
ctx.event.featureFlags = {
newCheckout: isEnabled('new-checkout'),
betaApi: isEnabled('beta-api'),
}
})
Response Time Classification
nitroApp.hooks.hook('evlog:enrich', (ctx) => {
const duration = ctx.event.duration as number | undefined
if (duration === undefined) return
if (duration < 100) ctx.event.performanceTier = 'fast'
else if (duration < 500) ctx.event.performanceTier = 'normal'
else if (duration < 2000) ctx.event.performanceTier = 'slow'
else ctx.event.performanceTier = 'critical'
})
Next Steps
- Built-in Enrichers - See all available built-in enrichers
- Adapters - Send enriched events to external services