Grafana Beyla eBPF auto-instrumentation for application observability without code changes. Covers supported languages/runtimes, requirements, installation, configuration (discovery, eBPF settings, OTLP traces export, Prometheus metrics export), Kubernetes deployment, and integration with Grafana Cloud. Use when setting up zero-code instrumentation, configuring eBPF probes, deploying Beyla to Kubernetes, connecting to Tempo/Prometheus, or troubleshooting instrumentation issues.
68
82%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Beyla is a Grafana eBPF auto-instrumentation tool that captures HTTP/gRPC traffic and generates traces and metrics without modifying application code.
CAP_SYS_ADMIN; in Kubernetes must run in host PID namespaceCheck BTF support:
ls /sys/kernel/btf/vmlinux # must exist| Language | HTTP | gRPC | DB queries |
|---|---|---|---|
| Go | ✅ | ✅ | ✅ |
| Java (JVM) | ✅ | ✅ | ✅ |
| Python | ✅ | ✅ | - |
| Ruby | ✅ | - | - |
| Node.js | ✅ | - | - |
| .NET | ✅ | ✅ | - |
| Rust | ✅ | ✅ | - |
| C/C++ | ✅ | - | - |
| PHP | ✅ | - | - |
# Docker
docker run --privileged --pid=host \
-v /sys/kernel/debug:/sys/kernel/debug:ro \
-e BEYLA_OPEN_PORT=8080 \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \
grafana/beyla
# Kubernetes (Helm)
helm repo add grafana https://grafana.github.io/helm-charts
helm install beyla grafana/beyla \
--version 1.16.7 \
--set discovery.services[0].open_port=8080 \
--set otelTraces.endpoint=http://tempo:4318# beyla-config.yml
log_level: INFO
discovery:
services:
- name: my-app
open_port: 8080
# or by process name:
# exe_path: /usr/bin/myapp
# or by K8s pod metadata (auto-detected in K8s)
ebpf:
wakeup_len: 100 # batch size for events
track_request_headers: false # enable to capture HTTP headers (high cardinality risk)
high_request_volume: false # optimize for high-traffic services
# Distributed tracing output (OTLP)
otel_traces_export:
endpoint: http://tempo:4318 # HTTP OTLP endpoint
# Or gRPC:
# endpoint: tempo:4317
# protocol: grpc
# Metrics output (Prometheus)
prometheus_export:
port: 9090
path: /metrics
# Or metrics via OTLP
otel_metrics_export:
endpoint: http://prometheus-otlp:9090apiVersion: apps/v1
kind: DaemonSet
metadata:
name: beyla
namespace: monitoring
spec:
selector:
matchLabels:
app: beyla
template:
metadata:
labels:
app: beyla
spec:
hostPID: true # required for eBPF
serviceAccountName: beyla
containers:
- name: beyla
image: grafana/beyla:latest
securityContext:
privileged: true # or use specific capabilities
# Alternative (non-privileged):
# capabilities:
# add: [SYS_ADMIN, SYS_PTRACE, NET_ADMIN]
env:
- name: BEYLA_OPEN_PORT
value: "8080"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://alloy:4318"
volumeMounts:
- name: sys-kernel-debug
mountPath: /sys/kernel/debug
readOnly: true
volumes:
- name: sys-kernel-debug
hostPath:
path: /sys/kernel/debugapiVersion: v1
kind: ServiceAccount
metadata:
name: beyla
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: beyla
rules:
- apiGroups: [""]
resources: [nodes, pods, services, endpoints, namespaces]
verbs: [get, list, watch]| Variable | Description |
|---|---|
BEYLA_OPEN_PORT | Port(s) to instrument (e.g., 8080, 8080-8090) |
BEYLA_EXECUTABLE_NAME | Process name pattern to instrument |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP endpoint for traces and metrics |
OTEL_EXPORTER_OTLP_PROTOCOL | grpc or http/protobuf (default) |
OTEL_SERVICE_NAME | Override service name in spans |
BEYLA_LOG_LEVEL | DEBUG, INFO, WARN, ERROR |
BEYLA_PROMETHEUS_PORT | Port for Prometheus metrics scrape |
BEYLA_PROMETHEUS_PATH | Path for Prometheus metrics (default /metrics) |
# Using Alloy as the OTLP receiver
otel_traces_export:
endpoint: http://alloy:4318 # Alloy forwards to Grafana Cloud Tempo
otel_metrics_export:
endpoint: http://alloy:4318 # Alloy forwards to Grafana Cloud PrometheusVia Alloy config:
otelcol.receiver.otlp "beyla" {
http { endpoint = "0.0.0.0:4318" }
output {
traces = [otelcol.exporter.otlp.grafana_cloud.input]
metrics = [otelcol.exporter.prometheus.local.input]
}
}Critical for production — prevents HTTP path cardinality explosion:
routes:
patterns:
- /user/{id}
- /api/v1/resources/{resource_id}
ignored_patterns:
- /health
- /metrics
ignore_mode: traces # or: metrics, both
unmatched: heuristic # or: path, wildcard, low-cardinalityunmatched strategies: heuristic (replaces numeric IDs, best default), low-cardinality (threshold-based collapsing), wildcard (/**), path (actual path — risk of explosion).
otel_traces_export:
sampler:
name: "parentbased_traceidratio" # parent-aware fraction sampling
arg: "0.1" # 10% sampling — arg is a quoted stringSamplers: always_on, always_off, traceidratio, parentbased_always_on (default), parentbased_traceidratio.
| Metric | Type | Description |
|---|---|---|
http.server.request.duration | Histogram | Inbound HTTP request duration |
http.client.request.duration | Histogram | Outbound HTTP request duration |
rpc.server.duration | Histogram | gRPC server call duration |
rpc.client.duration | Histogram | gRPC client call duration |
db.client.operation.duration | Histogram | DB query duration |
Labels: http.method, http.route, http.response.status_code, service.name, service.namespace
In Kubernetes, Beyla auto-discovers pods and enriches telemetry with K8s metadata:
discovery:
services:
- k8s_namespace: "production" # instrument all pods in namespace
- k8s_pod_name: "frontend.*" # by pod name regex
- k8s_deployment_name: "api" # by deployment name
- open_port: 8080 # or by port (any pod)Auto-enriched span attributes: k8s.namespace.name, k8s.pod.name, k8s.node.name, k8s.deployment.name
8f1ba27
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.