通过仅发送关键数据降低 FastAPI 中 Sentry APM 成本
抱歉,我需要您提供要翻译的具体文本内容(文章正文),才能为您完成翻译。请把文章的文字粘贴在这里,我会保持原有的格式和代码块不变,只翻译正文部分。
默认 APM 的真正问题
默认情况下,Sentry APM 非常慷慨:
- 每个请求都会成为一个事务
- 即使是子秒级的成功调用也会被记录
- 文档和 schema 端点也会被追踪
对于高流量 API,这很快会变成:
- 大量事务
- 更快的配额耗尽
- 为噪音付费,而不是洞察
实际上,我只需要关注:
- 失败的请求(5xx)
- 运行缓慢的请求
- 任何异常或有风险的情况
其他的都只是背景噪音。
成本节约策略
始终发送至 Sentry
- 任何返回 5xx 的请求
- 任何耗时超过 5 秒 的请求
从 Sentry 中剔除
- 快速的
GET / POST / PUT请求 - 在 3 秒 内成功完成的请求
/docs和/openapi.json端点
这使 Sentry 专注于问题,而不是流量量。
Source:
为什么需要两个中间件
SentryAsgiMiddleware – 启用 APM
SentryAsgiMiddleware 实际上会:
- 启动并结束 Sentry 事务
- 挂钩到 ASGI 请求生命周期
- 将性能数据发送到 Sentry
如果没有这个中间件:
- 不会创建事务
before_send_transaction永远不会被调用- APM 根本无法工作
简而言之: 没有 SentryAsgiMiddleware = 没有 APM
TimingMiddleware – 添加智能
第二个中间件是自定义的。它测量每个请求的真实执行时间,并将其附加到 Sentry scope。
class TimingMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
start_time = time.time()
response = await call_next(request)
duration = time.time() - start_time
with sentry_sdk.configure_scope() as scope:
scope.set_extra("duration", duration)
return response
需要它的原因:
- 执行时间是判断请求是否“重要”的依据
- Sentry 内部的计时信息不易用于过滤
- 没有它,成本控制逻辑只能靠猜测
可以这样理解:
SentryAsgiMiddleware是管道TimingMiddleware是大脑
在发送事务之前过滤事务
Sentry 提供了一个名为 before_send_transaction 的钩子。它在事务发送到 Sentry 之前运行,允许你丢弃该事务。
def before_send_transaction(event, hint):
transaction_name = event.get("transaction", "")
request_method = event.get("request", {}).get("method", "")
status_code = event.get("contexts", {}).get("response", {}).get("status_code", 0)
duration = event.get("extra", {}).get("duration")
# Ignore docs and schema
if "/docs" in transaction_name or "/openapi.json" in transaction_name:
return None
# Always send server errors
if status_code >= 500:
return event
# Drop fast successful requests
if (
request_method in ["GET", "POST", "PUT"]
and 200 <= status_code < 400
and duration
and duration < 3
):
return None
return event
- 返回
event→ 事务将被发送 - 返回
None→ 事务将被丢弃
简单、可预测,且完全由你掌控。
初始化 Sentry 并自定义过滤
sentry_sdk.init(
dsn="SENTRY_DSN",
send_default_pii=True,
traces_sample_rate=1.0,
before_send_transaction=before_send_transaction,
)
而不是依赖随机抽样,这种方法基于真实行为提供确定性的过滤。
变更内容
成本降低
交易量急剧下降,Sentry 使用量立即放慢。
更简洁的仪表盘
仅显示慢速或失败的请求,使调试更容易。
更好的信号
Sentry 中的每一次交易现在都意味着 “值得关注”。
当这种方法有意义时
- 您的 API 流量很大
- 大多数请求成功且快速
- 您更关注问题而非原始指标
如果您希望每个请求永远被追踪,这种方法并不适合。如果您想在不浪费金钱的情况下获得有用的可观测性,这正是合适的选择。
最终思考
APM 应该帮助你发现问题,而不是在计费仪表板中制造新问题。
通过组合:
SentryAsgiMiddleware- 一个简单的计时中间件
before_send_transaction
你将 Sentry 从 “collect everything” 转变为 “collect what actually matters.” 这一小小的改变在真实的生产系统中会产生巨大的差异。