flask中before_request不能单独统计完整接口耗时,必须配对after_request或使用teardown_request;推荐用time.perf_counter()记录起始时间存入g,teardown_request中计算差值并异步上报指标。

Flask before_request 不能直接统计完整接口耗时
因为 before_request 只在请求进入视图前触发,拿不到响应生成后的时间点。想靠它单独完成耗时统计,会漏掉视图函数执行、模板渲染、响应序列化等关键阶段——实际测出来经常比真实耗时少 20–80ms。
真正可行的做法是配对使用 before_request 和 after_request,或者改用 teardown_request(它保证执行,即使视图抛异常)。
-
before_request记录起始时间戳,存进g或request上下文 - 必须用
after_request或teardown_request读取结束时间并计算差值 - 别在
before_request里 print 或打日志——此时响应还没生成,日志可能被缓冲或丢失
用 g 存时间戳 + teardown_request 算耗时最稳妥
teardown_request 在每次请求生命周期结束时调用,无论成功或出错都会执行,比 after_request 更可靠。配合 Flask 的 g 对象,可以安全跨函数传递数据。
from flask import Flask, g, request
import time
<p>app = Flask(<strong>name</strong>)</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill8393" title="Forge — Python Developer"><img
src="https://img.php.cn/upload/skill/000/000/081/179203503734063.jpg" alt="Forge — Python Developer" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill8393" title="Forge — Python Developer" class="overflowclass">Forge — Python Developer</a>
<p class="overflowclass">Python开发助手 — 自动化脚本、API封装、命令行工具、数据管道、网页爬虫。经过测试的代码,包含错误处理和文档。当你需要...</p>
</div>
<a rel="nofollow" href="/xiazai/skill8393" title="Forge — Python Developer" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><p>@app.before_request
def before():
g.start_time = time.time()</p><p>@app.teardown_request
def teardown(exception):
if hasattr(g, 'start_time'):
duration = time.time() - g.start_time</p><h1>注意:这里不能 return response,只能打日志或发指标</h1><pre class="brush:php;toolbar:false;"><code> app.logger.info(f"{request.endpoint} took {duration:.3f}s")</code>
- 不要在
teardown_request中修改response,它不接收也不返回响应对象 - 如果需要记录到外部系统(如 Prometheus),建议用异步方式或队列,避免阻塞请求链路
-
exception参数非空说明视图出错了,可据此区分成功/失败耗时
为什么不用 time.perf_counter()?
用 time.time() 足够,但更推荐 time.perf_counter():它不受系统时间调整影响,单调递增,精度更高(纳秒级),特别适合测量短耗时。
- 替换
time.time()→time.perf_counter()即可,其余逻辑不变 - 注意单位:
perf_counter()返回浮点秒,差值仍是秒,无需额外换算 - 某些旧版 Python(=3.6,可放心用
生产环境要避开日志 I/O 成为瓶颈
每请求都打日志,尤其用 app.logger.info 写文件,在高并发下会拖慢整个应用。真实项目中,耗时统计应走轻量通道。
- 优先写入内存计数器(如
statsd客户端、prometheus_client的 Histogram) - 采样上报:比如只记录 P95 以上或错误请求的耗时,
if duration > 0.5 or exception: - 避免在
teardown_request中做 JSON 序列化、网络调用等重操作
中间件本身不该成为性能热点——这点容易被忽略,等 QPS 上千才暴露出来。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










