Add kaya-otel package for OpenTelemetry tracing and metrics
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:
2026-09-19 00:39:15 +00:00
parent 69762d93df
commit 148a35b71c
16 changed files with 1182 additions and 1 deletions
+29
View File
@@ -250,3 +250,32 @@ class AsgiTest(unittest.TestCase):
r = await client.put("/restaurants/42/menu")
self.assertEqual(404, r.status_code)
def test_route_template(self):
self.assertEqual('/employee/${employee_id}',
self.app.route_template('/employee/101325', HttpMethod.GET))
self.assertEqual('/square/${x:int}', self.app.route_template('/square/30', HttpMethod.GET))
self.assertIsNone(self.app.route_template('/unknown', HttpMethod.GET))
@async_test
async def test_exception_exposed_to_after_hooks(self):
app = KayaApp()
seen = []
async def after_request(ctx: HttpContext) -> None:
seen.append(ctx.exception)
app.add_after_request_hook(after_request)
@app.GET('/raises')
async def raises(ctx: HttpContext) -> None:
raise RuntimeError('boom')
transport = httpx.ASGITransport(app=app)
async with httpx.AsyncClient(transport=transport, base_url="http://127.0.0.1:80") as client:
with self.assertRaises(RuntimeError):
await client.get('/raises')
self.assertEqual(1, len(seen))
self.assertIsInstance(seen[0], RuntimeError)
self.assertEqual('boom', str(seen[0]))