Self-hosted service
open-telemetry/opentelemetry-ebpf-instrumentation avatar
open-telemetry/opentelemetry-ebpf-instrumentation

OpenTelemetry eBPF Instrumentation: zero-code telemetry for unmodified Linux binaries

Zero-code OpenTelemetry instrumentation powered by eBPF

596 stars209 forksCApache-2.0

At a glance

What is it?
OBI, the OpenTelemetry eBPF Instrumentation project, attaches OpenTelemetry spans and metrics to running user-space processes on Linux without touching application code. The catch is the stability contract: the project is in v0, it tells you to pin release tags, and its configuration format has already had a v1 to v2 migration.
Who is it for?
Adopt OBI when you need OpenTelemetry traces and metrics from services you cannot rebuild or redeploy, on Linux hosts where loading an eBPF program is acceptable, and you can pin a release tag and live with v0 semantics. Do not adopt it for a fleet you can instrument in code, since application SDKs give better span semantics without kernel-level dependencies, and do not assume continuity of emitted telemetry between minor versions.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

eBPF gives you telemetry without changing the application

OBI is the OpenTelemetry eBPF Instrumentation project, and the name comes from the OpenTelemetry e-BPF Instrumentation initials. The idea it implements is zero-code instrumentation for user-space applications on Linux: a process that was built without any OpenTelemetry library can still produce spans and metrics, because the collection happens in the kernel rather than inside the program.

That is a genuinely different operating position from the usual one. When you instrument at the application level you get rich, semantically meaningful spans, but you need the language SDK, you need a redeploy, and you need cooperation from the code owner. The eBPF approach trades span detail for coverage. You get HTTP server and client traffic, connection behaviour and process level metrics for anything running on the host, without touching a single binary.

The implementation is C for the eBPF side and Go for the rest, with the module named go.opentelemetry.io/obi. The eBPF programs live under a bpf/ folder, and the Go bindings for them are generated rather than hand written, which is why the development instructions start with a code generation step rather than a plain build.

The README tells you not to trust a moving tag

The project status section is unusually blunt for a project hosted under the OpenTelemetry organisation. OBI is in Development, and users are told to expect breaking changes between minor releases while the project remains in v0. There is a specific list of advice for anyone evaluating it for production use: pin to a specific semver release tag rather than relying on latest, review release notes before upgrading between minor versions, expect configuration, behaviour, supported environments and emitted telemetry to change between v0 minor releases, and avoid assuming telemetry continuity for dashboards, alerts or downstream processors before OBI declares those surfaces stable.

The releases show the shape of that. v0.15.2 shipped on 2026-10-16, v1.0.0-rc.2 on the same day, and v1.0.0-rc.1 a week earlier, while the last push to the main branch was on 2026-10-20. A v1 release candidate exists alongside a v0 line, so the version you pick determines which stability promises you get.

The repository root carries the policy documents that make those statements checkable: VERSIONING.md for the versioning and stability policy, SUPPORT_MATRIX.md for the environments and artifact platforms currently documented as supported, and TELEMETRY.md for the stable v1 telemetry surface and its guarantees.

A v1 to v2 configuration migration is already on the table

The configuration story has a wrinkle that is easy to trip over. The README points to a Config v1 to v2 migration guide under devdocs/config/version-2.0/migration.md, and states three things clearly: Config v1 is frozen for backward compatibility and does not receive bug fixes or new features, Config v2 is where configuration improvements land, and Config v2 should only be used with a release whose notes explicitly enable it for your standalone or Collector deployment mode.

That last sentence is the one to notice. Adopting the newer configuration format is not a matter of your own preference. Whether Config v2 is available to you depends on the release you run and on the deployment mode you chose, and the release notes are the place to check.

The two deployment modes named here are standalone and Collector. Running OBI as a standalone process and running it as a Docker container are the two setup paths the README links to in the OpenTelemetry zero-code documentation, which it calls the authoritative source of truth for setup, configuration and troubleshooting. The point of naming a separate authority is that this README is a summary rather than the full configuration reference, and the config files themselves live in a configs/ directory in the repository.

Release artifacts are signed and can be verified offline

The release engineering is where OBI is most conventional. Pre-built binaries are provided for Linux on amd64 and arm64, and each release includes a tar.gz archive per architecture, a source-generated archive, CycloneDX SBOM files for each of those artifacts, a separate SBOM for the embedded Java agent, a SHA256SUMS file, and a Sigstore bundle for every signed asset.

The verification procedure is spelled out in the README and it is worth following rather than skipping, because the point of the exercise is to check the artifacts before you run them with kernel-level privileges. The setup exports the version, the architecture, the release tag, the base URL and the certificate identity:

bash
# Set your desired version (find latest at https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/releases)
export VERSION=0.11.0

# Determine your architecture
# For Intel/AMD 64-bit: amd64
# For ARM 64-bit: arm64
export ARCH=amd64  # Change to arm64 for ARM systems

export RELEASE_TAG=v${VERSION}
export BASE_URL="https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/releases/download/${RELEASE_TAG}"
export ARTIFACT="obi-${RELEASE_TAG}-linux-${ARCH}.tar.gz"

Then it fetches the archive, its bundle, the checksum manifest and that manifest's bundle, and checks the signatures with Cosign against the certificate identity and the GitHub Actions OIDC issuer, before finally running sha256sum against the manifest. A successful Cosign verification confirms the local file matches the signed payload, that the signing identity matches this repository's release workflow and tag, that the certificate was issued by GitHub Actions OIDC, and that the bundle carries the transparency log material for offline verification. The checksum step then confirms the downloaded files against the signed manifest with sha256sum -c.

The version in the example is 0.11.0 while the current release line is higher, so treat it as a template rather than a value to copy.

Development starts with generated eBPF bindings, not a build

The development instructions are short and the order matters. The requirements are Docker and GNU Make. The first step is to generate all the eBPF Go bindings with `make docker-generate`, and the README notes that this task has to be re-run every time you add or modify a C file under the bpf/ folder.

That is the workflow cost of an eBPF project. The C programs in bpf/ are the actual instrumentation, and the Go side needs generated bindings to talk to them, so the generator runs in a container to keep the output reproducible. The Makefile confirms the arrangement: the generator image is pinned to a specific version, and the build flags for the C code are strict, with warnings treated as errors.

After generation, `make fmt verify` runs the linter and the unit tests. Integration tests come in three flavours, `make integration-test`, `make integration-test-k8s` and `make oats-test`, and the README warns that each target can take up to 50 minutes. The escape hatch for a faster loop is to use standard go tooling to run individual suites under the internal/test/integration and internal/test/integration/k8s folders.

The repository also carries a Go module manifest with a large dependency list, an eBPF library from cilium, cloud SDK clients for AWS, container client libraries, and the OpenTelemetry and Prometheus export stacks. That dependency surface is worth looking at before you decide what this process is allowed to reach.

The telemetry contract is a Weaver schema, not a promise

OBI defines its emission contract as a Weaver compatible schema registry under schemas/obi/. Weaver is the OpenTelemetry schema tooling, and the registry extends the upstream OpenTelemetry semantic conventions registry with the metrics, spans and attributes that OBI emits and that the upstream registry does not cover.

This is the mechanism that makes the "zero-code" claim auditable. Instead of asking you to trust that a future release emits the same signals, the project publishes a machine readable registry with stability classifications, and the generated telemetry reference under site/docs lists the attributes, metrics and spans it contains.

The distinction between the two documents matters when you plan an upgrade. TELEMETRY.md describes the stable v1 surface and its guarantees, which is the subset you can build dashboards on. The schema registry is wider than that, and the rest of it can move between v0 minor releases, which is exactly what the status section warns about.

So the honest way to read this project is that it has a stable contract for a defined surface and an unstable surface around it. If your alerting depends on a metric in the stable set, the version pinning advice applies. If it depends on something outside it, you are reading a moving target.

Java is a separate build path with its own agent and JNI library

A Java application cannot be observed by an eBPF program in the same way as a native process, so the repository carries a dedicated Java path. The Dockerfile shows a multi-stage build with a jni-builder stage that compiles a native library against the JNI headers, using a cross compile toolchain chosen by target architecture, and a separate javaagent-builder stage that builds the agent with Gradle on a JDK 21 base image.

The release artifacts reflect that: a release includes a CycloneDX SBOM for the embedded Java agent and its Java dependencies, separate from the SBOMs for the standalone archives. The Makefile names the agent obi-java-agent.jar and gives it its own command entry point.

The examples directory shows the scope of the intended use. There are directories for Apache, nginx, a store demo, the OpenTelemetry Collector, cloud setups, header enrichment, a dynamic selector, a Go trace API example and vendoring. Vendoring deserves a second look for anyone who has to run this in a restricted network, since it is the example that suggests working without pulling dependencies at build time.

The practical boundary of the whole project is the same as for any kernel-level tool: it needs privileges to load eBPF programs, and it needs a kernel and environment that the support matrix actually covers.

Editorial conclusion

Adopt OBI when you need OpenTelemetry traces and metrics from services you cannot rebuild or redeploy, on Linux hosts where loading an eBPF program is acceptable, and you can pin a release tag and live with v0 semantics. Do not adopt it for a fleet you can instrument in code, since application SDKs give better span semantics without kernel-level dependencies, and do not assume continuity of emitted telemetry between minor versions. Before you deploy, read SUPPORT_MATRIX.md for the environments covered, check TELEMETRY.md for what is guaranteed stable in v1, and follow the Config v1 to v2 migration guide, since Config v1 is frozen and receives no bug fixes.

Frequently asked questions

What is OpenTelemetry eBPF Instrumentation (OBI)?

OBI is an OpenTelemetry zero-code instrumentation project that collects telemetry from user-space Linux applications using eBPF, without requiring changes to the instrumented code. The eBPF programs are C, the rest of the project is Go, and the module is go.opentelemetry.io/obi.

How do I download and verify an OBI release?

Download the architecture tar.gz archive for your machine, the SHA256SUMS file and the Sigstore bundle for each, then run cosign verify-blob with the certificate identity and the GitHub Actions OIDC issuer, and finally check the files with sha256sum -c against the signed manifest. The README states that the release blobs are signed with GitHub Actions OIDC and that Cosign must be installed.

Is OBI stable enough for production use?

The project says it is in Development and advises users to pin a specific semver release tag rather than the latest tag, to read release notes between minor versions, and not to assume telemetry continuity for dashboards and alerts before OBI declares those surfaces stable. TELEMETRY.md describes the stable v1 surface and its guarantees.

What is the difference between Config v1 and Config v2 in OBI?

Config v1 is frozen for backward compatibility and gets no bug fixes or new features, while Config v2 receives the configuration improvements. The README says to use Config v2 only with a release whose notes explicitly enable it for your standalone or Collector deployment mode, and points to the migration guide under devdocs/config/version-2.0.

How do I build OBI from source?

You need Docker and GNU Make. Run `make docker-generate` first to generate the eBPF Go bindings, re-running it whenever you change a C file under bpf/, then `make fmt verify` for the linter and unit tests. The integration targets are `make integration-test`, `make integration-test-k8s` and `make oats-test`, and each can take up to 50 minutes.

What licence does OpenTelemetry eBPF Instrumentation use?

Apache-2.0, with the LICENSE file at the repository root and additional notices collected under the NOTICES/ directory and the NOTICE file.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. open-telemetry/opentelemetry-ebpf-instrumentation on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/open-telemetry-opentelemetry-ebpf-instrumentation.svg)](https://hysenlabs.com/projects/open-telemetry-opentelemetry-ebpf-instrumentation)

Was this useful?