在追踪应用的链路数据之前,您需要通过客户端将应用数据上报至可观测链路 OpenTelemetry 版服务端。本文介绍如何通过OpenTelemetry Go SDK上报Go应用数据。
前提条件
获取接入点信息
- 登录ARMS控制台,在左侧导航栏选择 。
- 在应用列表页面顶部选择目标地域,然后单击目标应用名称。
说明 语言列显示
图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。
- 在弹出的页面中,单击左侧导航栏上方的
图标,返回上一层。
- 在左侧导航栏单击集群配置,然后在右侧页面单击接入点信息页签。
- 在页面顶部选择需要接入的地域,然后在集群信息区域打开显示Token开关。
- 在客户端采集工具区域单击OpenTelemetry。
在下方表格的相关信息列中,获取接入点信息。说明 如果应用部署于阿里云生产环境,则选择阿里云VPC网络接入点,否则选择公网接入点。
背景信息
OpenTelemetry Go SDK提供了Go语言的分布式链路追踪能力,您可以直接使用OTLP gRPC或者HTTP协议向链路追踪服务端上报数据。示例Demo
使用gRPC协议上报
- 添加OpenTelemetry Go依赖。
go get go.opentelemetry.io/otel go get go.opentelemetry.io/otel/trace go get go.opentelemetry.io/otel/sdk go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc # otlp grpc
- 初始化OpenTelemetry Go SDK。您可以选择通过OpenTelemetry SDK直接上报或通过开源OpenTelemetry Collector转发。
- 如果选择直接上报,请将otelAgentAddr和xtraceToken替换为前提条件获取的接入点和鉴权Token。
- 如果选择使用OpenTelemetry Collector转发,请将otelAgentAddr替换为您本地部署的服务地址,并删除Header信息。
func initProvider() func() { ctx := context.Background() otelAgentAddr, xtraceToken, ok := common.ObtainXTraceInfo() if !ok { log.Fatalf("Cannot init OpenTelemetry, exit") os.Exit(-1) } headers := map[string]string{"Authentication": xtraceToken} //将xtraceToken替换为前提条件中获取的鉴权Token。 traceClient := otlptracegrpc.NewClient( otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint(otelAgentAddr), //将otelAgentAddr替换为前提条件中获取的接入点。 otlptracegrpc.WithHeaders(headers), otlptracegrpc.WithDialOption(grpc.WithBlock())) log.Println("start to connect to server") traceExp, err := otlptrace.New(ctx, traceClient) handleErr(err, "Failed to create the collector trace exporter") res, err := resource.New(ctx, resource.WithFromEnv(), resource.WithProcess(), resource.WithTelemetrySDK(), resource.WithHost(), resource.WithAttributes( // 在可观测链路 OpenTelemetry 版后端显示的服务名称。 semconv.ServiceNameKey.String(common.ServerServiceName), semconv.HostNameKey.String(common.ServerServiceHostName), ), ) handleErr(err, "failed to create resource") bsp := sdktrace.NewBatchSpanProcessor(traceExp) tracerProvider := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithResource(res), sdktrace.WithSpanProcessor(bsp), ) // 设置全局propagator为tracecontext(默认不设置)。 otel.SetTextMapPropagator(propagation.TraceContext{}) otel.SetTracerProvider(tracerProvider) return func() { cxt, cancel := context.WithTimeout(ctx, time.Second) defer cancel() if err := traceExp.Shutdown(cxt); err != nil { otel.Handle(err) } } }
- 添加埋点。
shutdown := initProvider() defer shutdown() //meter := global.Meter("demo-server-meter") serverAttribute := attribute.String("server-attribute", "foo") fmt.Println("start to gen chars for trace data") initTraceDemoData() fmt.Println("gen trace data done") tracer := otel.Tracer(common.TraceInstrumentationName) // 在OpenTelemetry中创建一个handler。 handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { // 模拟延迟 var sleep int64 switch modulus := time.Now().Unix() % 5; modulus { case 0: sleep = rng.Int63n(2000) case 1: sleep = rng.Int63n(15) case 2: sleep = rng.Int63n(917) case 3: sleep = rng.Int63n(87) case 4: sleep = rng.Int63n(1173) } ctx := req.Context() span := trace.SpanFromContext(ctx) span.SetAttributes(serverAttribute) actionChild(tracer, ctx, sleep) w.Write([]byte("Hello World")) }) wrappedHandler := otelhttp.NewHandler(handler, "/hello") http.Handle("/hello", wrappedHandler) http.ListenAndServe(":7080", nil)
- 启动应用程序。
go run main.go
登录ARMS控制台后,在 页面选择目标应用,查看链路数据。说明 语言列显示图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。
使用HTTP协议上报
- 添加OpenTelemetry Go依赖。
go get go.opentelemetry.io/otel go get go.opentelemetry.io/otel/trace go get go.opentelemetry.io/otel/sdk go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp # otlp http
- 初始化OpenTelemetry Go SDK,其中Endpoint和URLPath需替换为前提条件中获取的接入点信息。您可以选择通过OpenTelemetry SDK直接上报或通过开源OpenTelemetry Collector转发。
- 如果选择直接上报,请将Endpoint和URLPath替换为前提条件获取的接入点信息。
- 如果选择使用OpenTelemetry Collector转发,请将Endpoint替换为您本地部署的服务地址,并删除Header信息。
func initProvider() func() { ctx := context.Background() traceClientHttp := otlptracehttp.NewClient( otlptracehttp.WithEndpoint("127.0.XX.XX:8080"), //Endpoint需替换为前提条件中获取的接入点信息。 otlptracehttp.WithURLPath("/adapt_xxxxx/api/otlp/traces"), //URLPath需替换为前提条件中获取的接入点信息。 otlptracehttp.WithInsecure()) otlptracehttp.WithCompression(1) traceExp, err := otlptrace.New(ctx, traceClientHttp) handleErr(err, "Failed to create the collector trace exporter") res, err := resource.New(ctx, resource.WithFromEnv(), resource.WithProcess(), resource.WithTelemetrySDK(), resource.WithHost(), resource.WithAttributes( // 在可观测链路 OpenTelemetry 版后端显示的服务名称。 semconv.ServiceNameKey.String(common.ClientServiceName), semconv.HostNameKey.String(common.ClientServiceHostName), ), ) handleErr(err, "failed to create resource") bsp := sdktrace.NewBatchSpanProcessor(traceExp) tracerProvider := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithResource(res), sdktrace.WithSpanProcessor(bsp), ) // 设置全局propagator为tracecontext(默认不设置)。 otel.SetTextMapPropagator(propagation.TraceContext{}) otel.SetTracerProvider(tracerProvider) log.Println("OTEL init success") return func() { cxt, cancel := context.WithTimeout(ctx, time.Second) defer cancel() if err := traceExp.Shutdown(cxt); err != nil { otel.Handle(err) } } }
- 添加埋点。
tracer := otel.Tracer(common.TraceInstrumentationName) method, _ := baggage.NewMember("method", "repl") client, _ := baggage.NewMember("client", "cli") bag, _ := baggage.New(method, client) defaultCtx := baggage.ContextWithBaggage(context.Background(), bag) for { ctx, span := tracer.Start(defaultCtx, "ExecuteRequest") makeRequest(ctx) span.End() time.Sleep(time.Duration(1) * time.Second) }
- 启动应用程序。
go run main.go
登录ARMS控制台后,在 页面选择目标应用,查看链路数据。说明 语言列显示图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。