How to Configure OpenTelemetry Tracing with Headroom: Complete Setup Guide
Headroom provides an optional OpenTelemetry tracing façade that exports spans to Langfuse via OTLP when you install the otel extra, set the required environment variables, and call configure_langfuse_tracing() at startup.
Headroom ships with a lightweight tracing abstraction that remains in-process by default. To export distributed traces to an OpenTelemetry-compatible collector, you must enable the optional otel dependency and configure the Langfuse exporter using environment variables. This guide covers the complete configuration flow based on the Headroom source code.
Install the OpenTelemetry Extra
Begin by installing Headroom with the optional OpenTelemetry dependencies. The otel extra, defined in [pyproject.toml](https://github.com/chopratejas/headroom/blob/main/pyproject.toml) (line 153), pulls in the OpenTelemetry SDK and HTTP OTLP exporter.
pip install "headroom-ai[otel]"
Without this extra, Headroom falls back to a no-op tracer that discards spans locally.
Configure Environment Variables
Tracing is driven entirely by environment variables. The LangfuseTracingConfig.from_env() method (lines 54-77) reads these values to construct the OTLP endpoint and authentication headers.
Set the following variables before starting your application:
HEADROOM_LANGFUSE_ENABLED– Set totrueto activate the exporter.LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY– Authentication credentials for the Langfuse collector.LANGFUSE_BASE_URL(orLANGFUSE_OTEL_HOST) – The base URL of your Langfuse instance (e.g.,https://cloud.langfuse.com).HEADROOM_LANGFUSE_SERVICE_NAME– The service name that appears in trace metadata (defaults toheadroom).HEADROOM_LANGFUSE_RESOURCE_ATTRIBUTES– Optional comma-separatedkey=valuepairs added as resource attributes (e.g.,region=us-east,team=nlp).
These variables configure the OTLP endpoint at /api/public/otel/v1/traces and the HTTP Basic Authentication header required by Langfuse.
Activate the Exporter
Initialize the tracing system once at application startup. The configure_langfuse_tracing() function creates a TracerProvider, attaches a BatchSpanProcessor with an OTLPSpanExporter, and replaces the global Headroom tracer.
from headroom.observability.tracing import configure_langfone_tracing
# Reads env vars and configures the global tracer
configure_langfuse_tracing()
If the otel extra is missing or required environment variables are absent, the function falls back to a no-op tracer and logs a warning (lines 149-158 of tracing.py).
Create and Export Spans
Once configured, use the get_headroom_tracer() function to obtain the tracer instance and start spans. The HeadroomTracer delegates to the underlying OpenTelemetry tracer, ensuring all spans export to the configured Langfuse endpoint.
from headroom.observability.tracing import get_headroom_tracer
tracer = get_headroom_tracer()
def process_request():
with tracer.start_as_current_span("process_request", attributes={"user_id": "12345"}):
# Your business logic here
pass
Standard OpenTelemetry context propagation applies, so nested spans automatically become children of the current active span.
Advanced Configuration and Lifecycle Management
Inspect Tracing Status
Verify the current configuration using get_langfuse_tracing_status() (lines 94-106):
from headroom.observability.tracing import get_langfuse_tracing_status
status = get_langfuse_tracing_status()
print(status)
# Output: {'configured': True, 'enabled': True, 'service_name': 'headroom', ...}
Clean Shutdown
Ensure all pending spans flush before process exit by calling shutdown_headroom_tracing() (lines 191-205):
import atexit
from headroom.observability.tracing import shutdown_headroom_tracing
atexit.register(shutdown_headroom_tracing)
Complete Example
Here is a minimal working example that combines installation, configuration, and instrumentation:
import os
from headroom.observability.tracing import (
configure_langfuse_tracing,
get_headroom_tracer,
shutdown_headroom_tracing
)
# 1. Configure environment
os.environ["HEADROOM_LANGFUSE_ENABLED"] = "true"
os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-..."
os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-..."
os.environ["HEADROOM_LANGFUSE_RESOURCE_ATTRIBUTES"] = "env=production,service=ai-gateway"
# 2. Initialize tracing
configure_langfuse_tracing()
# 3. Use the tracer
tracer = get_headroom_tracer()
with tracer.start_as_current_span("main_workflow"):
print("Processing with distributed tracing enabled")
# 4. Optional: cleanup
shutdown_headroom_tracing()
Summary
- Install the extra: Use
pip install "headroom-ai[otel]"to include OpenTelemetry SDK dependencies. - Set environment variables: Configure
HEADROOM_LANGFUSE_ENABLED,LANGFUSE_PUBLIC_KEY, andLANGFUSE_SECRET_KEYto authenticate with the Langfuse collector. - Initialize at startup: Call
configure_langfuse_tracing()once to set up theTracerProviderandBatchSpanProcessor. - Instrument code: Use
get_headroom_tracer()to obtain the tracer andstart_as_current_span()to create exportable spans. - Manage lifecycle: Call
shutdown_headroom_tracing()on exit to ensure all spans flush to the collector.
Frequently Asked Questions
What happens if I install Headroom without the otel extra?
The library defaults to a no-op tracer that records spans in-process only. If you call configure_langfuse_tracing() without the extra installed, the function catches the missing dependency and logs a warning, continuing execution without exporting traces (see lines 149-158 in headroom/observability/tracing.py).
Can I export traces to a different OTLP endpoint instead of Langfuse?
Currently, Headroom only supports Langfuse as the OTLP destination through the configure_langfuse_tracing() helper. The function specifically constructs the Langfuse endpoint path (/api/public/otel/v1/traces) and authentication headers. For other collectors, you would need to implement a custom configuration using the underlying OpenTelemetry SDK directly.
How do I add custom resource attributes to all spans?
Set the HEADROOM_LANGFUSE_RESOURCE_ATTRIBUTES environment variable to a comma-separated list of key=value pairs before calling configure_langfuse_tracing(). These attributes attach to the Resource associated with the TracerProvider, appearing on every span exported from the service.
Is tracing enabled by default?
No. Tracing remains disabled until you explicitly set HEADROOM_LANGFUSE_ENABLED=true and call configure_langfuse_tracing(). This opt-in design prevents accidental data leakage to external collectors and ensures zero overhead when observability is not required.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →