Phase 0: Python Warm-up
2. Instrument with OBI
Now add APM tracing to this running app without touching a single line of code.
Download OBI #
Download the pre-built OBI binary from the GitHub releases page :
bash
cd ~/workshop/obi/01-obi-python
sudo env \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://ingest.${REALM}.signalfx.com:443" \
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="grpc" \
OTEL_EXPORTER_OTLP_HEADERS="X-SF-Token=${ACCESS_TOKEN}" \
OTEL_SERVICE_NAME="warmup-app" \
OTEL_RESOURCE_ATTRIBUTES="deployment.environment=ebpf-bare-app,host.name=${INSTANCE}" \
OTEL_EBPF_OPEN_PORT=5150 \
./obiGenerate traffic and look for this output
text
...
time=2026-02-27T19:29:56.296Z level=INFO msg="instrumenting process" component=discover.traceAttacher cmd=/usr/bin/python3.10 pid=245031 ino=7094 type=python service=warmup-app logenricher=false
...
time=2026-02-27T19:29:58.278Z level=INFO msg="Launching p.Tracer" component=generic.Tracerbash
VERSION=0.8.0
ARCH=amd64
wget "https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/releases/download/v$VERSION/obi-v$VERSION-linux-$ARCH.tar.gz"
wget "https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/releases/download/v$VERSION/SHA256SUMS"
sha256sum -c SHA256SUMS --ignore-missing
tar -xzf "obi-v$VERSION-linux-$ARCH.tar.gz"
ls -la ./obitext
obi-v0.6.0-linux-amd64.tar.gz: OK
-rwxr-xr-x 1 splunk splunk 112345678 Feb 27 14:47 ./obiRun OBI #
Exercise
In a separate terminal, run OBI with sudo. Replace the three placeholders with your realm, token, and hostname from the previous step (this may take a minute or two to complete):
bash
cd ~/workshop/obi/01-obi-python
sudo env \
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="https://ingest.${REALM}.signalfx.com:443" \
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="grpc" \
OTEL_EXPORTER_OTLP_HEADERS="X-SF-Token=${ACCESS_TOKEN}" \
OTEL_SERVICE_NAME="warmup-app" \
OTEL_RESOURCE_ATTRIBUTES="deployment.environment=ebpf-bare-app,host.name=${INSTANCE}" \
OTEL_EBPF_OPEN_PORT=5150 \
./obiGenerate traffic and look for this output
text
...
time=2026-02-27T19:29:56.296Z level=INFO msg="instrumenting process" component=discover.traceAttacher cmd=/usr/bin/python3.10 pid=245031 ino=7094 type=python service=warmup-app logenricher=false
...
time=2026-02-27T19:29:58.278Z level=INFO msg="Launching p.Tracer" component=generic.TracerWhat Do These Variables Do? #
| Variable | Purpose |
|---|---|
sudo | eBPF probes require root/kernel access |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | Full URL for Splunk’s OTLP trace ingest. The per-signal env var sends to this URL exactly the base OTEL_EXPORTER_OTLP_ENDPOINT would append /v1/traces which doesn’t match Splunk’s path |
OTEL_EXPORTER_OTLP_HEADERS | Auth header for Splunk |
OTEL_SERVICE_NAME | The service name that appears in Splunk APM |
OTEL_RESOURCE_ATTRIBUTES | Sets deployment.environment and host.name on every trace so you can filter to your data |
OTEL_EBPF_OPEN_PORT | Tells OBI to instrument the process listening on port 5150 |
Note
You may see warnings likefailed to upload metrics: 404 Not Found in the OBI logs. This is expected Splunk’s direct ingest doesn’t have a standard OTLP metrics endpoint. The traces still export correctly. In Phase 2, a collector handles both traces and metrics properly.Generate Traffic #
Go back to your first terminal and generate some requests:
bash
for i in $(seq 1 20); do curl -s "http://localhost:5150/hello"; sleep 1; doneNOTE: If you get a 404 error double check that there is no \ appended to the url you are curling. In some termings the ; will attempt to escape and cause an invalid url
