Auto-Instrumenting Go Applications Without Modifying Source Code
Issues with Auto-Instrumentation For Go Applications

Auto-Instrumenting Go Applications Without Modifying Source Code
Issues with Auto-Instrumentation For Go Applications
Go is statically compiled, which means all the code and libraries are “baked into” the binary at compile time. Because of this, traditional auto-instrumentation — which relies on dynamically hooking into functions at runtime — doesn’t work well in Go. Unlike languages such as Python or JavaScript, Go lacks runtime hooks to intercept library calls, so developers typically have to manually add tracing and propagate context making instrumentation more complex and error-prone.
Proposed Solution: Go Auto-Instrumentation with eBPF
The auto-instrumentation project for Go has been proposed and made to resolve this issue utilizing eBPF.
eBPF instrumentation solves this by tracing at the kernel level, outside the program itself. It can capture all network calls, syscalls, and I/O events, giving full observability without changing your Go code. Essentially, it sees everything Go’s “sewn-in” binary might hide.
Introduction:
This guide demonstrates how users can leverage eBPF to address the issue of having to modify your go source code for observability. Throughout the guide, I have created and deployed a ‘Hello World’ application on Kubernetes, written in Go, to serve as a reference.
Configuring OBI Permissions for Kubernetes Metadata Collection
Before we can start collecting telemetry with eBPF, we need to give our instrumentation tool, OBI, permission to see what’s running in the cluster.
Step 1: Create a ServiceAccount for OBI This gives OBI its own identity in the cluster, allowing it to access only the resources it needs. See here for Reference
Step 2: Grant OBI the necessary permissions We need to allow OBI to list and watch Pods and ReplicaSets so it can gather the information required. See here for reference.
Step 3: Bind the permissions to the ServiceAccount This connects the permissions to the OBI ServiceAccount. See here for reference.
Once these steps are complete, apply the configuration with: kubectl apply -f permissions.yaml
With these permissions, OBI can now decorate your traces with Kubernetes metadata, including:
- k8s.namespace.name
- k8s.deployment.name
- k8s.statefulset.name
- k8s.replicaset.name
- k8s.daemonset.name
- k8s.node.name
- k8s.pod.name
- k8s.container.name
- k8s.pod.uid
- k8s.pod.start_time
- k8s.cluster.name
Deploy OBI as a sidecar container
There are a couple of ways to deploy OBI. For this guide, I chose to deploy it as a sidecar container, though a DaemonSet deployment is also available. See reference here.
The first step will be to Configure the Pod Spec for OBI Sidecar. When adding OBI as a sidecar container to your deployment, you need to adjust the Pod spec with the following fields: See Reference here
Explanation:
shareProcessNamespace: true
This allows all containers in the Pod (your main app and the OBI sidecar) to see each other’s processes.
OBI needs this to observe and instrument the main application process without modifying your code.
serviceAccountName: obi
Associate the Pod with the OBI ServiceAccount you created earlier.
This grants OBI the permissions necessary to access Kubernetes resources (Pods, ReplicaSets, Deployments, etc.) so it can decorate traces with metadata like k8s.pod.name, k8s.namespace.name, and more.
In short: these two settings allow OBI to observe your application processes and enrich telemetry with Kubernetes metadata.
Add the OBI Sidecar Container
Next, add OBI as a sidecar container alongside your main application in the Pod specification: See reference here. This allows OBI to run next to your Go application, automatically instrumenting it using eBPF without requiring any code changes.
Configuring OBI Environment Variables
Finally, define the environment variables for the OBI container See Reference Here
These environment variables tell OBI how to instrument and export telemetry data:
OTEL_GO_AUTO_TARGET_EXE — Points to the main Go executable for instrumentation.
OTEL_EXPORTER_OTLP_ENDPOINT — Specifies your Dash0 OTLP endpoint.
OTEL_EBPF_KUBE_METADATA_ENABLE — Enables Kubernetes metadata decoration.
OTEL_EXPORTER_OTLP_HEADERS — Adds your authentication key for secure export.
OTEL_SERVICE_NAME — Identifies your Go application in Dash0.
Once configured, OBI will automatically collect and send traces, metrics, and logs from your Go application to Dash0 — no code changes required.
Using Dash0 As Your Observability Platform
For this guide, I chose Dash0 because it’s one of the first observability platforms built natively around OpenTelemetry. Dash0 provides a full suite of observability tools — including metrics, traces, and logs — while offering a pay-as-you-go pricing model with no minimum contracts. Compared to traditional platforms, it can deliver the same major functionality with up to 65% cost reduction.
If you’re exploring OpenTelemetry-based observability, Dash0 is worth checking out for its simplicity, full-featured approach, and efficiency.
메타데이터
- post_id
- 9bd61d229ea4
- slug
- auto-instrumenting-go-applications-without-modifying-source-code-9bd61d229ea4
- url
- https://medium.com/@vitor.mouzinho_24546/auto-instrumenting-go-applications-without-modifying-source-code-9bd61d229ea4
- canonical_url
- https://medium.com/@vitor.mouzinho_24546/auto-instrumenting-go-applications-without-modifying-source-code-9bd61d229ea4
- author_url
- https://medium.com/@vitor.mouzinho_24546
- status
- ok
- fetched_at
- 2026-08-30 06:48:14