opentelemetry-go Go 分布式追踪:完整教程与实战示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

OpenTelemetry Go:分布式追踪完全指南

1. 什么是 OpenTelemetry Go?为什么需要它?

OpenTelemetry 是一套用于生成和管理遥测数据(如链路追踪 traces、指标 metrics 和日志 logs)的 API、SDK 和工具集。opentelemetry-go 库是 OpenTelemetry 标准在 Go 语言中的官方实现。它为开发者提供了一种统一、与供应商无关的方式来对应用进行插桩,收集遥测数据,并将其发送到各种后端系统,例如 Jaeger、Zipkin、Prometheus、Grafana Tempo、Datadog 等。

为什么需要它?在当今的微服务架构中,一个用户请求往往要经过数十个不同的服务。当问题出现时(比如请求响应过慢或报错),如果没有分布式追踪,很难定位到底是哪个服务成为了瓶颈或故障源头。OpenTelemetry 能够追踪请求在整个系统中的完整路径,查看每一步的执行耗时,并将它们关联成一条由多个跨度(spans)组成的完整链路(trace)。这为开发者和 SRE 工程师提供了强大的调试、监控和性能优化工具。

OpenTelemetry 相较于其他方案(如老旧的 OpenTracing 或 OpenCensus 库)的核心优势在于其通用性和标准化。你只需使用统一的 API 编写一次代码,就可以在不修改应用代码的前提下,更换数据存储和可视化的后端。这使得 opentelemetry-go 不仅仅是一个库,更是构建可观测 Go 系统的基石。

2. 安装指南

要安装 opentelemetry-go 库及其核心组件,请使用 Go 的标准包管理器。你需要安装核心 API 包、追踪 SDK 以及导出器(例如用于控制台或 Jaeger 的导出器)。

# 安装核心 API
go get go.opentelemetry.io/otel

# 安装追踪 SDK
go get go.opentelemetry.io/otel/sdk

# 安装控制台导出器(用于调试)
go get go.opentelemetry.io/otel/exporters/stdout/stdouttrace

# 安装 HTTP 上下文传播器(用于 HTTP 集成)
go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

# 安装 Jaeger 导出器(用于生产环境)
go get go.opentelemetry.io/otel/exporters/jaeger

执行完上述命令后,所有必需的依赖项都会被自动添加到你的 go.mod 文件中。

3. 快速上手——最小化可运行示例

以下示例演示了如何创建一个包含单个跨度的简单链路,并将其输出到控制台。这是理解基本概念的绝佳起点。

package main

import (
	"context"
	"fmt"
	"log"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
	"go.opentelemetry.io/otel/trace"
)

func main() {
	// 1. 创建控制台导出器
	exporter, err := stdouttrace.New(
		stdouttrace.WithPrettyPrint(),
	)
	if err != nil {
		log.Fatal(err)
	}

	// 2. 创建带有导出器和资源的 TracerProvider
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String("my-service"),
		)),
	)
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Fatal(err)
		}
	}()

	// 3. 设置全局 TracerProvider
	otel.SetTracerProvider(tp)

	// 4. 获取 Tracer
	tracer := otel.Tracer("my-tracer")

	// 5. 创建一个跨度
	ctx, span :=                    

推荐