Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →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.
Recommended Free Tools
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.
#1 Best Overall
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:
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.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallAdd 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.
Rank #4
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.
OTLP/HTTP and OTLP/gRPC use different endpoint forms. Match exporter configuration to the receiver:
Best Value
| 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.
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.
Quick Recap
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.




