Uvicorn 本身不提供响应时间监控,需通过 FastAPI 中间件、结构化日志或 Prometheus 实现:中间件记录 X-Process-Time 响应头(仅应用层耗时);Loguru/structlog 记录带耗时的结构化日志(适合生产);Prometheus 提供聚合指标(需 prometheus-fastapi-instrumentator);--log-level debug 仅输出底层事件,无业务耗时且不可定制。

Uvicorn 本身不提供内置的响应时间监控能力,必须通过 FastAPI(或 Starlette)中间件、日志钩子或外部指标采集工具来实现。直接启动 uvicorn 命令时,它只负责 ASGI 生命周期调度,不记录耗时。
用 FastAPI 中间件记录 X-Process-Time 响应头
这是最轻量、最常用的方式,适合开发和初步压测。关键点在于:中间件必须在请求进入路由前开始计时,在响应发出前完成计算,并写入响应头。
-
TimingMiddleware必须继承BaseHTTPMiddleware,不能用普通装饰器替代 - 务必使用
time.time()(非time.perf_counter()),否则在异步嵌套中可能因事件循环切换导致时间偏差 - 响应头键名如
X-Process-Time是约定俗成,但可自定义;注意值必须是字符串,且不含单位 - 该方式无法捕获 Uvicorn 自身的连接建立、TLS 握手、响应体流式发送等环节耗时,仅反映应用层处理时间
import time from fastapi import Request from starlette.middleware.base import BaseHTTPMiddleware <p>class TimingMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) return response</p><p>app.add_middleware(TimingMiddleware)</p>
用 Loguru 或 structlog 记录带耗时的结构化日志
比响应头更进一步,能落地到文件、转发到 ELK 或 Loki,适合生产环境。重点在于日志格式必须包含毫秒级时间戳、路径、状态码和真实耗时。
Uvicorn 0.52.1 是 Python ASGI Web 服务器,提供异步应用服务及 WebSocket 支持,常用于 FastAPI、Starlette 等应用的开发和部署。本下载为官方 PyPI 通用 wheel 包,可使用 pip 安装,并由包管理器处理所需依赖。
- 不要依赖
logging默认模块,它在异步上下文中容易丢日志或阻塞事件循环 -
loguru的patch机制可自动注入elapsed字段,但需配合中间件手动传入起始时间 - 避免在日志中打印完整请求体或响应体(尤其含敏感数据),可用
request.url.path+request.method替代 - 日志级别建议设为
INFO,高频接口下注意磁盘 IO 或网络传输压力
from loguru import logger
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
<p>class LoggingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
logger.info(
"method={method} path={path} status={status} elapsed={elapsed:.3f}s",
method=request.method,
path=request.url.path,
status=response.status_code,
elapsed=process_time,
)
return response</p>
对接 Prometheus + Uvicorn metrics endpoint
需要额外依赖 prometheus-fastapi-instrumentator,适用于已有可观测性基建的团队。Uvicorn 不暴露指标端点,必须由 FastAPI 应用承载。
- 默认指标如
http_request_duration_seconds_bucket是直方图,需配置duration_buckets才能正确分桶(例如[0.01, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0]) - 务必调用
instrumentor.expose(app, include_in_schema=False),否则/metrics路径不会生效 - Uvicorn 启动时若启用
--workers > 1,各进程指标独立,Prometheus 抓取需配置 service discovery 或使用multi-process模式聚合 - 该方案不记录单次请求详情,只提供聚合统计(P90/P99/avg),排查具体慢请求仍需结合日志或链路追踪
为什么不能只靠 Uvicorn 的 --log-level debug?
uvicorn --log-level debug 会输出连接建立、请求解析、响应发送等底层事件,但不包含“从收到完整请求头到发出响应头”的业务耗时。它的时间戳是 Uvicorn 内部事件循环的 tick 时间,与应用逻辑执行无直接对应关系。
- 你会看到类似
127.0.0.1:54321 - "GET /health HTTP/1.1" 200 OK的日志,但没有毫秒级耗时字段 - debug 日志量极大,高频接口下极易淹没真正有用的信号,且无法按路径、状态码聚合分析
- Uvicorn 日志格式不可定制,无法注入 trace_id 或用户标识等上下文信息
真正要定位慢请求,得把中间件计时、结构化日志、Prometheus 分位数、以及分布式追踪(如 OpenTelemetry)这几层结合起来——单独依赖任何一层都会漏掉关键路径。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










