Metadata-Version: 2.4
Name: pulseboard-tracer
Version: 0.1.0
Summary: PulseBoard auto-instrumenting Python tracer — thin OTel shell. `pulseboard-run python app.py` and you're done.
Author: PulseBoard contributors
License: MIT
Project-URL: Homepage, https://github.com/OpenPulseBoard/pulseboard-tracer-python
Project-URL: Repository, https://github.com/OpenPulseBoard/pulseboard-tracer-python
Project-URL: Issues, https://github.com/OpenPulseBoard/pulseboard-tracer-python/issues
Keywords: pulseboard,observability,opentelemetry,otel,tracing,apm,instrumentation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: opentelemetry-api<2,>=1.27.0
Requires-Dist: opentelemetry-sdk<2,>=1.27.0
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.27.0
Requires-Dist: opentelemetry-instrumentation<1,>=0.48b0
Requires-Dist: opentelemetry-distro<1,>=0.48b0
Provides-Extra: test
Requires-Dist: pytest>=7.4; extra == "test"
Requires-Dist: pytest-cov>=4.1; extra == "test"
Dynamic: license-file

# pulseboard-tracer (Python)

[![pypi](https://img.shields.io/pypi/v/pulseboard-tracer.svg)](https://pypi.org/project/pulseboard-tracer/)
[![ci](https://github.com/OpenPulseBoard/pulseboard-tracer-python/actions/workflows/ci.yml/badge.svg)](https://github.com/OpenPulseBoard/pulseboard-tracer-python/actions/workflows/ci.yml)
[![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Auto-instrumenting OpenTelemetry tracer for Python, wired for
[PulseBoard](https://pulseboard.cloud). One install, one CLI flag, no code
change.

```bash
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.py
```

Within ~30s your service shows up in the PulseBoard service catalog with
HTTP / DB / cache / queue spans flowing.

---

## What you get

- 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`](https://pypi.org/project/opentelemetry-sdk/) and
[`opentelemetry-distro`](https://pypi.org/project/opentelemetry-distro/). We
do not fork OTel; you get every patch and instrumentation the upstream
community ships.

---

## How it boots

`pulseboard-run python app.py`

1. Translates `PULSE_*` env vars into the matching `OTEL_*` env vars the
   upstream SDK understands.
2. Execs `opentelemetry-instrument python app.py`, which discovers every
   installed `opentelemetry-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:

```bash
# Equivalent to pulseboard-run:
opentelemetry-instrument python app.py

# Or programmatic:
python -c "from pulseboard_tracer import start; start(); ..."
```

---

## Configuration

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.                                    |

### Programmatic use

```python
from pulseboard_tracer import start, shutdown

handle = start(service_name="checkout", sample_ratio=0.1)
try:
    ...
finally:
    shutdown()
```

---

## Acceptance smoke

```bash
PULSE_API_KEY=sk_... PULSE_DEBUG=1 \
    pulseboard-run python examples/smoke.py
```

You should see `[pulseboard-tracer debug] env translated → …` on stderr
and the in-process HTTP span in your PulseBoard tenant.

---

## Scope (this release)

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_instrumentor`
  entry-point machinery
- Env-based detection for AWS Lambda / GCP Cloud Run / k8s downward API
- `pulseboard-run` / `pulseboard-bootstrap` CLI 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

---

## Development

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e ".[test]"
pytest -q
```

CI runs the same suite against Python 3.9 / 3.10 / 3.11 / 3.12.

## License

MIT — see [LICENSE](LICENSE).
