Before you can view the trace data of your application in the Tracing Analysis console, you must use a client to submit the trace data to Tracing Analysis. This topic describes how to use OpenTelemetry SDK for Go to submit the trace data of a Go application.

Prerequisites

Background information

OpenTelemetry SDK for Go provides distributed tracing analysis capabilities for the Go programming language. You can use OpenTelemetry Protocol (OTLP) over gRPC or HTTP to submit data to the Tracing Analysis server.

Sample code

oltp-exporter

Submit data over gRPC

  1. Add the OpenTelemetry Go dependency.
    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
  2. Initialize OpenTelemetry SDK for Go.
    You can submit data by using OpenTelemetry SDK for Go or forward data by using the open source OpenTelemetry Collector.
    • If you submit data by using OpenTelemetry SDK for Go, replace otelAgentAddr and xtraceToken with the endpoint and authentication token obtained in the Prerequisites section.
    • If you forward data by using the open source OpenTelemetry Collector, replace otelAgentAddr with the IP address of your on-premises service and delete the headers.
    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}   // Replace xtraceToken with the authentication token obtained in the Prerequisites section. 
        traceClient := otlptracegrpc.NewClient(
            otlptracegrpc.WithInsecure(),
            otlptracegrpc.WithEndpoint(otelAgentAddr),    // Replace otelAgentAddr with the endpoint obtained in the Prerequisites section. 
            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(
                // Specify the service name displayed on the backend of Tracing Analysis. 
                semconv.ServiceNameKey.String(common.ServerServiceName),
            ),
        )
        handleErr(err, "failed to create resource")
    
        bsp := sdktrace.NewBatchSpanProcessor(traceExp)
        tracerProvider := sdktrace.NewTracerProvider(
            sdktrace.WithSampler(sdktrace.AlwaysSample()),
            sdktrace.WithResource(res),
            sdktrace.WithSpanProcessor(bsp),
        )
    
        // Set the global propagator to tracecontext. The global propagator is not specified by default. 
        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)
            }
        }
    }
  3. Instrument the application.
    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)
    
        // Create a handler in OpenTelemetry. 
        handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
            // Simulate a delay.
            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)
  4. Start the application.
    go run main.go

    On the Applications page in the Tracing Analysis console, click the name of the application and view the trace data.

Submit data over HTTP

  1. Add the OpenTelemetry Go dependency.
    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
  2. Initialize OpenTelemetry SDK for Go. Replace Endpoint and URLPath with the endpoint obtained in the Prerequisites section.
    You can submit data by using OpenTelemetry SDK for Go or forward data by using the open source OpenTelemetry Collector.
    • If you submit data by using OpenTelemetry SDK for Go, replace Endpoint and URLPath with the endpoint obtained in the Prerequisites section.
    • If you forward data by using the open source OpenTelemetry Collector, replace Endpoint with the IP address of your on-premises service and delete the headers.
    func initProvider() func() {
        ctx := context.Background()
    
        traceClientHttp := otlptracehttp.NewClient(
            otlptracehttp.WithEndpoint("127.0.XX.XX:8080"),      //Replace Endpoint with the endpoint obtained in the Prerequisites section. 
            otlptracehttp.WithURLPath("/adapt_xxxxx/api/otlp/traces"),   //Replace URLPath with the endpoint obtained in the Prerequisites section. 
            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(
                // Specify the service name displayed on the backend of Tracing Analysis. 
                semconv.ServiceNameKey.String(common.ClientServiceName),
            ),
        )
        handleErr(err, "failed to create resource")
    
        bsp := sdktrace.NewBatchSpanProcessor(traceExp)
        tracerProvider := sdktrace.NewTracerProvider(
            sdktrace.WithSampler(sdktrace.AlwaysSample()),
            sdktrace.WithResource(res),
            sdktrace.WithSpanProcessor(bsp),
        )
    
        // Set the global propagator to tracecontext. The global propagator is not specified by default. 
        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)
            }
        }
    }
  3. Instrument the application.
    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)
        }
  4. Start the application.
    go run main.go

    On the Applications page in the Tracing Analysis console, click the name of the application and view the trace data.