forked from phoenix-oss/llama-stack-mirror
feat(telemetry): normalize path (#1739)
# What does this PR do? This will prevent 'operations' from being flooded <img width="401" alt="image" src="https://github.com/user-attachments/assets/c95e0eeb-4a10-4003-88df-9bb6d0a548cd" /> Before <img width="1049" alt="image" src="https://github.com/user-attachments/assets/157fb614-e007-4cb3-a571-226e50525bfa" /> ## Test Plan After <img width="811" alt="image" src="https://github.com/user-attachments/assets/b2b10344-1d73-44e5-abee-a9f039090963" />
This commit is contained in:
parent
636d97207f
commit
f76550ce4e
1 changed files with 39 additions and 1 deletions
|
@ -228,13 +228,51 @@ class TracingMiddleware:
|
||||||
async def __call__(self, scope, receive, send):
|
async def __call__(self, scope, receive, send):
|
||||||
if scope.get("type") == "lifespan":
|
if scope.get("type") == "lifespan":
|
||||||
return await self.app(scope, receive, send)
|
return await self.app(scope, receive, send)
|
||||||
|
|
||||||
path = scope.get("path", "")
|
path = scope.get("path", "")
|
||||||
await start_trace(path, {"__location__": "server"})
|
|
||||||
|
# Try to match the path to a route template
|
||||||
|
route_template = self._match_path(path)
|
||||||
|
|
||||||
|
# Use the matched template or original path
|
||||||
|
trace_path = route_template or path
|
||||||
|
|
||||||
|
await start_trace(trace_path, {"__location__": "server", "raw_path": path})
|
||||||
try:
|
try:
|
||||||
return await self.app(scope, receive, send)
|
return await self.app(scope, receive, send)
|
||||||
finally:
|
finally:
|
||||||
await end_trace()
|
await end_trace()
|
||||||
|
|
||||||
|
def _match_path(self, path):
|
||||||
|
"""Match a path to a route template using simple segment matching."""
|
||||||
|
path_segments = path.split("/")
|
||||||
|
|
||||||
|
for route in self.app.app.routes:
|
||||||
|
if not hasattr(route, "path"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
route_path = route.path
|
||||||
|
route_segments = route_path.split("/")
|
||||||
|
|
||||||
|
# Skip if number of segments doesn't match
|
||||||
|
if len(path_segments) != len(route_segments):
|
||||||
|
continue
|
||||||
|
|
||||||
|
matches = True
|
||||||
|
for path_seg, route_seg in zip(path_segments, route_segments, strict=True):
|
||||||
|
# If route segment is a parameter (contains {...}), it matches anything
|
||||||
|
if route_seg.startswith("{") and route_seg.endswith("}"):
|
||||||
|
continue
|
||||||
|
# Otherwise, segments must match exactly
|
||||||
|
elif path_seg != route_seg:
|
||||||
|
matches = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if matches:
|
||||||
|
return route_path
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class ClientVersionMiddleware:
|
class ClientVersionMiddleware:
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue