OpenTelemetry Go: Complete Guide with Code Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

OpenTelemetry Go: Complete Guide to Distributed Tracing

1. What Is It and Why Do You Need It?

OpenTelemetry is a collection of APIs, SDKs, and tools designed to create and manage telemetry data such as traces, metrics, and logs. The opentelemetry-go library is the official implementation of the OpenTelemetry standard for the Go language. It provides developers with a unified, vendor-neutral way to instrument their applications for telemetry collection, which can then be sent to various backends like Jaeger, Zipkin, Prometheus, Grafana Tempo, Datadog, and many others.

Why do you need it? In modern microservices architectures, a user request often passes through dozens of different services. When a problem occurs — for example, a request takes too long or ends with an error — without distributed tracing it's extremely difficult to pinpoint which service is the bottleneck or the source of the failure. OpenTelemetry lets you trace the request's path across your entire system, see the execution time of each step, and link them into a single trace composed of spans. This gives developers and Site Reliability Engineers (SREs) a powerful tool for debugging, monitoring, and performance optimization.

The key advantage of OpenTelemetry over other solutions (such as the older OpenTracing or OpenCensus libraries) is its universality and standardization. You write your code once using a single API, and you can switch the backend for storing and visualizing data without changing your application code. This makes opentelemetry-go not just a library, but a foundation for building observable systems in Go.

2. Installation

To install the opentelemetry-go library and its core components, use the standard Go package manager. You'll need to install the main API package, the tracing SDK, and an exporter (for example, for the console or Jaeger).

# Install the core API
go get go.opentelemetry.io/otel

# Install the tracing SDK
go get go.opentelemetry.io/otel/sdk

# Install the console exporter (for debugging)
go get go.opentelemetry.io/otel/exporters/stdout/stdouttrace

# Install the HTTP context propagator (for HTTP integration)
go get go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp

# Install the Jaeger exporter (for production)
go get go.opentelemetry.io/otel/exporters/jaeger

After running these commands, all necessary dependencies will be added to your go.mod file.

3. Quick Start — Minimal Working Example

This example shows how to create a simple trace with a single span and output it to the console. It's a great starting point for understanding the basic concepts.

package main

import (
	"context"
	"fmt"
	"log"

	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
	"go.opentelemetry.io/otel/sdk/resource"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
	"go.opentelemetry.io/otel/trace"
)

func main() {
	// 1. Create a console exporter
	exporter, err := stdouttrace.New(
		stdouttrace.WithPrettyPrint(),
	)
	if err != nil {
		log.Fatal(err)
	}

	// 2. Create a TracerProvider with the exporter and resource
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithResource(resource.NewWithAttributes(
			semconv.SchemaURL,
			semconv.ServiceNameKey.String("my-service"),
		)),
	)
	defer func() {
		if err := tp.Shutdown(context.Background()); err != nil {
			log.Fatal(err)
		}
	}()

	// 3. Set the global TracerProvider
	otel.SetTracerProvider(tp)

	// 4. Get a Tracer
	tracer := otel.Tracer("my-tracer")

	// 5. Create a span
	ctx, span :=                    

Recommendations