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:

  1. 首先安装工具(如上所述)
  2. 创建一个简单的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 上启动服务
}
  1. 使用otel构建应用:
otel go build -o myapp
  1. 运行应用:
./myapp
  1. 访问http://localhost:8080/hello,你将看到自动生成的OpenTelemetry追踪数据。

注意事项

如果在go build时发现任何编译失败,这很可能是一个bug。欢迎在GitHub Issues中提交问题来帮助我们改进这个项目。

如果你的框架不在支持列表中,不用担心,你可以轻松地将代码注入到任何官方不支持的框架/库中。


更多关于golang实现OpenTelemetry编译时自动插桩的插件库opentelemetry-go-auto-instrumentation的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于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 自动插桩主要通过以下方式实现:

  1. 编译时插桩:使用 Go 的编译器插件机制在编译阶段注入追踪代码
  2. 运行时插桩:通过修改二进制文件或使用中间件方式

安装与配置

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 支持以下常见组件的自动插桩:

  1. HTTP 服务:自动追踪 HTTP 请求
  2. 数据库操作:支持主流SQL数据库
  3. gRPC:客户端和服务端追踪
  4. 消息队列:Kafka、RabbitMQ等
  5. Redis:Redis操作追踪

编译时插桩

要实现真正的编译时插桩,需要使用 Go 的 -toolexec 标志:

go build -toolexec="/path/to/otel-go-instrument" ./...

这需要在项目中包含对应的插桩工具。

最佳实践

  1. 合理采样:在生产环境中配置适当的采样率
  2. 资源标签:添加服务名称、环境等元数据
  3. 错误处理:确保追踪系统不会影响主业务流程
  4. 性能监控:监控自动插桩对性能的影响

常见问题解决

  1. 无法收集追踪数据

    • 检查OTLP或Jaeger端点配置
    • 验证采样器配置
  2. 性能下降

    • 降低采样率
    • 使用批量导出
  3. 缺少某些操作的追踪

    • 检查是否配置了对应的instrumentor
    • 可能需要手动添加特定操作的追踪

自动插桩可以显著降低接入OpenTelemetry的复杂度,但仍建议在关键业务路径上添加有意义的自定义span,以获取更完整的追踪视图。

回到顶部