OpenTelemetry Go Jaeger Exporter 实战指南配置、环境变量与 Span 转换原理含弃用迁移说明【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki本指南以仓库中 vendored 的go.opentelemetry.io/otel/exporters/jaeger模块官方 READMEvendor/go.opentelemetry.io/otel/exporters/jaeger/README.md为骨架结合该模块源码展开。你将掌握如何用 Go 将 OpenTelemetry Span 导出到 Jaeger AgentUDP/compact thrift与 Jaeger CollectorHTTP/thrift五个OTEL_EXPORTER_JAEGER_*环境变量的完整语义与优先级规则以及 Span 在导出链路上的序列化与分包细节同时明确该模块的弃用状态与 OTLP 迁移路径。注意本文面向当前仓库Loki中 vendor 依赖树内锁定的该 OpenTelemetry 模块版本所有 API、默认值与行为均以仓库内实际源码为准。模块定位与弃用状态必读go.opentelemetry.io/otel/exporters/jaeger是 OpenTelemetry Go SDK 官方提供的 Jaeger Span Exporter 实现负责把 SDK 采集到的 Span 转换为 Jaeger 数据结构并上报。但该模块目前处于已弃用Deprecated状态OpenTelemetry 于 2023 年 7 月停止对该 Jaeger Exporter 的支持Jaeger 官方已接受并推荐使用 OTLP 作为上报协议官方建议改用 OTLP Trace Exporter即go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp或go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc。尽管如此该模块仍随依赖树 vendored 于当前仓库的 vendor/go.opentelemetry.io/otel/exporters/jaeger 目录下完整实现仅约 10 个 Go 源文件jaeger.go、env.go、agent.go、uploader.go、reconnecting_udp_client.go、doc.go等并内嵌 Apache Thrift v0.14.1 的 vendored 副本与生成的internal/gen-go代码。对于仍在维护存量 Jaeger 链路的读者理解其配置方式与内部机制仍有现实意义对新项目则建议直接走 OTLP。安装该模块的获取命令为go get -u go.opentelemetry.io/otel/exporters/jaeger由于当前仓库通过 vendor 机制固化依赖实际使用以 vendor/go.opentelemetry.io/otel/exporters/jaeger 目录中的版本为准。该模块依赖 OpenTelemetry SDK 的sdktracego.opentelemetry.io/otel/sdk/trace与语义约定包semconv/v1.21.0并提供trace.SpanExporter接口实现可直接挂接到sdktrace.NewTracerProvider的WithSpanProcessor上仓库内 pkg/xcap/tracer_test.go 展示了 TracerProvider SpanProcessor 的标准装配方式可参考其中的sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(recorder))用法。快速上手示例New是模块的入口函数签名如下见 jaeger.gofunc New(endpointOption EndpointOption) (*Exporter, error)它接收一个EndpointOption通过WithAgentEndpoint或WithCollectorEndpoint构造并会从默认resource.Default()中读取service.name作为兜底服务名——若默认资源中也取不到服务名New会直接返回错误failed to get service name from default resource。下面是一个完整的可运行用法示例基于模块公开 API 编写package main import ( context log go.opentelemetry.io/otel go.opentelemetry.io/otel/exporters/jaeger sdktrace go.opentelemetry.io/otel/sdk/trace ) func main() { // 方式一上报到 Jaeger AgentUDPcompact thrift 协议 exp, err : jaeger.New(jaeger.WithAgentEndpoint( jaeger.WithAgentHost(localhost), jaeger.WithAgentPort(6831), )) // 方式二上报到 Jaeger CollectorHTTP thrift 协议 // exp, err : jaeger.New(jaeger.WithCollectorEndpoint( // jaeger.WithEndpoint(http://localhost:14268/api/traces), // jaeger.WithUsername(admin), // jaeger.WithPassword(secret), // )) if err ! nil { log.Fatal(err) } tp : sdktrace.NewTracerProvider( sdktrace.WithBatcher(exp), // 挂接为批量 SpanProcessor ) otel.SetTracerProvider(tp) // ... 业务代码产生 Span ... // 优雅关闭刷新并释放导出器资源 _ tp.Shutdown(context.Background()) }导出器实现sdktrace.SpanExporter接口源码中以var _ sdktrace.SpanExporter (*Exporter)(nil)静态断言因此可与sdktrace.WithBatcher等标准处理器组合使用。Exporter的ExportSpansjaeger.go会先检查 context 是否已取消或导出器是否已 Shutdown通过内部stopCh通道随后将 spans 按 Resource 分组、逐个 batch 上传Shutdownjaeger.go使用sync.Once关闭stopCh并调用底层 uploader 的shutdown释放连接。两种上报端点与配置选项导出器支持两种目标端点各自对应不同的传输协议见 README 的 Configuration 一节及 uploader.go 实现端点协议构造选项说明Jaeger Agentjaeger.thriftovercompact thriftUDPWithAgentEndpoint应用内联 sidecar/同机 Agent低延迟、易丢包Jaeger Collectorjaeger.thriftoverHTTPWithCollectorEndpoint直连 Collector可靠传输支持认证Agent 端点选项AgentEndpointOptionWithAgentEndpoint默认启用 UDP 断线自动重连AttemptReconnecting: true其可配置选项均实现在 uploader.goWithAgentHost(host string)覆盖OTEL_EXPORTER_JAEGER_AGENT_HOST默认localhostWithAgentPort(port string)覆盖OTEL_EXPORTER_JAEGER_AGENT_PORT默认6831WithLogger(*log.Logger)/WithLogr(logr.Logger)设置 Agent 客户端日志二者互相覆盖WithDisableAttemptReconnecting()关闭 UDP 重连客户端WithAttemptReconnectingInterval(d time.Duration)设置重新解析 Agent 地址的间隔默认 30 秒WithMaxPacketSize(size int)设置最大 UDP 包大小。Collector 端点选项CollectorEndpointOptionWithCollectorEndpoint支持WithEndpoint(url string)覆盖OTEL_EXPORTER_JAEGER_ENDPOINT默认http://localhost:14268/api/tracesWithUsername(username string)/WithPassword(password string)覆盖同名环境变量用于向 Collector 发送 Basic 认证两者均无默认值只有同时非空时才会设置Authorization头WithHTTPClient(client *http.Client)自定义 HTTP 客户端默认使用http.DefaultClient。优先级规则README 明确指出通过选项对象Options进行的配置优先于环境变量。即配置解析顺序为显式 Option 环境变量 内置默认值。以WithAgentEndpoint为例源码先以envOr(envAgentHost, localhost)读取环境变量兜底再依次应用传入的 Options 覆盖之见 uploader.go。环境变量完整对照表以下是 README 中给出的官方环境变量表可同时对照 env.go 中声明的常量名环境变量对应选项默认值OTEL_EXPORTER_JAEGER_AGENT_HOSTWithAgentHostlocalhostOTEL_EXPORTER_JAEGER_AGENT_PORTWithAgentPort6831OTEL_EXPORTER_JAEGER_ENDPOINTWithEndpointhttp://localhost:14268/api/tracesOTEL_EXPORTER_JAEGER_USERWithUsername无默认值不设置OTEL_EXPORTER_JAEGER_PASSWORDWithPassword无默认值不设置源码中envOr(key, defaultValue)env.go的判定逻辑是os.Getenv返回非空字符串时采用环境变量值否则回退到默认值。这意味着空字符串环境变量会被当作未设置处理。注意OTEL_EXPORTER_JAEGER_USER与OTEL_EXPORTER_JAEGER_PASSWORD属于 Collector HTTP 端点配置对 UDP Agent 端点无效。典型使用方式无需改代码纯环境变量驱动export OTEL_EXPORTER_JAEGER_AGENT_HOSTjaeger-agent.default.svc.cluster.local export OTEL_EXPORTER_JAEGER_AGENT_PORT6831 # 或直连 Collector # export OTEL_EXPORTER_JAEGER_ENDPOINThttp://jaeger-collector:14268/api/traces源码级原理Span 如何变成 Jaeger Batch理解导出链路有助于排查“字段丢失”“trace 对不上”等问题。核心转换逻辑集中在 jaeger.go分组jaegerBatchListjaeger.go按 Span 的 Resource 去重resourceKey : ss.Resource().Equivalent()聚合成多个gen.Batch每个 Batch 携带一个Process即资源信息和若干 Span空的 span 列表直接返回 nil。Resource → Processprocess 函数jaeger.go遍历 Resource 属性service.name被特殊提取为Process.ServiceName不再作为普通 tag其余属性转换为 Process tags若 Resource 中没有service.name则用New时从默认资源取到的服务名兜底。Span → Thrift SpanspanToThriftjaeger.goTraceID 与 SpanID 均以binary.BigEndian.Uint64拆分为TraceIdHigh/TraceIdLow/SpanId三个 int64 字段ParentSpanId 取父 SpanID时间戳与 Duration 统一以**微秒µsUnixNano/1000**为单位——这解释了 Jaeger UI 中时间精度与原始纳秒的差异Attributes 按类型映射为 thrift TagSTRING→VStr、BOOL→VBool、INT64→VLong、FLOAT64→VDouble切片类型bool/int64/float64/string 切片会被json.Marshal成字符串后作为VStr写入keyValueToTagjaeger.go#L231-L275附加约定 tagotel.library.name/otel.library.version来自 InstrumentationScope、span.kind非 Internal 时、otel.status_codeOK/ERROR、errortrueError 状态时、otel.status_descriptionEvents日志转换为gen.Log字段包含event事件名同名 attribute 会覆盖之以及otel.event.dropped_attributes_count被丢弃属性计数jaeger.go#L192-L194Links 全部以FOLLOWS_FROM类型的SpanRef导出不保留CHILD_OF之外的原始关系语义。传输层细节UDP 分包与 HTTP 上传AgentUDP compact thriftagent.go 实现agentClientUDP关键常量与行为udpPacketMaxLength 65000单个 UDP 报文最大字节数与 jaeger-agent 同步emitBatchOverhead 70数据报封装额外开销实际可用载荷上限为65000 - 70序列化采用 compact thrift 协议thrift.NewTCompactProtocolFactoryConf并用TMemoryBuffer先计算每个 Span 的序列化大小EmitBatch会做逐 span 分包单个 Span 超过包上限则直接丢弃并记录错误累计大小接近上限时先flush当前批次再开启新包agent.go#L123-L178默认开启重连 UDP 客户端newReconnectingUDPConn位于 reconnecting_udp_client.go会在 Agent 主机名对应的 DNS 记录变化时自动重新解析连接重连间隔默认 30 秒。CollectorHTTP binary thriftuploader.go 中collectorUploader.upload的行为使用binary thrift协议序列化整个 Batchthrift.NewTBinaryProtocolConf与 Agent 端的 compact 协议不同发起POST请求到配置的 EndpointContent-Type固定为application/x-thrift仅当 username 与 password同时非空时才调用req.SetBasicAuth设置 Basic 认证响应体被读取并丢弃io.Copy(io.Discard, resp.Body)只要 HTTP 状态码不在[200, 300)区间即返回failed to upload traces; HTTP status code: %d错误shutdown为空操作——HTTP 无长连接需要关闭。从 Jaeger Exporter 迁移到 OTLP鉴于模块已弃用README 给出的官方迁移方向是改用 OTLP Trace Exporterotlptracehttpgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp基于 HTTP/protobuf 上报适合直连 Collector 或网关otlptracegrpcgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc基于 gRPC 上报。迁移时需同步调整 Jaeger 侧配置启用 OTLP 接收端口并将原有jaeger.New(jaeger.WithAgentEndpoint(...))等调用替换为 OTLP 对应的New/WithEndpoint选项环境变量OTEL_EXPORTER_JAEGER_*也应替换为 OTLP 标准变量如OTEL_EXPORTER_OTLP_ENDPOINT。当前仓库的 vendor 依赖中已包含 OTLP 相关模块可参照 vendor 目录确认可用的 OTLP exporter 版本后平滑切换。参考资料与源码导航模块官方文档vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md入口与 Span 转换vendor/go.opentelemetry.io/otel/exporters/jaeger/jaeger.go环境变量定义vendor/go.opentelemetry.io/otel/exporters/jaeger/env.goUDP Agent 客户端vendor/go.opentelemetry.io/otel/exporters/jaeger/agent.go、vendor/go.opentelemetry.io/otel/exporters/jaeger/reconnecting_udp_client.go端点选项与 HTTP 上传vendor/go.opentelemetry.io/otel/exporters/jaeger/uploader.goThrift 生成代码vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger、vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agentSDK 装配参考pkg/xcap/tracer_test.go展示 TracerProvider SpanProcessor 的标准用法【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
