DEV Community

Cover image for Grafana Beyla: eBPF auto-instrumentation for HTTP and gRPC, no code
Span Observer
Span Observer

Posted on Originally published at span.observer

Grafana Beyla: eBPF auto-instrumentation for HTTP and gRPC, no code

Grafana Beyla is an eBPF auto-instrumentation tool: it watches your HTTP and gRPC services from the Linux kernel and produces traces and RED metrics without touching the code or restarting the application. For a platform team inheriting dozens of uninstrumented services, it is a quick way to get a first level of visibility.

This practical guide explains what Beyla really does, how to run it against a container, which Linux privileges it needs, where its traces stop and why its status has changed: the code was donated to OpenTelemetry in 2025. Everything comes from the official Grafana and OpenTelemetry documentation. The content depends on neither Dynatrace SaaS nor Dynatrace Managed; only the OTLP output links them, through a compatible backend.

In brief

  • Beyla captures web-transaction spans and Rate, Errors, Duration (RED) metrics for HTTP/S and gRPC services, without changing application code or configuration (Grafana documentation).
  • Prerequisites: Linux kernel 5.8 or later with BTF; 5.17 or later for trace context propagation through HTTP headers.
  • RED metrics are the safe bet; traces are « supported with limitations » depending on the language.
  • The code now lives upstream in OpenTelemetry eBPF Instrumentation (OBI); Beyla is the distribution supported by Grafana.

Grafana Beyla: what the tool observes, and how

According to Grafana’s documentation, Beyla inspects application executables and the operating system’s networking layer using eBPF. From that it derives web-transaction spans and RED metrics for Linux HTTP/S and gRPC services. The languages listed include Go, C/C++, Rust, Python, Ruby, Java (GraalVM Native included), Node.js and .NET.

Export is vendor-agnostic: OpenTelemetry format (OTLP) or native Prometheus metrics. Beyla also listens to the Kubernetes API to decorate metrics and traces with pod and service metadata, and integrates with Grafana Alloy.

Why an agent outside the process changes the measurement

A classic agent measures service time, that is, the time spent inside the request handler. Beyla observes at the kernel’s network level. Its documentation says its latencies therefore reflect what the client sees, internal queue time included. For a latency SLO that difference matters: an overloaded service whose threads are all busy looks fast from the inside and slow to the user.

Another documented consequence: the instrumentation code does not run in the application’s memory. It can be added or removed without a restart, and a failure of the eBPF component does not crash the monitored service. These points come from Grafana; validate them on your own workload.

Prerequisites and Linux privileges

The home page of the Beyla documentation sets these conditions:

  • Linux kernel 5.8 or later with BTF enabled (file /sys/kernel/btf/vmlinux); the 4.18 kernels of the RHEL 8 family are also supported;
  • context propagation through HTTP headers: kernel 5.17 or later, because the tool uses the bpf_loop helper;
  • Go applications built with Go 1.17 or later.

Beyla loads eBPF programs and reads /proc, so it needs privileges. The Security page recommends granting only the capabilities required rather than full root. At start-up it warns if a capability is missing; setting BEYLA_ENFORCE_SYS_CAPS=1 makes it fail immediately.

List of Linux capabilities required by Beyla: CAP\_BPF, CAP\_NET\_RAW, CAP\_NET\_ADMIN, CAP\_PERFMON, CAP\_SYS\_PTRACE, CAP\_SYS\_ADMIN and what each is used for

A point to watch on managed clusters: according to the documentation, AKS and EKS default to a perf_event_paranoid setting above 1, which requires CAP_SYS_ADMIN instead of CAP_PERFMON. Debian-based distributions often use the value 3, with the same effect. Have your security team validate this requirement before any rollout.

Running Beyla against a container, step by step

The easiest way to try it is the Docker mode in the documentation: a Beyla container shares the PID namespace of the container to instrument.

  1. Start a test service. The documentation uses a small Go blog, mariomac/goblog:dev, listening on HTTPS on internal port 8443.
  2. Choose the process. The variable BEYLA_OPEN_PORT=8443 selects the process listening on that port. BEYLA_AUTO_TARGET_EXE selects by executable path (glob pattern).
  3. Print traces in plain text. BEYLA_TRACE_PRINTER=text prints them to standard output, handy for validating before exporting.
  4. Run Beyla with --pid="container:goblog" and either --privileged or the capabilities listed above.

docker run commands for the goblog service then for Beyla with BEYLA\_OPEN\_PORT and BEYLA\_TRACE\_PRINTER, followed by the printed trace lines

docker run -p 18443:8443 --name goblog mariomac/goblog:dev

docker run --rm \
  -e BEYLA_OPEN_PORT=8443 \
  -e BEYLA_TRACE_PRINTER=text \
  --pid="container:goblog" \
  --privileged \
  grafana/beyla:latest
Enter fullscreen mode Exit fullscreen mode

How to check that it works

Open https://localhost:18443, browse around, then watch Beyla’s output. Each request appears as a line with duration, HTTP status, method, path and addresses, for example « 200 GET / ». If nothing shows, look in the logs for the warning about missing capabilities, then check the port you chose.

Moving to a configuration file and OTLP

For long-term operation, configuration moves to YAML. Environment variables take priority over the file, according to the documentation. The discovery.instrument section describes the target services; the open_ports key accepts ports and ranges (80,443,8000-8999), and exe_path a pattern on the executable path. On Kubernetes it also accepts filters such as k8s_namespace or k8s_deployment_name.

beyla-config.yaml file with discovery.instrument open\_ports, ebpf context\_propagation all, otel\_traces\_export endpoint and prometheus\_export port 8999

discovery:
  instrument:
    - open_ports: 8443
ebpf:
  context_propagation: "all"
otel_traces_export:
  endpoint: http://otel-collector:4318
prometheus_export:
  port: 8999
  path: /metrics
log_level: INFO
Enter fullscreen mode Exit fullscreen mode

The example above assembles keys found in the documentation (the Collector address is fictitious). If you target a Collector, our guide to the OpenTelemetry Collector on Kubernetes describes a full OTLP receiving pipeline, with export to Dynatrace. To limit trace volume afterwards, see tail sampling.

The Prometheus port lets a Prometheus server scrape the RED metrics; our article on Prometheus and Dynatrace on Kubernetes covers that collection.

Trace limits, language by language

The documentation offers a compatibility matrix worth reading before promising traces to a team. Its conclusions: Beyla is strongest as a zero-code baseline layer for RED metrics and service graphs, while OpenTelemetry SDKs remain the recommended choice for detailed distributed traces.

  • Go HTTP, HTTP/2, HTTPS and gRPC: traces recommended. Go is the best-covered case.
  • Standard Java, Node.js, Python, Ruby: traces « supported with limitations ».
  • Reactive or thread-switching Java: traces not recommended; stand-alone spans may not attach to the right trace.
  • .NET: fine if the service is not first in the call chain; if it is the entry point, tracing may not work correctly.
  • Service already instrumented with an OpenTelemetry SDK: Beyla automatically disables its own traces and remains recommended for RED metrics.

Context propagation between services

Distributed traces rely on the W3C traceparent header. Beyla reads the incoming context, follows execution and adds traceparent to outgoing HTTP and gRPC requests; if the application already set it, Beyla reuses that value. Network-level propagation is disabled by default: enable it with BEYLA_BPF_CONTEXT_PROPAGATION=all or ebpf.context_propagation. It needs extra capabilities (CAP_NET_ADMIN and CAP_PERFMON). To see what correct propagation gives you across message queues, read our article on context propagation with Kafka.

Beyla, OBI and OpenTelemetry: where do things stand?

Grafana’s documentation states it: Beyla’s code was donated to the OpenTelemetry project in 2025 under the name OpenTelemetry eBPF Instrumentation (OBI), now maintained by a consortium of contributors including Grafana. Beyla is the OBI distribution supported by Grafana, and imports OBI’s code as a library. Every OBI feature is therefore in Beyla, but not the reverse: process metrics, survey mode or the Alloy integration do not exist in OBI.

Two practical differences for a rollout: OBI’s environment variables start with OTEL_EBPF_ (Beyla accepts both prefixes), and metrics without a semantic convention carry the beyla_ or obi_ prefix. The YAML schema is the same. The OpenTelemetry site describes OBI as a getting-started tool for application observability, covering HTTP/S, gRPC, Kafka and several databases, on kernel 5.8 or later. The exact Beyla version to install was not verified here: check the repository’s releases page before pinning a version.

This move points toward a standard: if you are building an OpenTelemetry strategy, eBPF auto-instrumentation has a place in it without depending on a single vendor. Our comparison of OpenTelemetry and Prometheus sets the general frame.

What this changes for an SRE team

Beyla lowers the cost of the first observability layer: you get RED metrics, hence availability and latency SLIs, on services nobody can recompile. It does not replace instrumentation work on critical services, where business spans and log correlation stay richer with an SDK. Our article on observability versus monitoring recalls why these signals complement each other.

Best practices

  • Start with a single service and BEYLA_TRACE_PRINTER=text, before any export.
  • Limit discovery with discovery.instrument on Kubernetes, rather than instrumenting the whole node.
  • Configure low-cardinality routes (Routes Decorator) for usable traces, as the documentation advises.
  • Grant precise capabilities and document the CAP_SYS_ADMIN exception if the node requires it.
  • Do not double up Beyla and an SDK on the traces of one service; keep Beyla for RED metrics.
  • Test on a kernel identical to production: prerequisites depend on the kernel version.

Frequently asked questions

Does Grafana Beyla replace OpenTelemetry SDKs?

No. According to Grafana’s documentation, Beyla is strongest as a baseline layer for RED metrics, whereas SDKs remain recommended for detailed distributed traces. The two can coexist, with Beyla switching off its own traces.

Do I need to restart the application to instrument it with Beyla?

No. The documentation says Beyla instruments without a restart and without modifying the application. You do need to give it the right Linux privileges and a compatible kernel.

Is Beyla still maintained since the donation to OpenTelemetry?

Yes. Grafana presents it as the OBI distribution it supports, and notes that its release cycle is usually faster than OBI’s. The GitHub repository also says development is moving to the upstream OBI repository.

Conclusion

Beyla offers a short path to RED metrics and partial traces, at the price of elevated Linux privileges and language-dependent trace limits. Try it on one service, read the compatibility matrix, then decide where an SDK is still needed.

Sources

span.observer is an independent community blog, not affiliated with Dynatrace LLC or Grafana Labs. Product names belong to their respective owners; configuration examples are for teaching purposes, fictitious addresses included.


Originally published on span.observer. French version: https://span.observer/fr/grafana-beyla-ebpf-auto-instrumentation/.

Top comments (0)