Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions otlp-bench/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/internal/otlpbuild/testdata/tmp
/internal/otlpbuild/testdata/dst
otlp-bench-results
5 changes: 5 additions & 0 deletions otlp-bench/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# otlp-bench

`otlp-bench` is a tool for comparing different variants for encoding profiling data as OTLP.

For now check [reports/2025-11-27-gh733-resource-attr-dict/README.md]() for more information.
29 changes: 29 additions & 0 deletions otlp-bench/bench-setup/Dockerfile.custom
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM alpine:3.19 AS certs

RUN apk --update add ca-certificates


FROM golang:1.25 AS build-stage

WORKDIR /build

COPY ./builder-manifest.yaml builder-manifest.yaml

RUN --mount=type=cache,target=/root/.cache/go-build GO111MODULE=on go install go.opentelemetry.io/collector/cmd/[email protected]
RUN --mount=type=cache,target=/root/.cache/go-build builder --config builder-manifest.yaml


FROM alpine:3.19

RUN apk --no-cache add ca-certificates util-linux

ARG USER_UID=10001
RUN adduser -D -u ${USER_UID} otel
USER ${USER_UID}

COPY --chmod=755 --from=build-stage /build/dist/otelcol-ebpf-profiler-custom /otelcol/otelcol-ebpf-profiler-custom

ENTRYPOINT ["/otelcol/otelcol-ebpf-profiler-custom"]
CMD ["--config", "/conf/relay.yaml"]

EXPOSE 4317 4318 13133 14250 14268 6831 9411
89 changes: 89 additions & 0 deletions otlp-bench/bench-setup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# OTLP Profiling Benchmark Setup

This setup captures real-world OTLP profiling data to measure the impact of protocol changes on in-memory and wire size.

## Overview

We run two workloads on a single-node minikube cluster:

- **[OpenTelemetry Demo](https://github.com/open-telemetry/opentelemetry-demo)** (Astronomy Shop): A fictional e-commerce application composed of ~15 microservices written in Go, Java, Python, .NET, Node.js, Rust, PHP, and more. Generates diverse profiling data across different runtimes and frameworks.
- **[NetBox](https://github.com/netbox-community/netbox)**: A network infrastructure management platform (IPAM/DCIM) built with Django. Runs as a gunicorn WSGI application that spawns multiple worker processes—useful for evaluating profiler behavior with forking Python processes.

A custom OpenTelemetry Collector with the [eBPF profiler](https://github.com/open-telemetry/opentelemetry-ebpf-profiler) captures profiles from all processes on the node and writes them to disk.

## Prerequisites

- Ubuntu 24.04 VM (tested on AWS c6a.8xlarge: 32 vCPUs, 64 GiB)
- Sudo access

## Setup

### 1. Install dependencies

```bash
./install.sh
```

This installs Docker, minikube, kubectl, helm, and configures the system for Kubernetes.

After installation, either log out and back in, or run `newgrp docker` to activate Docker group membership.

### 2. Start the cluster

```bash
minikube start --driver=none
```

### 3. Deploy workloads

**OpenTelemetry Demo:**

```bash
kubectl create namespace otel-demo
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm install otel-demo open-telemetry/opentelemetry-demo -n otel-demo --values k8s/opentelemetry-demo/values.yaml
```

**NetBox:**

```bash
kubectl create namespace netbox-bench
helm install netbox-bench oci://ghcr.io/netbox-community/netbox-chart/netbox -n netbox-bench
```

NetBox takes ~10 minutes to start (database migrations). Wait for all pods to be ready:

```bash
kubectl get pods -n netbox-bench -w
```

Then start the load generator:

```bash
kubectl apply -f k8s/netbox/load-generator.yaml
```

### 4. Deploy the collector

Build a custom collector pinned to a specific commit of the eBPF profiler:

```bash
./build-custom-collector.sh
```

Deploy it:

```bash
kubectl create namespace otel
kubectl apply -f k8s/opentelemetry-collector/
```

## Output

Profiles are written to `/var/lib/otel-profiles/profiles.proto` in the [file exporter format](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/fileexporter#file-format).

## Notes

- The collector runs as a DaemonSet with privileged access (required for eBPF).
- We use a custom Kubernetes manifest because the collector Helm charts don't yet support the profiling distribution.
- The `builder-manifest.yaml` pins the eBPF profiler to a [specific commit](https://github.com/open-telemetry/opentelemetry-ebpf-profiler/tree/fd60ef3f4a81577e4269bf821b11b38b81fadb52) for reproducibility. It includes [#889](https://github.com/open-telemetry/opentelemetry-ebpf-profiler/pull/889) which makes collector logs more configurable.
39 changes: 39 additions & 0 deletions otlp-bench/bench-setup/build-custom-collector.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
set -e

# Configuration
IMAGE_NAME="otelcol-ebpf-profiler-custom"
IMAGE_TAG="${IMAGE_TAG:-latest}"

# Verify we're using minikube with driver=none
if ! kubectl config current-context 2>/dev/null | grep -q "minikube"; then
echo "❌ Error: Not using minikube context"
echo "This script only supports minikube with driver=none"
exit 1
fi

MINIKUBE_DRIVER=$(minikube profile list -o json 2>/dev/null | grep -o '"Driver":"[^"]*"' | cut -d'"' -f4 || echo "")
if [ "$MINIKUBE_DRIVER" != "none" ]; then
echo "❌ Error: Minikube is using driver: $MINIKUBE_DRIVER"
echo "This script only supports minikube with driver=none"
echo ""
echo "To use driver=none:"
echo " sudo minikube delete"
echo " sudo minikube start --driver=none"
exit 1
fi

echo "Building custom OpenTelemetry Collector..."
echo "Image: ${IMAGE_NAME}:${IMAGE_TAG}"
echo "Driver: none (using host Docker daemon)"
echo ""

# Build with host Docker daemon
docker build -f Dockerfile.custom -t ${IMAGE_NAME}:${IMAGE_TAG} .

echo ""
echo "✅ Build complete!"
echo ""
echo "Deploy with:"
echo " kubectl create namespace otel # if not exists"
echo " kubectl apply -f k8s/opentelemetry-collector/"
40 changes: 40 additions & 0 deletions otlp-bench/bench-setup/builder-manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
dist:
name: otelcol-ebpf-profiler-custom
description: Custom OpenTelemetry Collector with eBPF Profiler
version: latest
output_path: ./dist
otelcol_version: latest

extensions:
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/opampextension v0.139.0

exporters:
- gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.139.0
- gomod: go.opentelemetry.io/collector/exporter/nopexporter v0.139.0
- gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.139.0
- gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter v0.139.0

processors:
- gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.139.0
- gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.139.0
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.139.0

receivers:
- gomod: go.opentelemetry.io/ebpf-profiler fd60ef3f4a81577e4269bf821b11b38b81fadb52
import: go.opentelemetry.io/ebpf-profiler/collector

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

# When adding a replace, add a comment before it to document why it's needed and when it can be removed
replaces:
# see https://github.com/openshift/api/pull/1515
- github.com/openshift/api => github.com/openshift/api v0.0.0-20230726162818-81f778f3b3ec
Loading