October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Implementing Distributed Tracing in Go with OpenTelemetry

A practical guide to Go distributed tracing with OpenTelemetry, from SDK setup and useful spans to cross-service context propagation, OTLP export, and sampling.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To add distributed tracing to a Go application, initialize the OpenTelemetry SDK, configure a trace exporter and service resource, instrument HTTP and other supported dependencies, and add manual spans around important application work. Then propagate trace context across requests, choose a sampling policy, and shut down the tracer provider cleanly so buffered spans can be exported.

Prerequisites and Go packages

OpenTelemetry separates its API from its SDK. Instrumentation libraries use the API to create telemetry; an application needs the SDK to process and export that telemetry. As the OpenTelemetry Go instrumentation documentation puts it: “If you’re instrumenting an app, you need to use the OpenTelemetry SDK for your language.”

As an Amazon Associate I earn from qualifying purchases.

The official Go getting-started guide lists Go 1.23 or newer as a prerequisite. Check that guide before starting, since prerequisites and package APIs can change. For manual tracing, the core imports are typically go.opentelemetry.io/otel, go.opentelemetry.io/otel/trace, and go.opentelemetry.io/otel/sdk; exporter and instrumentation packages depend on your chosen transport and dependencies. Use the current documentation and release information to select compatible module versions rather than pinning an unverified version from an example.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I add OpenTelemetry tracing to a Go application?

Set up the pipeline before creating application spans: create an exporter, identify the service with resource attributes, configure a tracer provider and span processor, register the provider when appropriate, and acquire a tracer. The official manual instrumentation guide demonstrates this structure with a batch span processor. In a real service, connect the exporter to a receiving endpoint and handle setup errors rather than treating a placeholder endpoint as production configuration.

Initialize the provider and flush it at shutdown

A representative setup has this shape; fill in the exporter construction with the OTLP transport and endpoint your deployment uses, and adapt lifecycle handling to your application:

ctx := context.Background()

// Create an exporter configured for your OTLP receiver.
// Handle the returned error before starting the application.
traceExporter, err := newTraceExporter(ctx)
if err != nil {
    return err
}

res, err := resource.New(ctx,
    resource.WithAttributes(attribute.String("service.name", "orders-api")),
)
if err != nil {
    return err
}

provider := sdktrace.NewTracerProvider(
    sdktrace.WithResource(res),
    sdktrace.WithBatcher(traceExporter),
)
otel.SetTracerProvider(provider)

// During graceful shutdown, before the process exits:
if err := provider.Shutdown(shutdownCtx); err != nil {
    return err
}

The snippet shows the pipeline shape, not a complete exporter implementation: exporter constructors and configuration differ between OTLP/HTTP and OTLP/gRPC. In a service, use a bounded shutdown context and call Shutdown from the application’s graceful-termination path so pending batches can be flushed. If provider creation fails, report the error and avoid starting an application that silently appears instrumented but cannot export.

Once the provider is configured, obtain a tracer using an instrumentation-scope name that identifies the component creating spans:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
tracer := otel.Tracer("example.com/orders")
ctx, span := tracer.Start(ctx, "orders.process")
defer span.End()

// Perform application work using ctx where supported.

Pass the returned context to downstream calls and end spans when their work is complete. Use stable operation names; avoid putting request IDs, user IDs, or other high-cardinality values in span names. Put relevant, non-sensitive details in attributes where they help explain the operation.

Global provider and zero-code instrumentation

Registering the provider globally is a common choice when instrumentation libraries retrieve it through the OpenTelemetry API. Do not apply that setup blindly when combining manual spans with eBPF-based Go zero-code instrumentation such as OBI. The Go manual instrumentation guidance cautions against setting a global tracer provider in that deployment model; follow the Auto SDK guidance for the setup you use.

Where to add instrumentation

Use dependency instrumentation for supported boundaries, then add manual spans for application-specific work. These approaches complement one another: automatic instrumentation can capture supported HTTP or framework activity, but it does not know the meaning of your business operations.

Instrument HTTP and other supported dependencies

The OpenTelemetry Go libraries documentation describes net/http instrumentation that can automatically create spans and metrics for HTTP requests. Check the instrumentation library for your server, client, framework, or database to confirm its current support and configuration. Avoid adding a second span around the same boundary if middleware or a library already creates one; duplicates make traces harder to interpret.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Add manual spans around meaningful work

Manual spans are useful for operations a dependency cannot describe, such as validating an order, applying a pricing rule, or coordinating multiple downstream calls. Give each span a clear operation name and make its lifetime match the work it represents. Keep attributes useful and appropriately scoped: telemetry can expose sensitive data if request bodies, credentials, or personal information are attached indiscriminately.

How do I propagate trace context between Go services?

A trace becomes a connected cross-service view only when the active trace context travels with the request. OpenTelemetry Context is an execution-scoped propagation mechanism and is specified as immutable. In Go, pass the context returned when starting a span through the call chain. At HTTP boundaries, configure a propagator and use instrumentation that extracts context from inbound requests and injects it into outbound requests.

The exact Go APIs and configuration depend on the current instrumentation package and version. Follow the official OpenTelemetry Go documentation for the propagation setup supported by your chosen packages rather than copying propagation code from another language. Verify both sides of a service boundary: the receiver must extract the incoming context, and the caller must inject it into the outgoing request. Without that handoff, each service may produce spans, but they will not necessarily belong to the same trace.

How do I export Go OpenTelemetry traces using OTLP?

OTLP is the flexible standard export path in the OpenTelemetry Go exporters guide. Go trace exporters support OTLP over HTTP and gRPC. In production, the guide recommends sending telemetry to an OpenTelemetry Collector, which can then export it to a visualization system or vendor backend. Jaeger, Zipkin, Prometheus, and vendor-specific backends are among the destination options described in the documentation; confirm that a particular destination supports the protocol and signal path you plan to use.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

OTLP/HTTP and OTLP/gRPC use different endpoint forms. Match exporter configuration to the receiver:

Choice Endpoint form What to check
OTLP/HTTP An HTTP base endpoint; trace data is sent to the signal path, commonly /v1/traces. Confirm whether the exporter expects a base URL or a signal-specific URL, and whether TLS and headers match the receiver configuration.
OTLP/gRPC A gRPC target address. Do not append HTTP signal paths such as /v1/traces; confirm the target, TLS, and any required headers.

Do not combine a gRPC exporter with an HTTP signal-path URL, or assume that an HTTP exporter accepts a bare gRPC target. Check the exporter guide and the receiver’s instructions for the precise settings.

Direct export or Collector

Direct export can be useful for a small or controlled setup, but a Collector provides a separate point to receive and route telemetry before it reaches a backend. The OpenTelemetry Go exporters documentation says, “Using the Collector in production environments is a best practice.” That guidance is a deployment recommendation, not a requirement that every development environment run a Collector.

The Go exporter guide also describes environment-based exporter configuration through contrib’s autoexport. Its supported exporter values and environment-variable support vary; the Go SDK documentation specifically notes that OTEL_SDK_DISABLED is not currently supported. Check the current exporter documentation before relying on a particular environment variable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose a sampling policy

Sampling controls how many spans are recorded and exported. A sampling decision should be made at the beginning of a trace and propagated, so services do not keep inconsistent fragments of the same request. Sampling is an operating trade-off: recording more traces improves the chance of retaining useful diagnostic cases but increases telemetry volume; recording fewer reduces volume but may omit the trace you need.

Policy Best suited to Important consideration
AlwaysSample Development or controlled debugging, as described by the Go sampling guide. Records every eligible trace, so evaluate volume before applying it to production traffic.
NeverSample Controlled cases where traces should not be recorded. It provides no trace samples for diagnosing requests covered by that policy.
Parent-based sampler with a trace-ID ratio sampler A production option suggested for consideration in the Go sampling guide. Respects the parent’s decision and samples according to a configured ratio when no parent decision governs the trace; choose the ratio based on operational needs rather than treating one percentage as universal.

If you implement a custom sampler, preserve the parent tracestate and keep synchronous ShouldSample work inexpensive. See the official Go sampling documentation for sampler behavior and configuration.

What is stable in OpenTelemetry Go?

The OpenTelemetry Go documentation’s status table lists traces and metrics as stable and logs as release candidate. Stability status can change, so check the current table when choosing APIs for a new implementation. This guide focuses on traces; logs do not need to be part of the tracing pipeline for trace context and spans to work.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.