编写自定义增强器,为广泛事件添加任何派生上下文信息。增强器是一个接收 EnrichContext 并修改事件的函数。
基本示例
为每个事件添加部署元数据:
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
evlog:enrich 钩子接收一个 EnrichContext:
enrich-context.ts
interface EnrichContext {
/** 发出的广泛事件(可变) */
event: WideEvent
/** 请求元数据 */
request?: {
method?: string
path?: string
requestId?: string
}
/** 安全的HTTP请求头(已过滤敏感头) */
headers?: Record<string, string>
/** 响应元数据 */
response?: {
status?: number
headers?: Record<string, string>
}
}
工厂模式
对于带有选项的可复用增强器,使用工厂模式(与内置增强器相同):
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)
})
})
与内置增强器结合使用
将自定义增强器与内置增强器混合使用:
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) => {
// 运行内置增强器
for (const enricher of builtIn) enricher(ctx)
// 添加自定义上下文
ctx.event.region = process.env.FLY_REGION ?? process.env.AWS_REGION
ctx.event.instance = process.env.FLY_ALLOC_ID ?? process.env.HOSTNAME
})
})
更多示例
功能标志
server/plugins/evlog-enrich.ts
nitroApp.hooks.hook('evlog:enrich', (ctx) => {
ctx.event.featureFlags = {
newCheckout: isEnabled('new-checkout'),
betaApi: isEnabled('beta-api'),
}
})
响应时间分类
server/plugins/evlog-enrich.ts
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'
})