Skip to main content
Sumo Logic

Go OpenTelemetry auto-instrumentation

OpenTelemetry Golang instrumentation gives you the possibility to capture telemetry (metrics and traces) data from code written in Golang. The best way is to use https://github.com/open-telemetry/opentelemetry-go. See the list of supported libraries.

Instrumentation types

Automatic instrumentation

The best way to use Golang instrumentation is to include a supported library into your code. See below for steps required to instrument the application automatically.

Manual instrumentation

If you’re using libraries that are not officially supported or in case you want to be very specific and granular with instrumentation, you can instrument your code manually using https://pkg.go.dev/go.opentelemetry.io/otel/api. Examples of using manual instrumentation can be found in https://github.com/open-telemetry/opentelemetry-go/tree/master/example

Automatic instrumentation steps

The instructions below apply to version v0.20.0 of OpenTelemetry Go Instrumentation.

Mandatory packages installation

Installation of packages listed below is mandatory to start working with instrumentation:

go get -u go.opentelemetry.io/otel@v0.20.0

It downloads and installs OpenTelemetry package for golang. It includes APIs for traces. This package includes SDK needed also for manual instrumentation.

Next, you'll install the spans exporter. There are currently three supported protocols OTLP, Zipkin, and Jaeger. Sumo Logic recommends the OTLP gRPC exporter. Execute the command below:

go get -u go.opentelemetry.io/otel/exporters/otlp@v0.20.0

Application specific packages installation

Next, we need to download instrumented versions of libraries and put them into the following path:

go.opentelemetry.io/contrib/instrumentation/{IMPORT_PATH}/otel{PACKAGE_NAME}@{VERSION}

For example net/http package, which will be used in the example HTTP client code below:

go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.20.0

Import and initialize instrumentation packages 

To get traces from your application you need to import instrumented libraries and initialize them. An Example of an HTTP server using an instrumented library can be found here.

Tracing initialization requires a few steps to be ready. The first one is to initialize the OTLP gRPC exporter driver and exporter. The most important option in this configuration is to set up a valid OTLP receiver (collector) address. This can be done by setting up otlpgrpc.WithEndpoint(). In the code below the default OTLP receiver for Sumo Logic Kubernetes Deployment is provided. The next step is to set up a Tracer Provider. For details of the configuration see Provider implementation.

func initTracer() {
    ctx := context.Background()
    
    otlpDriver := otlpgrpc.NewDriver(
        otlpgrpc.WithInsecure(),
        otlpgrpc.WithEndpoint("collection-sumologic-otelcol.sumologic:4317"),
        otlpgrpc.WithDialOption(grpc.WithBlock()),
    )
    
    exporter, err := otlp.NewExporter(ctx, otlpDriver)
    if err != nil {
        log.Fatal(err)
    }

    tracerProvider := sdktrace.NewTracerProvider(
        sdktrace.WithBatcher(exporter),
        //sdktrace.WithSampler(sdktrace.AlwaysSample()), - please check TracerProvider.WithSampler() implementation for details.
    )
    
    otel.SetTracerProvider(tracerProvider)
    otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
        propagation.TraceContext{}, propagation.Baggage{}))
}

After preparing the tracing initialization code use the initTracer() method and instrumented library. See the following example HTTP client main function:

func main() {

    initTracer()

    client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}

    ctx := baggage.ContextWithoutValues(context.Background())

    req, _ := http.NewRequestWithContext(ctx, "GET", "http://sumologic.com", nil)

    fmt.Printf("Sending request...\n")
    res, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Response status code: %v\n", res.Status)
    fmt.Printf("Waiting for few seconds to export spans ...\n\n")
    time.Sleep(10 * time.Second)
}

The last step is to set the service.name attribute. It can be done by setting the environment variable OTEL_RESOURCE_ATTRIBUTES=service.name=YOUR_SERVICE_NAME. Ensure the string value represents its business logic, such as "SumoWebCall", according to the example above. This will appear as a tracing service name in Sumo Logic.