Auto-instrumenting OpenTelemetry tracer for Python, wired for PulseBoard. One install, one CLI flag, no code change.
pip install pulseboard-tracer
pulseboard-bootstrap # one-time: pip-installs OTel instrumentations
# for whatever libs are in your venv
PULSE_API_KEY=sk_... pulseboard-run python app.pyWithin ~30s your service shows up in the PulseBoard service catalog with HTTP / DB / cache / queue spans flowing.
- Distributed traces for every popular Python library that has an upstream
OpenTelemetry instrumentation:
requests,urllib,urllib3,httpx,aiohttp,flask,django,fastapi,starlette,psycopg,psycopg2,pymongo,redis,sqlalchemy,celery,boto3,botocore,grpc,kafka-python,pika,elasticsearch, and more. - Resource attributes auto-detected for Docker, Kubernetes (downward API env vars), AWS Lambda and GCP Cloud Run.
- OTLP/HTTP exporter wired to your PulseBoard tenant with
Authorization: Bearer $PULSE_API_KEY. ParentBased(TraceIdRatio)sampling, batched span export — same defaults as the OpenTelemetry contrib distribution.
This package is a thin shell over the upstream
opentelemetry-sdk and
opentelemetry-distro. We
do not fork OTel; you get every patch and instrumentation the upstream
community ships.
pulseboard-run python app.py
- Translates
PULSE_*env vars into the matchingOTEL_*env vars the upstream SDK understands. - Execs
opentelemetry-instrument python app.py, which discovers every installedopentelemetry-instrumentation-*package via its entry points and patches the matching libraries before your code imports them.
pulseboard-run is the recommended path. The two alternatives below also
work because we register ourselves as an OpenTelemetry distro via the
opentelemetry_distro entry point:
# Equivalent to pulseboard-run:
opentelemetry-instrument python app.py
# Or programmatic:
python -c "from pulseboard_tracer import start; start(); ..."Every setting is environment-driven. Programmatic overrides are also
supported via start(...).
| Variable | Default | Notes |
|---|---|---|
PULSE_URL |
https://api.pulseboard.cloud |
OTLP/HTTP base URL. /v1/traces, /v1/metrics are appended. |
PULSE_API_KEY |
(none) | Sent as Authorization: Bearer …. Required in production. |
PULSE_SERVICE_NAME |
detected | Falls back to OTEL_SERVICE_NAME, AWS_LAMBDA_FUNCTION_NAME, K_SERVICE. |
PULSE_SERVICE_VERSION |
(none) | Becomes service.version. |
PULSE_ENVIRONMENT |
(none) | Becomes deployment.environment.name. |
PULSE_DISABLE_INSTRUMENTATION |
(none) | CSV of short names: flask,django. Full opentelemetry-instrumentation-X also. |
PULSE_SAMPLE_RATIO |
1 |
Float in [0, 1]. Applied with ParentBased(TraceIdRatio). |
PULSE_DISABLED |
false |
When 1/true, exporters are set to none so no telemetry is shipped. |
PULSE_DEBUG |
false |
When 1/true, lifecycle messages to stderr. |
from pulseboard_tracer import start, shutdown
handle = start(service_name="checkout", sample_ratio=0.1)
try:
...
finally:
shutdown()PULSE_API_KEY=sk_... PULSE_DEBUG=1 \
pulseboard-run python examples/smoke.pyYou should see [pulseboard-tracer debug] env translated → … on stderr
and the in-process HTTP span in your PulseBoard tenant.
Shipped in 0.1:
- Traces (OTLP/HTTP,
BatchSpanProcessor) - Metrics + logs export plumbing (PulseBoard-specific exemplar wiring lands with the LLM tracer slice)
- Auto-instrumentation discovery via the upstream
opentelemetry_instrumentorentry-point machinery - Env-based detection for AWS Lambda / GCP Cloud Run / k8s downward API
pulseboard-run/pulseboard-bootstrapCLI wrappers- Programmatic
start()/shutdown()API
Explicitly not in 0.1:
- Continuous CPU/heap profiler hook (planned with the agent-side profiler service)
- Error / exception capture beyond what OTel spans already record
- LLM request shape capture (planned with the LLM observability slice)
- Framework-specific extensions beyond the upstream auto-instrumentations (FastAPI/Celery/LangChain extras land in a later slice)
- Source-map / debug-symbol upload helper
python -m venv .venv
source .venv/bin/activate
pip install -e ".[test]"
pytest -qCI runs the same suite against Python 3.9 / 3.10 / 3.11 / 3.12.
MIT — see LICENSE.