golang的链路追踪一般都是用的jeager,今天去官方仓库看,发现,jaeger的client已经停止维护了,一头雾水,后面研究了一番,发现有一个叫做OpenTelemetry的东西,规范了trace,metric的接口,希望大家都按照统一的标准去做。
关于OpenTelemetry使用的一些文章: www.cnblogs.com/charlieroro… my.oschina.net/yunduansing…
jaeger实现的代码,拷贝了一份过来
引入
go get go.opentelemetry.io/otel/sdk
go get go.opentelemetry.io/otel/exporters/stdout/stdouttrace
简单封装 jaeger.go
package jaeger
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
"go.opentelemetry.io/otel/trace"
"os"
)
// tracerProvider returns an OpenTelemetry TracerProvider configured to use
// the Jaeger exporter that will send spans to the provided url. The returned
// TracerProvider will also use a Resource configured with all the information
// about the application.
func tracerProvider(url, serviceName, environment, id string) (*tracesdk.TracerProvider, error) {
// Create the Jaeger exporter
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
if err != nil {
return nil, err
}
tp := tracesdk.NewTracerProvider(
// Always be sure to batch in production.
tracesdk.WithBatcher(exp),
// Record information about this application in an Resource.
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName),
attribute.String("environment", environment),
attribute.String("ID", id),
)),
)
return tp, nil
}
func NewJaeger(ctx context.Context, url, serviceName, environment, id string) {
tp, err := tracerProvider(url, serviceName, environment, id)
if err != nil {
return
}
// Register our TracerProvider as the global so any imported
// instrumentation in the future will default to using it.
otel.SetTracerProvider(tp)
ctx, cancel := context.WithCancel(ctx)
sig := make(chan os.Signal, 1)
select {
case <-ctx.Done():
case <-sig:
}
if err := tp.Shutdown(ctx); err != nil {
log.Fatal(err)
}
cancel()
}
func StartFromContext(ctx context.Context, tracer, spanName string) (context.Context, trace.Span) {
tp := otel.GetTracerProvider()
t := tp.Tracer(tracer)
return t.Start(ctx, spanName)
}
使用
go jaeger.NewJaeger(ctx, url, serviceName, environment, id)
其中 ctx 表示 go 的 context.Context,url 是 Jaeger ui 地址,serviceName 指的是微服务名,environment 指的是运行环境如 dev,id 随便传
然后就可以在 service 里面直接使用:
_, span := jaeger.StartFromContext(ctx, "trancer", "spanname")
defer span.End()
span.SetAttributes(attribute.String("data from", "redis cache"))
最后再去 jaeger ui 就能看到开头的效果。