Effect 怎么把日志和 span 导出到 OTLP?
代码里加了 span 和日志,却在外部系统里什么都看不到。
因为这些信号默认只存在于进程内。在 Effect 里,导出是一个普通的 Layer:用 effect/observability 的 OtlpTracer、OtlpLogger、OtlpMetrics 构造它,再提供序列化和 HTTP 客户端两个依赖,合并进应用的主 Layer 就行。
这正是观测和业务分离的好处:不提供这个 Layer,就没有任何东西被导出,业务代码一行都不用改。如果你还不熟悉 Layer,先看 Effect 的 Layer 怎么组织依赖;如果想先分清日志、span、指标,见 Effect 里日志、span 和指标各自该观测什么。
导出的 Layer 怎么写?
import { Layer } from "effect"
import { FetchHttpClient } from "effect/http"
import { OtlpLogger, OtlpSerialization, OtlpTracer } from "effect/observability"
const resource = { serviceName: "checkout", serviceVersion: "1.0.0" }
export const ObservabilityLive = Layer.merge(
OtlpTracer.layer({ url: "http://collector:4318/v1/traces", resource }),
OtlpLogger.layer({ url: "http://collector:4318/v1/logs", resource })
).pipe(
Layer.provide(OtlpSerialization.layerJson),
Layer.provide(FetchHttpClient.layer)
)OtlpTracer 和 OtlpLogger 各自指向收集器的一个地址,resource 标明服务名和版本。它们需要序列化(OtlpSerialization.layerJson)和 HTTP 客户端(FetchHttpClient.layer)两个依赖,用 Layer.provide 补上。
不接 sink 会怎样?
没有任何东西被导出。这也让测试可以不接任何 sink。
已经在用 OpenTelemetry 怎么办?
已有 OpenTelemetry 生态的项目,可以用 @effect/opentelemetry 对接现有 SDK;全新项目不一定需要它。
想自定义日志格式怎么办?
用 Logger.make 构造 logger,再用 Logger.layer 安装。Logger.layer 默认是替换现有 logger,想保留原有的要显式合并。
版本:Effect v4(教程章节没有标注具体的 effect 版本号)。代码和关于 OTLP 导出、@effect/opentelemetry、Logger.layer的描述都来自教程章节,我没有在本文中运行过,也没有连接真实的收集器验证。