Skip to main content

OBI as a collector receiver

OBI can operate as a receiver component inside the OpenTelemetry Collector. This combines OBI's zero-code eBPF instrumentation with the Collector's processing capabilities, enabling tail-based sampling, data filtering, attribute redaction, and multi-backend export in a single binary.

When to use Collector receiver mode​

Use OBI as a Collector receiver when you need:

  • Unified telemetry pipeline: Process traces, metrics, and logs through a single Collector instance.
  • Advanced processing: Apply tail-based sampling, attribute filtering, or data redaction before export.
  • Multiple backends: Export to Coralogix and additional destinations simultaneously.
  • Compliance requirements: Redact sensitive data (PII, credentials) from telemetry before it leaves the node.

For simple deployments with a single backend and no processing requirements, the standard Helm chart deployment is simpler and uses fewer resources.

Prerequisites​

  • Linux kernel 5.8+ with BTF enabled (or RHEL 4.18 build 348+).
  • Go 1.25 or later.
  • OpenTelemetry Collector Builder (ocb) installed.
  • OBI source repository cloned locally (examples use v0.13.0).
  • Docker or a local C compiler with clang and eBPF headers.

Build the custom Collector​

Step 1: Generate eBPF files​

Clone the OBI repository and generate the required eBPF bytecode:

git clone https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation.git
cd opentelemetry-ebpf-instrumentation
git checkout v0.13.0

# Using Docker (recommended):
make docker-generate

# Or locally if you have clang and eBPF headers:
# make generate

Step 2: Create the builder configuration​

Create a builder-config.yaml file that includes the OBI receiver alongside your required processors and exporters:

dist:
name: otelcol-obi
description: OpenTelemetry Collector with OBI receiver
output_path: ./dist

exporters:
- gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.142.0
- gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.142.0

processors:
- gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.142.0

receivers:
- gomod: go.opentelemetry.io/obi v0.13.0
import: go.opentelemetry.io/obi/collector

providers:
- gomod: go.opentelemetry.io/collector/confmap/provider/envprovider v1.18.0
- gomod: go.opentelemetry.io/collector/confmap/provider/fileprovider v1.18.0
- gomod: go.opentelemetry.io/collector/confmap/provider/yamlprovider v1.18.0

replaces:
- go.opentelemetry.io/obi => /path/to/opentelemetry-ebpf-instrumentation

Update the replaces path to point to your local OBI repository clone.

Step 3: Build the Collector binary​

ocb --config builder-config.yaml

The built binary is at ./dist/otelcol-obi.

Configure the Collector​

Create a collector-config.yaml that defines the OBI receiver, processors, and exporters:

receivers:
obi:
open_port: '8080'
metrics:
features: [network, application]

processors:
batch:
timeout: 1s
send_batch_size: 1024

exporters:
otlp:
endpoint: https://<coralogix-otel-endpoint>:443
headers:
Authorization: Bearer ${env:CORALOGIX_PRIVATE_KEY}

service:
pipelines:
traces:
receivers: [obi]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [obi]
processors: [batch]
exporters: [otlp]

Replace <coralogix-otel-endpoint> with your Coralogix OpenTelemetry endpoint.

Run the Collector​

The Collector requires elevated privileges for eBPF probe attachment:

sudo ./dist/otelcol-obi --config collector-config.yaml

Or grant specific capabilities without running as root:

sudo setcap cap_sys_admin,cap_sys_ptrace,cap_dac_read_search,cap_net_raw,cap_perfmon,cap_bpf,cap_checkpoint_restore=ep ./dist/otelcol-obi
./dist/otelcol-obi --config collector-config.yaml

Deploy on Kubernetes​

Build and push the container image​

FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY dist/otelcol-obi /otelcol-obi
RUN chmod +x /otelcol-obi
ENTRYPOINT ["/otelcol-obi"]
docker build -t <your-registry>/otelcol-obi:v0.13.0 .
docker push <your-registry>/otelcol-obi:v0.13.0

Deploy as a DaemonSet​

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: otel-collector-obi
namespace: monitoring
spec:
selector:
matchLabels:
app: otel-collector-obi
template:
metadata:
labels:
app: otel-collector-obi
spec:
hostNetwork: true
hostPID: true
containers:
- name: otel-collector
image: <your-registry>/otelcol-obi:v0.13.0
args:
- --config=/conf/collector-config.yaml
securityContext:
privileged: true
capabilities:
add:
- SYS_ADMIN
- SYS_PTRACE
- NET_RAW
- DAC_READ_SEARCH
- PERFMON
- BPF
- CHECKPOINT_RESTORE
volumeMounts:
- name: config
mountPath: /conf
- name: sys
mountPath: /sys
readOnly: true
- name: proc
mountPath: /host/proc
readOnly: true
resources:
limits:
memory: 1Gi
cpu: "1"
requests:
memory: 512Mi
cpu: 500m
volumes:
- name: config
configMap:
name: otel-collector-config
- name: sys
hostPath:
path: /sys
- name: proc
hostPath:
path: /proc

Advanced configurations​

Tail-based sampling​

Retain all error traces and slow traces while sampling successful traces at a lower rate. Add the tail sampling processor to your builder configuration:

# Add to builder-config.yaml processors:
processors:
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor v0.142.0

Then configure the sampling policies in your Collector config:

processors:
tail_sampling:
policies:
- name: errors
type: status_code
status_code:
status_codes: [ERROR]
- name: slow_traces
type: latency
latency:
threshold_ms: 1000
- name: sample_success
type: probabilistic
probabilistic:
sampling_percentage: 5
batch:
timeout: 1s

service:
pipelines:
traces:
receivers: [obi]
processors: [tail_sampling, batch]
exporters: [otlp]

Sensitive data filtering​

Redact PII and sensitive attributes before export. Add the attributes processor to your builder configuration:

# Add to builder-config.yaml processors:
processors:
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.142.0

Then configure redaction rules:

processors:
attributes:
actions:
- key: http.url
action: delete
- key: user.email
action: delete
- key: credit_card
pattern: \d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}
action: hash
batch:
timeout: 1s

service:
pipelines:
traces:
receivers: [obi]
processors: [attributes, batch]
exporters: [otlp]

Feature comparison​

FeatureStandalone OBIOBI as Collector receiver
eBPF instrumentationSupportedSupported
Service discoverySupportedSupported
Traces and metrics collectionSupportedSupported
JSON log enrichmentSupportedSupported
Collector processors (sampling, filtering)Not availableSupported
Multiple export destinationsLimitedFully supported
Tail-based samplingNot availableSupported
Resource overheadLowerModerate
Configuration complexitySimpleMore complex

Limitations​

  • Single node scope: The OBI receiver instruments processes on the local node only. Deploy as a DaemonSet for cluster-wide coverage.
  • Privileged access: eBPF probe attachment requires elevated capabilities (CAP_SYS_ADMIN, CAP_BPF, CAP_SYS_PTRACE, and others).
  • Linux only: eBPF is a Linux kernel technology. Windows and macOS are not supported.
  • Restart required: Changes to OBI receiver configuration require a Collector restart.

Troubleshooting​

Build fails with API incompatibility errors​

Ensure your OBI source and Collector component versions are compatible:

  1. Update the OBI repository: git pull origin main.
  2. Check the versions in OBI's go.mod and match them in your builder-config.yaml.
  3. Verify Go version is 1.25+.

No telemetry appears​

  1. Verify the OBI receiver configuration includes the correct open_port.
  2. Check Collector logs for service discovery: grep "discovered service" collector.log.
  3. Verify eBPF programs loaded: bpftool prog show.

Permission denied errors​

Ensure the Collector runs with the required capabilities. On Kubernetes, verify the securityContext in your DaemonSet spec includes all required capabilities.

High memory usage​

Limit instrumentation to specific services to reduce telemetry volume:

receivers:
obi:
discovery:
instrument:
- k8s_pod_labels:
app: web-app
- exe_path: api-service

Adjust batch processor settings:

processors:
batch:
timeout: 200ms
send_batch_size: 512
send_batch_max_size: 1024
Last updated on