diff --git a/python/sglang/srt/utils/common.py b/python/sglang/srt/utils/common.py index 38f593ba9..dc1df393e 100644 --- a/python/sglang/srt/utils/common.py +++ b/python/sglang/srt/utils/common.py @@ -1493,7 +1493,13 @@ def add_prometheus_middleware(app): def add_prometheus_track_response_middleware(app): from prometheus_client import Counter - http_response_status_counter = Counter( + http_request_counter = Counter( + name="sglang:http_requests_total", + documentation="Total number of HTTP requests by endpoint and method", + labelnames=["endpoint", "method"], + ) + + http_response_counter = Counter( name="sglang:http_responses_total", documentation="Total number of HTTP responses by endpoint and status code", labelnames=["endpoint", "status_code", "method"], @@ -1501,24 +1507,36 @@ def add_prometheus_track_response_middleware(app): @app.middleware("http") async def track_http_status_code(request, call_next): + # With recording all requests, we have the risk of high cardinality if requests have arbitrary unhandled paths. + # But given that SGLang engines with metrics enabled are usually behind routers this looks safe. + path, is_handled_path = _get_fastapi_request_path(request) + method = request.method + + http_request_counter.labels(endpoint=path, method=method).inc() + response = await call_next(request) - route = request.scope.get("route") - endpoint = ( - route.path - if route - else ("unknown_route" if response.status_code == 404 else request.url.path) - ) - - http_response_status_counter.labels( - endpoint=endpoint, + http_response_counter.labels( + endpoint=path, + method=method, status_code=str(response.status_code), - method=request.method, ).inc() return response +# https://github.com/blueswen/fastapi-observability/blob/132a3c576f8b09e5311c68bd553215013bc75685/fastapi_app/utils.py#L98 +def _get_fastapi_request_path(request) -> Tuple[str, bool]: + from starlette.routing import Match + + for route in request.app.routes: + match, child_scope = route.matches(request.scope) + if match == Match.FULL: + return route.path, True + + return request.url.path, False + + def bind_port(port): """Bind to a specific port, assuming it's available.""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)