- Add a uv workspace at the repository root covering all packages/kaya-* members - Replace pip-compile requirements files with a committed uv.lock - Remove redundant per-package dev extras - Build and publish artifacts with uv build and uv publish in CI - Update the README with uv sync/run/build commands
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
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 theservice.nameresource attribute.endpoint: base URL of an OTLP/HTTP collector; the signal paths/v1/tracesand/v1/metricsare appended. WhenNone, the exporters use their own defaults, including the standardOTEL_EXPORTER_OTLP_ENDPOINTenvironment variable.headers: extra HTTP headers sent to the collector (e.g. authentication).metric_export_interval_millis: metric export interval (default60000).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 withservice.namewhen 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 ashttp.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 asREDACTED(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: whenTrue, metrics use rawurl.pathattributes (legacy, potentially high cardinality). The defaultFalsekeeps metrics low-cardinality by usinghttp.routewhen 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 as1002,1003and1007-1011.
Behavior
- Every HTTP request gets a
SERVERspan 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>andhttp.routeis set. The response status code is recorded ashttp.response.status_codewhen 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, carrying
the applicable standard attributes:
url.scheme,url.path,url.query,network.protocol.name(websocket),network.transport,client.address/client.portandserver.address/server.port. The close code is recorded askaya.websocket.close_code; exceptions and configured error close codes mark the span as failed and seterror.type(the exception class name, or the close code). - W3C
traceparent/tracestateheaders on incoming requests are honored, so traces propagate from upstream services. - Metrics:
http.server.request.duration(histogram, seconds), withhttp.request.method,http.routewhen known andhttp.response.status_codeattributes.http.server.active_requests(up-down counter), withhttp.request.methodattributes.
OTelMixin is a KayaMixin, so the app stays a KayaApp and both ASGI and
RSGI keep working.