golang实现OpenTelemetry编译时自动插桩的插件库opentelemetry-go-auto-instrumentation的使用
Golang实现OpenTelemetry编译时自动插桩的插件库opentelemetry-go-auto-instrumentation的使用
项目介绍
这个项目为Golang应用程序提供了一个自动化的解决方案,可以无需修改代码就能利用OpenTelemetry实现有效的可观测性。插桩是在编译时完成的,只需在go build
前添加otel
前缀即可开始使用。
安装方法
通过Bash安装
Linux和MacOS用户可以通过以下命令安装工具:
sudo curl -fsSL https://cdn.jsdelivr.net/gh/alibaba/opentelemetry-go-auto-instrumentation@main/install.sh | sudo bash
默认会安装在/usr/local/bin/otel
。
预编译二进制文件
可以从发布页面下载最新的预编译版本。
从源码构建
检出源代码并通过以下命令之一构建工具:
make # 仅构建
make install # 构建并安装
快速开始
检查版本:
otel version
可以设置工具的配置:
otel set -verbose # 打印详细日志
otel set -debug # 启用调试模式
otel set -rule=custom.json # 使用默认和自定义规则
通常不需要设置任何配置,只需在go build
前添加otel
前缀即可构建项目:
otel go build
otel go build -o app cmd/app
otel go build -gcflags="-m" cmd/app
这样就完成了整个过程!工具会自动为你的代码添加OpenTelemetry插桩,你可以开始观察你的应用程序了。
示例
- demo - 完整的端到端示例,展示自动插桩与OpenTelemetry追踪和指标收集
- zap logging - 集成示例展示如何自动为
github.com/uber-go/zap
包添加结构化日志插桩 - benchmark - 性能测试套件,测量自动插桩工具的开销和效率
- sql injection - 安全相关示例,展示自定义代码注入用于SQL注入检测和预防
- nethttp - HTTP监控示例,展示请求/响应头和网络流量分析的自动插桩
支持的库
插件名称 | 最小支持版本 | 最大支持版本 |
---|---|---|
database/sql | - | - |
echo | v4.0.0 | v4.12.0 |
gin | v1.7.0 | v1.10.0 |
go-redis | v9.0.5 | v9.5.1 |
gorm | v1.22.0 | v1.25.9 |
grpc | v1.44.0 | - |
logrus | v1.5.0 | v1.9.3 |
mongodb | v1.11.1 | v1.15.1 |
mux | v1.3.0 | v1.8.1 |
net/http | - | - |
zap | v1.20.0 | v1.27.0 |
我们正在逐步开源我们支持的库,非常欢迎您的贡献!
完整示例
以下是一个完整的示例展示如何使用opentelemetry-go-auto-instrumentation:
- 首先安装工具(如上所述)
- 创建一个简单的Gin应用:
// main.go
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World!",
})
})
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
- 使用otel构建应用:
otel go build -o myapp
- 运行应用:
./myapp
- 访问
http://localhost:8080/hello
,你将看到自动生成的OpenTelemetry追踪数据。
注意事项
如果在go build
时发现任何编译失败,这很可能是一个bug。欢迎在GitHub Issues中提交问题来帮助我们改进这个项目。
如果你的框架不在支持列表中,不用担心,你可以轻松地将代码注入到任何官方不支持的框架/库中。
更多关于golang实现OpenTelemetry编译时自动插桩的插件库opentelemetry-go-auto-instrumentation的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现OpenTelemetry编译时自动插桩的插件库opentelemetry-go-auto-instrumentation的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
OpenTelemetry Go 自动插桩插件库使用指南
OpenTelemetry 的自动插桩功能可以大大简化分布式追踪的接入工作。对于 Go 语言,opentelemetry-go-auto-instrumentation
是一个实现编译时自动插桩的插件库。
基本概念
自动插桩(Auto-instrumentation)是指在编译或运行时自动为应用程序添加追踪代码,而不需要手动修改业务代码。OpenTelemetry 的 Go 自动插桩主要通过以下方式实现:
- 编译时插桩:使用 Go 的编译器插件机制在编译阶段注入追踪代码
- 运行时插桩:通过修改二进制文件或使用中间件方式
安装与配置
1. 安装依赖
go get go.opentelemetry.io/otel
go get go.opentelemetry.io/otel/sdk
go get github.com/open-telemetry/opentelemetry-go-auto-instrumentation
2. 基本使用示例
package main
import (
"context"
"log"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"github.com/open-telemetry/opentelemetry-go-auto-instrumentation/pkg/instrumentors"
)
func initTracer() *sdktrace.TracerProvider {
// 创建Jaeger exporter
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint("http://localhost:14268/api/traces")))
if err != nil {
log.Fatal(err)
}
// 创建Tracer Provider
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("my-service"),
semconv.DeploymentEnvironmentKey.String("development"),
)),
)
otel.SetTracerProvider(tp)
return tp
}
func main() {
tp := initTracer()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
}
}()
// 初始化自动插桩
inst, err := instrumentors.NewInstrumentors()
if err != nil {
log.Fatal(err)
}
defer inst.Close()
// 你的业务代码
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
tr := otel.Tracer("main")
_, span := tr.Start(ctx, "handle-request")
defer span.End()
w.Write([]byte("Hello, World!"))
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
高级配置
1. 配置自动插桩选项
inst, err := instrumentors.NewInstrumentors(
instrumentors.WithServiceName("my-awesome-service"),
instrumentors.WithEnvironment("production"),
instrumentors.WithSampler(sdktrace.AlwaysSample()),
instrumentors.WithPropagators(propagation.TraceContext{}),
)
2. 选择性插桩
inst, err := instrumentors.NewInstrumentors(
instrumentors.WithInstrumentors(
// 只对HTTP和数据库操作进行插桩
instrumentors.NewHTTPInstrumentor(),
instrumentors.NewSQLInstrumentor(),
),
)
支持的自动插桩组件
opentelemetry-go-auto-instrumentation
支持以下常见组件的自动插桩:
- HTTP 服务:自动追踪 HTTP 请求
- 数据库操作:支持主流SQL数据库
- gRPC:客户端和服务端追踪
- 消息队列:Kafka、RabbitMQ等
- Redis:Redis操作追踪
编译时插桩
要实现真正的编译时插桩,需要使用 Go 的 -toolexec
标志:
go build -toolexec="/path/to/otel-go-instrument" ./...
这需要在项目中包含对应的插桩工具。
最佳实践
- 合理采样:在生产环境中配置适当的采样率
- 资源标签:添加服务名称、环境等元数据
- 错误处理:确保追踪系统不会影响主业务流程
- 性能监控:监控自动插桩对性能的影响
常见问题解决
-
无法收集追踪数据:
- 检查OTLP或Jaeger端点配置
- 验证采样器配置
-
性能下降:
- 降低采样率
- 使用批量导出
-
缺少某些操作的追踪:
- 检查是否配置了对应的instrumentor
- 可能需要手动添加特定操作的追踪
自动插桩可以显著降低接入OpenTelemetry的复杂度,但仍建议在关键业务路径上添加有意义的自定义span,以获取更完整的追踪视图。