OpenTelemetry与Go和Jaeger集成
目录
OpenTelemetry简介
在Go中开始使用OpenTelemetry
使用OpenTelemetry实现追踪
使用OpenTelemetry实现指标
使用OpenTelemetry实现日志
与Jaeger集成
最佳实践和高级主题
结论
1. OpenTelemetry简介
OpenTelemetry是一个开源的可观测性框架,专为云原生软件设计。它提供了一套统一的API、库、代理和收集器服务,用于捕获分布式追踪和指标。OpenTelemetry是厂商中立的,可以与多种后端系统集成,包括Jaeger。
核心概念:
追踪(Traces):表示请求在分布式系统中的流转过程
跨度(Spans):追踪中的单个工作单元
指标(Metrics):随时间变化的数值测量
日志(Logs):带时间戳的离散事件记录
2. 在Go中开始使用OpenTelemetry
要在Go项目中开始使用OpenTelemetry,您需要安装以下包:
go get go.opentelemetry.io/otel
go get go.opentelemetry.io/otel/sdk
go get go.opentelemetry.io/otel/exporters/jaeger在Go应用程序中的基本设置:
package main
import (
"context"
"log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
)
func initTracer() *sdktrace.TracerProvider {
exporter, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint("http://localhost:14268/api/traces")))
if err != nil {
log.Fatal(err)
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("my-service"),
)),
)
otel.SetTracerProvider(tp)
return tp
}
func main() {
tp := initTracer()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Printf("关闭追踪提供者时出错: %v", err)
}
}()
// 您的应用程序代码
}3. 使用OpenTelemetry实现追踪
追踪帮助您理解请求在系统中的流转。以下是创建和管理跨度的方法:
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
func performWork(ctx context.Context) {
tr := otel.Tracer("my-service")
ctx, span := tr.Start(ctx, "performWork")
defer span.End()
// 为跨度添加属性
span.SetAttributes(attribute.String("key", "value"))
// 创建子跨度
ctx, childSpan := tr.Start(ctx, "childOperation")
// 执行一些工作
childSpan.End()
// 为跨度添加事件
span.AddEvent("有趣的事件发生", trace.WithAttributes(attribute.Int("got.number", 42)))
}4. 使用OpenTelemetry实现指标
指标允许您测量和监控特定值随时间的变化:
import (
"go.opentelemetry.io/otel/metric"
)
var meter = otel.Meter("my-service")
var requestCounter metric.Int64Counter
func init() {
var err error
requestCounter, err = meter.Int64Counter(
"requests_total",
metric.WithDescription("请求总数"),
)
if err != nil {
log.Fatal(err)
}
}
func handleRequest(ctx context.Context) {
requestCounter.Add(ctx, 1)
// 处理请求
}5. 使用OpenTelemetry实现日志
虽然OpenTelemetry没有直接提供日志API,但您可以将现有的日志解决方案与追踪集成:
import (
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
)
func processItem(ctx context.Context, logger *zap.Logger, item string) {
span := trace.SpanFromContext(ctx)
logger := logger.With(zap.String("trace_id", span.SpanContext().TraceID().String()))
logger.Info("正在处理项目", zap.String("item", item))
// 处理项目
}6. 与Jaeger集成
要将您的追踪数据发送到Jaeger,您需要配置Jaeger导出器:
import (
"go.opentelemetry.io/otel/exporters/jaeger"
)
func initJaegerExporter() (*jaeger.Exporter, error) {
return jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint("http://localhost:14268/api/traces")))
}确保您已经运行了Jaeger。您可以使用Docker启动它:
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:latest7. 最佳实践和高级主题
使用上下文传播来维护跨服务边界的追踪上下文
在高吞吐量系统中实现采样以减少数据量
使用批处理来更高效地导出遥测数据
在可观测性管道中实现错误处理和弹性
考虑使用OpenTelemetry Collector进行高级数据处理和路由
8. 结论
本指南为您提供了使用OpenTelemetry和Jaeger在Go应用程序中实现可观测性的坚实基础。随着您对这些概念越来越熟悉,请探索官方文档和社区资源以了解更高级的用例和优化。
最后更新于