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

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

drain pipeline
0/5 delivered
wide event
{
  level:    "info",
  method:   "POST",
  path:     "/checkout",
  duration: 234,
  user:     {...},
  cart:     {...}
}
BUILDING
  1. axiom
    pending
  2. otlp
    pending
  3. sentry
    pending
  4. nuxthub
    pending
  5. fs
    pending
fire-and-forget retry with backoff one failure ≠ blocked response ✓ all destinations resolved

在代码中无需命名目标地发送事件

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

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

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

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

选择目标

Axiom

将日志发送到 Axiom,Axiom 会为每个字段建立索引,因此您可以针对任意字段进行查询。

PostHog

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

Sentry

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

Better Stack

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

Datadog

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

Grafana Loki

将日志推送到自托管、多租户或 Grafana Cloud Loki。

ClickHouse

将日志插入 ClickHouse,以便对海量数据进行快速聚合。

OTLP

面向 Grafana、Datadog、Honeycomb 等平台的 OpenTelemetry 协议。

HyperDX

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

文件系统

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

NuxtHub

在您的 NuxtHub 数据库中进行自托管日志存储,并带有自动保留策略。

内存

适用于任何运行时的内存环形缓冲区,包括 Cloudflare Workers。

自定义

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

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)
})