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

Mandatory packages installation

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

go get -u go.opentelemetry.io/otel

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

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}

For example net/http package:

go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

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.

For example, your HTTP server main function should do this in the following way:

func main() {
    initTracer()

    uk := label.Key("username")

    helloHandler := func(w http.ResponseWriter, req *http.Request) {
        ctx := req.Context()
        span := trace.SpanFromContext(ctx)
        username := otel.BaggageValue(ctx, uk)
        span.AddEvent(ctx, "handling this...", uk.String(username.AsString()))

        _, _ = io.WriteString(w, "Hello, world!\n")
    }

    otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello")

    http.Handle("/hello", otelHandler)
    err := http.ListenAndServe(":7777", nil)
    if err != nil {
        panic(err)
    }
}

Exporters configuration

The last configuration step is setting up a span exporter. There are currently 3 supported tools OTLP, Zipkin, and Jaeger, Sumo Logic recommends the OTLP exporter:

OTLP exporter

To configure OTLP as a span consumer you need to implement an exporter function. It should use the NewExporter function from the OTLP package:

exporter, err := otlp.NewExporter()

For example:

exp, err := otlp.NewExporter(
otlp.WithInsecure(),
otlp.WithAddress("collection-sumologic-otelcol.sumologic:55680"),
)

In this example, the value of the variable points to the default Sumologic Kubernetes Collector. For Kubernetes environments see the available endpoints for a direct connection. For other environments see endpoints and protocols.

All configuration options for the exporter are described here.

The next step is the initialization of the tracing provider using the function sdktrace.NewTracerProvider().

The exemplary configuration including exporter and tracer is described here.