For the complete documentation index, see llms.txt. Markdown versions are available by appending .md to documentation URLs.

Go Compile-Time OpenTelemetry Instrumentation Guide

SigNoz Cloud - This page applies to SigNoz Cloud editions.
Self-Host - This page applies to self-hosted SigNoz editions.

Overview

OpenTelemetry Go compile-time instrumentation adds tracing to your application during go build. The tool is called otelc. It rewrites the build, not your source code, so you keep your code free of OpenTelemetry calls. The instrumented binary exports traces and Go runtime metrics to SigNoz over OTLP.

Prerequisites

How it works

otelc wraps the Go toolchain. It reads your dependency graph, finds the libraries it has rules for, and injects hook code into those packages as the compiler runs. Your files on disk never change, so the repository shows no diff.

otelc wraps go build, injects hooks into matched libraries, and produces an instrumented binary that exports OTLP to SigNoz
otelc changes the build, so the binary carries the instrumentation and your repository stays clean

The build also injects the OpenTelemetry SDK setup. The binary reads the standard OTEL_* environment variables at startup and exports OTLP to SigNoz on its own. It needs no agent and no extra privileges.

Send traces to SigNoz

Step 1. Install otelc

Install the tool with go install:

go install go.opentelemetry.io/otelc/tool/cmd/otelc@v1.1.0

Confirm that the tool is on your path:

otelc version

Step 2. Build your application with otelc

Put otelc in front of your normal build command.

otelc go build -o myapp .

If a Makefile or a CI pipeline owns the build command, keep go build and plug otelc in through GOFLAGS:

otelc setup
export GOFLAGS="${GOFLAGS} '-toolexec=otelc toolexec'"
go build -o myapp .

Run otelc setup once in the module directory, and again after the dependencies change. It writes the matched rules to .otelc-build/, which the build reads.

The build prints one line for each instrumentation that it applies. The binary behaves like the one you built before.

Step 3. Set the environment variables and run

The instrumented binary reads the standard OpenTelemetry environment variables at startup. It needs no other configuration.

export OTEL_SERVICE_NAME="<service-name>"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
export OTEL_RESOURCE_ATTRIBUTES="service.version=<service-version>"
 
./myapp

Verify these values:

  • <region>: Your SigNoz Cloud region.
  • <your-ingestion-key>: Your SigNoz ingestion key.
  • <service-name>: The name your service gets in SigNoz, for example payment-service.
  • <service-version> (optional): Your release version, image tag, or git commit, for example 1.4.2.

At startup the application logs these lines:

trace provider initialized with auto-export
OpenTelemetry initialized
runtime metrics enabled

Validate

Send a few requests to your application, then open SigNoz.

Open Services. Your service appears with request rate, error rate, and latency within a minute or two.

Open Traces and filter by your service name. Each request produces one server span, one client span for an outbound HTTP call, and one span for each database call.

Spans from a Go service instrumented with otelc, listed in the SigNoz Traces Explorer
HTTP and database spans from a Go binary built with otelc

Open one trace and select a database span. The span carries the query text, the database system, and the address of the database server.

Trace detail for a Go service instrumented with otelc, with the database span selected
A SELECT span with db.query.text and server.address, captured without a code change

Open Metrics and search for go.. The Go runtime metrics, such as go.goroutine.count and go.memory.used, arrive with the same service name.

Supported libraries

otelc instruments these libraries. Your application gets spans for the libraries it uses.

LibrarySpans
net/http (client and server)HTTP
google.golang.org/grpc (client and server)RPC
database/sqlDatabase client
github.com/gin-gonic/ginHTTP server
github.com/redis/go-redis/v9Database client
go.mongodb.org/mongo-driverDatabase client
github.com/segmentio/kafka-goMessaging
github.com/aws/aws-sdk-go-v2AWS client
github.com/linode/linodego/v2HTTP client
k8s.io/client-goKubernetes resource
github.com/openai/openai-go, github.com/anthropics/anthropic-sdk-goGenAI
log, log/slog, github.com/sirupsen/logrusTrace and span ID in log records

This table matches v1.1.0, the version this guide installs. Later releases add more libraries, so check the supported libraries for v1.1.0 against the version you install.

Turn instrumentations on or off

The binary contains every instrumentation that matched your dependencies. You can select a subset at runtime without a rebuild:

# Run only net/http and gRPC instrumentation.
OTEL_GO_ENABLED_INSTRUMENTATIONS=nethttp,grpc ./myapp
 
# Run everything except net/http.
OTEL_GO_DISABLED_INSTRUMENTATIONS=nethttp ./myapp

Names are lowercase. The allowlist applies first, then the denylist removes entries from it.

To control what the build puts into the binary, declare the instrumentations in an otel.instrumentation.go file. See the external configuration guide.

Troubleshooting

Still not seeing data in SigNoz? Work through Debug missing traces, logs, and metrics, which covers SDK diagnostics, Collector connectivity, and the common ingestion errors for all three signals.

The application logs x509: certificate signed by unknown authority

  • Cause: The container image has no root certificates, so it cannot open a TLS connection to SigNoz Cloud.
  • Fix: Install ca-certificates in the runtime image, or copy the certificates from the build stage.
  • Verify: The export errors stop and traces arrive in SigNoz.

The build succeeds but no spans arrive

  • Cause: The application uses no supported library, or the build did not run through otelc.
  • Fix: Check the build output for the injected instrumentations. Make sure that the command starts with otelc go build, or that GOFLAGS carries -toolexec=otelc toolexec.
  • Verify: The application logs OpenTelemetry initialized at startup.

Spans exist but a library is missing

  • Cause: The instrumentation is turned off, or the library is not supported.
  • Fix: Unset OTEL_GO_ENABLED_INSTRUMENTATIONS and OTEL_GO_DISABLED_INSTRUMENTATIONS, then compare your library against the supported list.
  • Verify: The missing spans appear in the trace detail view.

Spans have no Kubernetes attributes

  • Cause: The application does not know its pod, namespace, or node.
  • Fix: Send the data through the SigNoz Kubernetes Collector, which adds the k8s.* attributes. You can also set them yourself with the downward API in OTEL_RESOURCE_ATTRIBUTES.
  • Verify: Spans carry k8s.pod.name and k8s.namespace.name.

Setup OpenTelemetry Collector (Optional)

Use the OpenTelemetry Collector when you need to process, filter, or route telemetry before it reaches SigNoz. Follow the Switch to Collector guide for setup instructions.

Then point the application at the Collector:

OTEL_EXPORTER_OTLP_ENDPOINT="http://<collector-host>:4318"

Limitations

  • The tool instruments a fixed list of libraries. Custom frameworks and your own code get no spans.
  • You must rebuild and redeploy the application to add or remove instrumentation at build time.
  • v1.1.0 exports traces and Go runtime metrics. It records no HTTP or database metrics, so SigNoz derives rate, error, and latency from the spans.

Next steps

Get Help

If you need help with the steps in this topic, please reach out to us on SigNoz Community Slack. If you are a SigNoz Cloud user, please use in product chat support located at the bottom right corner of your SigNoz instance or contact us at cloud-support@signoz.io.

Is this page helpful

Last updated—September 12, 2026

Edit on GitHub