Add kaya-otel package for OpenTelemetry tracing and metrics
CI / Build Pip package (push) Successful in 4m8s
CI / Build Pip package (push) Successful in 4m8s
Instrument HTTP requests and WebSocket connections via Kaya hooks, covering both ASGI and RSGI. Records handler exceptions, WebSocket close codes, optional header capture, exclusions and lifecycle hooks. Add route-template resolution and exception visibility to kaya-core so trace/metric attributes can use low-cardinality routes and failed spans can record escaped exceptions.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user