增强器

自定义增强器

编写自定义增强器,为广泛事件添加上下文信息。添加部署元数据、租户ID、功能标志或任何计算数据。

编写自定义增强器,为广泛事件添加任何派生上下文信息。增强器是一个接收 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'
})

下一步