适配器
使用 evlog 适配器将日志发送到外部服务。内置对流行可观测性平台和自定义目标的支持。

适配器允许您将日志发送到外部可观测性平台。evlog 提供内置适配器以支持流行的服务,并且您可以为任何目标创建自定义适配器。

适配器如何工作

适配器在每次请求完成后接收一个 DrainContext,并将数据发送到外部服务。排水过程在 fire-and-forget 模式下运行,这意味着它永远不会阻塞 HTTP 响应。

如何连接适配器取决于您使用的框架:

// server/plugins/evlog-drain.ts
import { createAxiomDrain } from 'evlog/axiom'

export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('evlog:drain', createAxiomDrain())
})
Serverless 支持: 在 Cloudflare Workers 和 Vercel Edge 上,evlog 会自动使用 waitUntil() 来确保在运行时终止前排水完成。无需额外配置。

可用适配器

Axiom

将日志发送到 Axiom 以进行强大的查询和仪表板展示。

OTLP

用于 Grafana、Datadog、Honeycomb 等的 OpenTelemetry 协议。

HyperDX

使用其文档化的摄取端点和 API 密钥,通过 OTLP/HTTP 将日志发送到 HyperDX。

PostHog

将日志发送到 PostHog Logs 以进行结构化日志记录和可观测性。

Sentry

将结构化日志发送到 Sentry Logs 以进行高基数查询。

Better Stack

将日志发送到 Better Stack 以进行日志管理和告警。

Datadog

通过本地 HTTP 摄入 API 将日志发送到 Datadog Logs。

文件系统

将日志写入本地 NDJSON 文件用于调试和 AI 代理集成。

自定义

为任何目标构建您自己的适配器。

HTTP

在不耦合框架的情况下将客户端日志发送到您的服务器。

管道

批量处理事件、失败重试并处理缓冲区溢出。

独立使用

在纯 TypeScript 或 Bun 脚本(无 HTTP 框架)中使用 initLogger 中的 drain 选项。每个发出的事件都会自动被排出。

index.ts
import type { DrainContext } from 'evlog'
import { initLogger, log, createRequestLogger } from 'evlog'
import { createAxiomDrain } from 'evlog/axiom'
import { createDrainPipeline } from 'evlog/pipeline'

const pipeline = createDrainPipeline<DrainContext>()
const drain = pipeline(createAxiomDrain())

initLogger({
  env: { service: 'my-script' },
  drain,
})

log.info({ action: 'job_started' }) // 自动排出

const reqLog = createRequestLogger({ method: 'POST', path: '/process' })
reqLog.set({ processed: 42 })
reqLog.emit() // 自动排出

await drain.flush()
请参阅完整的 bun-script 示例,了解一个实际的批处理脚本。

多目标发送

通过组合排水器同时将日志发送到多个服务:

src/index.ts
import { createAxiomDrain } from 'evlog/axiom'
import { createOTLPDrain } from 'evlog/otlp'

const axiom = createAxiomDrain()
const otlp = createOTLPDrain()

const drain = async (ctx) => {
  await Promise.allSettled([axiom(ctx), otlp(ctx)])
}

然后将 drain 传递给您的框架:

// server/plugins/evlog-drain.ts
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('evlog:drain', drain)
})

排出上下文

每个适配器都会接收一个带有以下内容的 DrainContext

字段类型描述
eventWideEvent包含所有累积上下文的完整日志事件
requestobject请求元数据(methodpathrequestId
headersobject安全的 HTTP 头(敏感头会被过滤)
安全性: 敏感头信息(如 authorizationcookiex-api-key 等)会自动被过滤,不会传递给适配器。

零配置设置

所有适配器都支持通过环境变量自动配置,无需更改代码即可在不同环境中部署。

每个适配器读取以 NUXT_* 为前缀的变量(适用于 Nuxt/Nitro 的 runtimeConfig)和无前缀的备用变量(适用于任何框架):

.env
# Axiom (NUXT_AXIOM_* 或 AXIOM_*)
AXIOM_TOKEN=xaat-xxx
AXIOM_DATASET=my-logs

# OTLP (NUXT_OTLP_* 或 OTEL_*)
OTLP_ENDPOINT=https://otlp.example.com

# HyperDX (NUXT_HYPERDX_* 或 HYPERDX_*)
HYPERDX_API_KEY=<YOUR_HYPERDX_API_KEY_HERE>

# PostHog (NUXT_POSTHOG_* 或 POSTHOG_*)
POSTHOG_API_KEY=phc_xxx

# Sentry (NUXT_SENTRY_* 或 SENTRY_*)
SENTRY_DSN=https://key@o0.ingest.sentry.io/123

# Better Stack (NUXT_BETTER_STACK_* 或 BETTER_STACK_*)
BETTER_STACK_SOURCE_TOKEN=your-source-token

# Datadog (NUXT_DATADOG_* 或 DATADOG_* 或 DD_*)
DD_API_KEY=your-api-key
DD_SITE=datadoghq.eu

适配器会自动读取这些变量,因此只需调用 createXDrain() 而无需传入参数。