Skip to main content

OBI as a collector receiver

Starting with v0.5.0, 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 (v0.5.0 or later — examples below use v0.9.0) cloned locally.
  • 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.9.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.9.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'
meter_provider:
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.9.0 .
docker push <your-registry>/otelcol-obi:v0.9.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.9.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:
instrument:
targets:
- service_name: 'web-app'
- service_name: 'api-service'

Adjust batch processor settings:

processors:
batch:
timeout: 200ms
send_batch_size: 512
send_batch_max_size: 1024
Was this page helpful?