Metadata-Version: 2.5
Name: ko-observability
Version: 0.2.1
Summary: Org-wide OpenTelemetry bootstrap for Python services
Project-URL: Repository, https://github.com/Komus-ai/nexora-observability
Project-URL: Documentation, https://github.com/Komus-ai/nexora-observability/tree/main/docs
Author-email: Komus-ai <dev@cinco.ai>
License: MIT
Keywords: observability,opentelemetry,otlp,structlog
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.12
Requires-Dist: opentelemetry-api>=1.27.0
Requires-Dist: opentelemetry-exporter-otlp-proto-common>=1.27.0
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.27.0
Requires-Dist: opentelemetry-sdk>=1.27.0
Requires-Dist: protobuf<8.0,>=5.0
Requires-Dist: structlog>=24.4.0
Provides-Extra: dev
Requires-Dist: httpx>=0.27.0; extra == 'dev'
Requires-Dist: mypy>=1.13.0; extra == 'dev'
Requires-Dist: opentelemetry-sdk>=1.27.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Provides-Extra: elasticsearch
Requires-Dist: opentelemetry-instrumentation-elasticsearch>=0.48b0; extra == 'elasticsearch'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.115.0; extra == 'fastapi'
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.48b0; extra == 'fastapi'
Provides-Extra: httpx
Requires-Dist: opentelemetry-instrumentation-httpx>=0.48b0; extra == 'httpx'
Provides-Extra: query
Requires-Dist: httpx>=0.27.0; extra == 'query'
Description-Content-Type: text/markdown

# ko-observability (Python)

Org-wide OpenTelemetry bootstrap for Python services: one-call, idempotent
`init_otel` for process startup, lazy `get_tracer` / `get_meter` accessors for library code
that doesn't own process lifecycle, and a structlog processor (`otel_bridge` /
`make_otel_bridge`) that stamps each log line with the active span's `trace_id`/`span_id`.

## Install

```bash
pip install ko-observability
```

Optional extras, install alongside the base package as needed:

```bash
# Auto-instrument FastAPI request/response spans
pip install "ko-observability[fastapi]"

# Auto-instrument outbound httpx calls
pip install "ko-observability[httpx]"

# Auto-instrument the Elasticsearch client
pip install "ko-observability[elasticsearch]"

# Read your own service's telemetry back out (admin-panel style queries)
pip install "ko-observability[query]"
```

## Quick start

```python
from ko_observability import init_otel, get_tracer

init_otel(service_name="my-service", service_namespace="nexora")

tracer = get_tracer(__name__)
with tracer.start_as_current_span("do-work"):
    ...
```

Call `init_otel` exactly once at process startup. It's safe to call again (or to let library
code fall back to `get_tracer`/`get_meter` before it runs) — both paths are no-ops on top of an
already-configured provider. `OTEL_SDK_DISABLED=true` turns the whole thing into a no-op, and a
misconfigured exporter degrades to "telemetry doesn't work" rather than crashing the host process.

### Where does it go?

| `TELEMETRY_DESTINATION` | Output |
|---|---|
| `file` (default) | `$TELEMETRY_FILE_DIR/{traces,metrics,logs}.jsonl` (default `./telemetry`), one OTLP/JSON request per line |
| `otlp` | OTLP/gRPC to `OTEL_EXPORTER_OTLP_ENDPOINT` (default `http://localhost:4317`) |

Full contract: [docs/otel.md → Local file mode](../../docs/otel.md#local-file-mode-the-default).

## Reading telemetry back (`query` extra)

```python
from ko_observability.query import get_query_client

client = get_query_client()
traces = client.list_traces(limit=20)
```

Scoped to the caller's own `service_name` by default. See [`docs/query.md`](../../docs/query.md).

## Docs

Full documentation — env vars, the logs/metrics pipelines, semantic conventions, and the
Collector deployment this SDK ships telemetry to — lives in the repository:

https://github.com/Komus-ai/nexora-observability/tree/main/docs
