Metadata-Version: 2.4
Name: kaya-otel
Version: 0.0.4
Summary: OpenTelemetry tracing and metrics for the Kaya lightweight ASGI web framework
Author-email: Walter Oggioni <oggioni.walter@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/woggioni/kaya
Project-URL: Bug Tracker, https://github.com/woggioni/kaya/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Topic :: Utilities
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Developers
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: kaya-core
Requires-Dist: opentelemetry-sdk
Requires-Dist: opentelemetry-exporter-otlp-proto-http
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: ipdb; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: httpx; extra == "dev"
Requires-Dist: httpx-ws; extra == "dev"
Requires-Dist: kaya-rsgi; extra == "dev"

# kaya-otel

OpenTelemetry tracing and metrics for the Kaya web framework.

Provides `OTelMixin`, a `KayaMixin` that instruments HTTP requests and
WebSocket connections with OpenTelemetry spans and exports HTTP server
metrics, shipping everything to an OTLP/HTTP collector.

## Usage

```python
from kaya.core import KayaApp, HttpContext
from kaya.otel import OTelMixin

app = KayaApp(mixins=[
    OTelMixin(
        service_name='my-service',
        endpoint='http://localhost:4318',
    )
])

@app.GET('/')
async def home(ctx: HttpContext):
    await ctx.send_str(200, 'Hello World!')
```

## Parameters

- `service_name`: value of the `service.name` resource attribute.
- `endpoint`: base URL of an OTLP/HTTP collector; the signal paths
  `/v1/traces` and `/v1/metrics` are appended. When `None`, the exporters
  use their own defaults, including the standard
  `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable.
- `headers`: extra HTTP headers sent to the collector (e.g. authentication).
- `metric_export_interval_millis`: metric export interval
  (default `60000`).
- `tracer_provider` / `meter_provider`: inject custom providers (e.g. with
  in-memory exporters for tests) instead of the OTLP defaults. The mixin
  only shuts down providers it created itself.
- `resource_attributes`: extra resource attributes merged with
  `service.name` when the mixin creates the providers.
- `excluded_paths` / `excluded_path_regexes`: skip tracing and metrics for
  matching paths (useful for health checks and metrics endpoints).
- `capture_request_headers` / `capture_response_headers`: opt-in HTTP header
  capture as `http.request.header.<name>` / `http.response.header.<name>`
  span attributes. Header names are normalized to lowercase with `-`
  replaced by `_`; values are captured as string lists.
- `sanitize_headers`: headers captured as `REDACTED` (default:
  `authorization`, `proxy-authorization`, `cookie`, `set-cookie`).
- `server_request_hook` / `server_response_hook` / `websocket_connect_hook` /
  `websocket_close_hook`: optional synchronous callbacks invoked with the
  span and the Kaya context/websocket at the corresponding lifecycle point.
  Hook exceptions are logged and do not fail the request.
- `metrics_include_raw_path`: when `True`, metrics use raw `url.path`
  attributes (legacy, potentially high cardinality). The default `False`
  keeps metrics low-cardinality by using `http.route` when Kaya can resolve
  a route template.
- `websocket_error_close_codes`: close codes that mark a websocket span as
  failed. Defaults to protocol/application error codes such as `1002`,
  `1003` and `1007`-`1011`.

## Behavior

- Every HTTP request gets a `SERVER` span named `<METHOD> <path>` with the
  usual HTTP semantic attributes (`http.request.method`, `url.path`,
  `client.address`, `server.address`, ...). When Kaya resolves a route
  template, the span name is updated to `<METHOD> <route template>` and
  `http.route` is set. The response status code is recorded as
  `http.response.status_code` when the handler sends the response; 5xx
  statuses mark the span as failed. Exceptions escaping the handler are
  recorded on the span and also mark it as failed.
- Every WebSocket connection gets one span for its whole lifetime. The close
  code is recorded as `kaya.websocket.close_code`; exceptions and configured
  error close codes mark the span as failed.
- W3C `traceparent`/`tracestate` headers on incoming requests are honored,
  so traces propagate from upstream services.
- Metrics:
  - `http.server.request.duration` (histogram, seconds), with
    `http.request.method`, `http.route` when known and
    `http.response.status_code` attributes.
  - `http.server.active_requests` (up-down counter), with
    `http.request.method` attributes.

`OTelMixin` is a `KayaMixin`, so the app stays a `KayaApp` and both ASGI and
RSGI keep working.
