最近在尝试用 LGTM 来实现 Go 微服务的可观测性,就顺便整理一下文档。
Tempo 会分为 4 篇文章:
Tempo 的架构
官网测试实操跑通
gin 框架发送 trace 数据到 tempo
go-zero 微服务框架使用发送数据到 tempo
本文就是写一下如何在 gin server 里面加入 trace 的逻辑
代码地址:lgtm/example/gin-lgtm at main · zxmfke/lgtm (github.com)
gin server 接入 trace,是比较简单的,只需要封装一个 tracer 的初始化和中间件就可以了。直接看代码。
Tracer Init
初始化一个 tracerProvider,并把这个 tracerProvider 设置为全局的 provider。
func InitTracer(c Config) error { var err error
err = tracerProvider(c) ... otel.SetTracerProvider(tp)
return nil}
func createExporter(c Config) (tracesdk.SpanExporter, error) { switch c.Batcher { case kindZipKin: return zipkin.New(c.Endpoint) case kindOtlphttp: opts := []otlptracehttp.Option{ otlptracehttp.WithInsecure(), otlptracehttp.WithEndpoint(c.Endpoint), } return otlptracehttp.New(context.Background(), opts...)
case kindOtlpgrpc:
opts := []otlptracegrpc.Option{ otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint(c.Endpoint), } return otlptracegrpc.New(context.Background(), opts...)
default: return nil, fmt.Errorf("unknown exporter: %s", c.Batcher) }}
复制代码
Tracer Middleware
利用 gin 路由的中间件模式,添加一个 tracer 的中间件,把要 trace 的路由的信息,在请求前记录并在请求结束后发送到 tempo。
func Trace(ctx *gin.Context) {
newSpan := Extract(ctx.Request, "trace-middleware")
defer newSpan.End()
ctx.Set(HeaderTraceContextKey, newSpan.spanCtx) ctx.Set(HeaderTraceIDKey, newSpan.SpanID())
newSpan.Inject(ctx.Request)
ctx.Next()
newSpan.SetIntTag("http.status_code", ctx.Writer.Status()) if ctx.Writer.Status() == http.StatusOK { newSpan.SetStatus(codes.Ok, "well done") return } newSpan.SetStatus(codes.Error, "something goes wrong")
}
复制代码
Main
在代码仓库的 main.go 逻辑就是初始化,并把 tracer middleware 加入到 router 里面。
func main() {
if err := tracer.InitTracer(tracer.Config{ ServiceName: "tracer-demo", Endpoint: "127.0.0.1:4318", Sampler: 1.0, Batcher: "otlphttp", }); err != nil { fmt.Println(fmt.Errorf("%s", err.Error())) return }
r := gin.Default()
r.Use(tracer.Trace) r.GET("/ping", func(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{ "message": "pong", }) })
r.POST("/test", func(ctx *gin.Context) {
Sub(ctx)
ctx.JSON(http.StatusOK, gin.H{ "code": 0, "msg": "success", })
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
复制代码
请求接口后,可以通过 Grafana Tempo 里面查看
评论