diff --git a/docs/references/production_request_trace.md b/docs/references/production_request_trace.md index 928e5fd3fc8..3b2f6e25364 100644 --- a/docs/references/production_request_trace.md +++ b/docs/references/production_request_trace.md @@ -12,7 +12,7 @@ This section explains how to configure the request tracing and export the trace pip install -e "python[tracing]" # or manually install the dependencies using pip - pip install opentelemetry-sdk opentelemetry-api opentelemetry-exporter-otlp opentelemetry-exporter-otlp-proto-grpc + pip install opentelemetry-sdk opentelemetry-api opentelemetry-exporter-otlp opentelemetry-exporter-otlp-proto-grpc opentelemetry-instrumentation-fastapi ``` 2. launch opentelemetry collector and jaeger diff --git a/python/pyproject.toml b/python/pyproject.toml index d6480ebb6b9..9b2248176a8 100755 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -88,6 +88,7 @@ tracing = [ "opentelemetry-api", "opentelemetry-exporter-otlp", "opentelemetry-exporter-otlp-proto-grpc", + "opentelemetry-instrumentation-fastapi", ] all = ["sglang[test]", "sglang[decord]"] blackwell = ["sglang[test]", "sglang[decord]"] diff --git a/python/sglang/srt/entrypoints/http_server.py b/python/sglang/srt/entrypoints/http_server.py index ea0d9799b1d..f47e4e22c8f 100644 --- a/python/sglang/srt/entrypoints/http_server.py +++ b/python/sglang/srt/entrypoints/http_server.py @@ -29,7 +29,11 @@ from http import HTTPStatus from typing import Any, AsyncIterator, Callable, Dict, List, Optional, Union -from sglang.srt.tracing.trace import process_tracing_init, trace_set_thread_info +from sglang.srt.tracing.trace import ( + instrument_fastapi, + process_tracing_init, + trace_set_thread_info, +) # Fix a bug of Python threading setattr(threading, "_register_atexit", lambda *args, **kwargs: None) @@ -1183,6 +1187,9 @@ async def vertex_generate(vertex_req: VertexGenerateReqInput, raw_request: Reque return ORJSONResponse({"predictions": ret}) +instrument_fastapi(app) + + def _update_weight_version_if_provided(weight_version: Optional[str]) -> None: """Update weight version if provided.""" if weight_version is not None: diff --git a/python/sglang/srt/tracing/trace.py b/python/sglang/srt/tracing/trace.py index b4ccbfa9f2f..e2b2a70bbd1 100644 --- a/python/sglang/srt/tracing/trace.py +++ b/python/sglang/srt/tracing/trace.py @@ -25,6 +25,8 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional +from fastapi import FastAPI + logger = logging.getLogger(__name__) opentelemetry_imported = False tracing_enabled = False @@ -32,6 +34,7 @@ try: from opentelemetry import context, propagate, trace from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter + from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor from opentelemetry.sdk.resources import SERVICE_NAME, Resource from opentelemetry.sdk.trace import TracerProvider, id_generator from opentelemetry.sdk.trace.export import BatchSpanProcessor @@ -550,3 +553,10 @@ def trace_slice_add_attr(rid: str, attrs: Dict[str, Any]): slice_info = thread_context.cur_slice_stack[-1] slice_info.span.set_attributes(attrs) + + +def instrument_fastapi(app: FastAPI): + if not opentelemetry_imported: + return + + FastAPIInstrumentor.instrument_app(app)