Choosing zero-code auto instrumentation for Go

A guide to choosing between OpenTelemetry eBPF Instrumentation (OBI) and Go compile-time instrumentation (otelc) for Go applications.

আপনি এই পৃষ্ঠার ইংরেজি সংস্করণ দেখছেন কারণ এটি এখনও সম্পূর্ণভাবে অনুবাদ করা হয়নি। সাহায্য করতে আগ্রহী? দেখুন Contributing।

For Go applications, OpenTelemetry provides two distinct “zero-code” approaches to instrument applications without modifying source code: runtime attachment and build-time weaving.

This guide compares OpenTelemetry eBPF Instrumentation (OBI) and OpenTelemetry Go Compile-Time Instrumentation (otelc) to help you choose the right tool for your environment.

Note: For information on the Go auto-instrumentation SDK, see Auto Instrumentation. This guide specifically focuses on comparing the eBPF and compile-time zero-code approaches.

This is a decision guide, not a ranking. Both projects are official OpenTelemetry components. In many setups, they solve different problems or even work well together.

The two mental models

When evaluating zero-code instrumentation, it helps to understand the fundamental architectural difference between the two approaches:

  • Runtime (eBPF): The instrumentation runs alongside your application as a separate process (often on the host node). It observes the application from the outside—specifically at the application, kernel, and networking layers. While it may inject outgoing headers into the application’s memory space for trace context propagation, it does not require changes to the application’s build process.

  • Compile Time (otelc): The instrumentation is injected into the application’s source during the compilation process. The resulting binary contains the telemetry logic natively, meaning no external runtime agent is required.

OBI

OpenTelemetry eBPF Instrumentation (OBI) uses eBPF (What is eBPF?) to automatically inspect application executables and the OS networking layer.

  • How it hooks in: Deploys eBPF probes in the Linux kernel and the application to capture trace spans and metrics as system calls and network packets occur.
  • Language coverage: Broad and essentially polyglot. Supports Java, .NET, Go, Python, Ruby, Node.js, C, C++, and Rust, among others.
  • Operational requirements: Requires a Linux environment (kernel 5.8+ or specific backports), BTF support, and elevated privileges (root or specific Linux capabilities).
  • Telemetry produced: Excels at capturing traces (incoming and outgoing spans for HTTP/S, gRPC, database queries), RED (Rate, Errors, Duration) metrics, network flows, and log enrichment. It captures what enters and leaves the process, but internal spans specific to the application’s frameworks or libraries still need to be manually specified by the user, either by modifying the application code or by manually defining code sections in a configuration file.

otelc

OpenTelemetry Go Compile-Time Instrumentation (otelc) uses the Go toolchain’s -toolexec mechanism to automatically inject OpenTelemetry instrumentation directly into your application binary during the compilation process.

  • How it hooks in: Intercepts the compilation of packages, matches functions against instrumentation rules, and injects OpenTelemetry hooks directly into the compiled binary.
  • Language coverage: Go only.
  • Operational requirements: Requires access to the Go build pipeline. Because the instrumentation is baked into the binary, it runs anywhere the Go binary runs and requires no special OS privileges or kernel features at runtime.
  • Telemetry produced: Provides deep in-process spans with high fidelity. It can trace internal function calls, capture application-specific context, and instrument third-party Go dependencies.

Trade-offs

FeatureOBI (eBPF)otelc (Compile-Time)
Deployment ModelDeployed separately (e.g., Kubernetes DaemonSet, sidecar, or host agent). Zero changes to application build pipeline.Baked into the application binary during go build. Requires wrapping your build command.
Runtime RequirementsRequires specific Linux kernel versions, BTF, and elevated privileges (root/capabilities).No special runtime privileges, kernel features or OS requirements needed.
Signal Fidelity & DepthExcellent for network boundaries and protocol interactions. Cannot easily see internal function calls or custom business logic.Deep in-process visibility. Can instrument internal functions, custom logic, and code paths.
Third-party LibrariesSees the network calls and database queries made by dependencies.Can instrument the internal code execution of Go module dependencies.
Lifecycle ManagementCan be attached, detached, upgraded, or downgraded dynamically without application restarts.Requires an application rebuild, redeploy, and restart to change versions or remove instrumentation.

When to use which

Choose OBI if:

  • You prioritize ease of deployment and immediate feedback: Deploying the OBI agent allows you to collect telemetry without modifying your software development lifecycle (SDLC) or build processes.
  • You have a mixed-language fleet: You want a single, unified auto-instrumentation tool that works across Go, Java, Python, .NET, and more.
  • You lack build pipeline access: You do not own the build process, use pre-compiled vendor binaries, or cannot access the source code.
  • You care about boundary observability: Your primary goal is tracking service-to-service communications, RED metrics, and database calls across your infrastructure.
  • You are running on Linux: You operate in a Linux environment (inside or outside of Kubernetes) and can deploy an agent with the necessary privileges to observe your processes. OBI provides selectors for instrumenting by executable name, open port(s), and process PID, as well as Container, Pod, Deployment, Namespace, and metadata labels in containerized scenarios (Docker/Kubernetes), making it flexible for various deployment scenarios.

Choose otelc if:

  • You own the Go build pipeline: You have full control over how your Go services are compiled and deployed.
  • You require instrumentation guarantees: You can write tests during the build phase to ensure the telemetry being collected is accurate before deployment.
  • You need maximum span fidelity: You require deep, in-process tracing of business logic and internal application states.
  • You want to trace third-party internals: You need visibility into the execution of the third-party Go modules that you import but don’t own.
  • Your runtime is restricted: You operate in environments that restrict root privileges, eBPF capabilities, or specific kernel versions (e.g., certain serverless or highly locked-down container environments).
  • You need a platform-agnostic solution: Your application must run on Windows, Linux, or macOS, or on specialized architectures that the Go runtime already supports.

Using them together

Because these tools operate at different layers of the stack, they are complementary and can be used together in the same environment:

  • Use otelc to generate deep, high-fidelity traces for your Go business logic, internal library calls, and custom spans.
  • Use OBI to provide infrastructure-level network observability, kernel-level TCP metrics, and coverage for any non-Go components or sidecars running in your environment.

Both Special Interest Groups (SIGs) plan to improve interoperability between these two tools in the future.


সর্বশেষ পরিবর্তিত September 28, 2026: docs(zero-code): add auto-instrumentation decision guide (#11035) (114187fa)