可观测性 / 已完成

生产环境日志、监控和告警

理解日志、指标、链路追踪、request_id、P95、慢查询和告警设计。

返回文章积累

一句话:日志、监控和告警就是给线上系统装上仪表盘和报警器,让你知道系统现在是不是健康,出问题时能快速找到原因。

本篇学完你会什么:知道线上系统应该看哪些指标、日志怎么打才有用、告警怎么设才不吵,以及一次接口变慢时应该按什么顺序排查。

1. 为什么上线后不能只看“服务还在”

本地开发时,你看到接口能返回,就会觉得它没问题。

上线后不一样。真实用户会同时访问,数据库会变大,网络会抖,第三方服务会超时。

一个服务“还活着”不代表它“好用”:

状态用户感受系统可能发生了什么
接口能返回正常服务健康
接口很慢卡顿数据库慢、外部接口慢、连接池不够
偶尔 500不稳定某些输入没处理、依赖偶发失败
大量 401/403不能用token 过期、权限配置错
CPU 很高页面转圈死循环、大查询、并发太高

所以线上系统至少要有三样东西:

日志:发生了什么事
监控:现在状态怎么样
告警:什么时候需要人处理

2. 日志、指标、链路追踪分别是什么

日志

日志像系统日记,记录某一刻发生了什么。

例子:

2026-06-30 10:20:31 INFO user login success user_id=12 request_id=abc123
2026-06-30 10:20:35 ERROR create order failed user_id=12 error=payment timeout request_id=abc123

日志适合回答:

刚才发生了什么?
哪个用户触发的?
报错堆栈是什么?
请求 id 是多少?

指标

指标像仪表盘,持续显示系统状态。

常见指标:

指标含义
QPS每秒有多少请求
P95 响应时间95% 的请求在多久内完成
错误率失败请求占比
CPU / 内存服务器资源是否紧张
数据库连接数连接池是否快被用完

链路追踪

链路追踪用来回答:

一个请求从前端到后端,再到数据库、Redis、第三方接口,中间每一步花了多久?

小项目可以先不接复杂 tracing,但至少要有 request_id。它能把同一次请求的多条日志串起来。

3. FastAPI 项目日志怎么打

日志不是越多越好,而是要能帮你排查问题。

建议每次请求都带上:

字段作用
request_id把同一次请求串起来
methodGET、POST、PUT、DELETE
path请求路径
status_code响应状态码
duration_ms花了多久
user_id当前用户,没有就为空
error错误类型和消息

一个简单中间件示例:

import time
import uuid
import logging

from fastapi import Request

logger = logging.getLogger("app.request")


async def request_log_middleware(request: Request, call_next):
    request_id = request.headers.get("X-Request-Id") or str(uuid.uuid4())
    start = time.perf_counter()

    try:
        response = await call_next(request)
    except Exception:
        duration_ms = round((time.perf_counter() - start) * 1000, 2)
        logger.exception(
            "request failed",
            extra={
                "request_id": request_id,
                "method": request.method,
                "path": request.url.path,
                "duration_ms": duration_ms,
            },
        )
        raise

    duration_ms = round((time.perf_counter() - start) * 1000, 2)
    logger.info(
        "request finished",
        extra={
            "request_id": request_id,
            "method": request.method,
            "path": request.url.path,
            "status_code": response.status_code,
            "duration_ms": duration_ms,
        },
    )
    response.headers["X-Request-Id"] = request_id
    return response

还要把它注册到 FastAPI 应用里:

app.middleware("http")(request_log_middleware)

注意:extra={...} 里的字段不会自动出现在所有日志格式里。真实项目要配合 JSON logger,或者在 logging formatter 里明确输出 request_idpathduration_ms 这些字段。不然代码写了,日志平台里还是看不到。

大白话:每个请求都给一张小票。以后用户说“刚才失败了”,你可以用小票号找到完整过程。

4. 监控应该先看哪些指标

初学者不要一上来做几十个图。先看最能说明问题的 8 个:

指标为什么重要
请求量 QPS判断流量有没有突然变大
P95 响应时间判断大部分用户是否卡
5xx 错误率判断服务是否异常
4xx 比例判断参数、鉴权、权限问题是否变多
CPU判断计算资源是否紧张
内存判断是否有泄漏或缓存过大
数据库慢查询判断瓶颈是否在 SQL
Redis 命中率判断缓存是否有效

推荐先按页面或接口分组:

/api/v1/auth/login
/api/v1/users
/api/v1/knowledge/search

不要只看全站平均值。平均值很容易把某个接口的慢问题藏起来。

5. 告警怎么设才有用

告警的目标不是“声音越大越专业”,而是让人及时处理真正的问题。

好的告警应该有:

内容示例
触发条件5xx 错误率 5 分钟内超过 2%
影响范围/api/v1/orders 接口
当前数值当前错误率 8.5%
排查入口日志查询链接、监控面板链接
处理建议先看最近发布、数据库、第三方接口

不建议这样设:

只要出现一次 500 就告警
CPU 超过 60% 就告警
接口超过 500ms 就告警

这些阈值不是一定错,而是太容易脱离业务基线。比如有的后台报表接口 2 秒也能接受,有的登录接口 500ms 就已经偏慢。告警最好先看一段时间正常数据,再定阈值。

更实用的方式:

场景告警建议
服务不可用1-2 分钟连续健康检查失败
错误率升高5 分钟内 5xx 超过阈值
响应变慢P95 连续 10 分钟超过阈值
数据库异常连接池耗尽或慢查询明显增多
磁盘风险磁盘使用率超过 80%

6. 一次接口变慢怎么排查

假设用户反馈:

用户列表页面今天很慢

不要第一反应就改代码。按顺序看:

  1. 看监控:是不是只有 /users 慢,还是所有接口都慢。
  2. 看流量:请求量有没有突然变大。
  3. 看错误率:慢的同时有没有 500。
  4. 看日志:找慢请求的 request_id
  5. 看 SQL:有没有慢查询,分页是否失效。
  6. 看依赖:Redis、数据库、第三方服务是否异常。
  7. 看发布:最近有没有上线新版本。

常见结论:

现象可能原因下一步
只有一个列表接口慢SQL、分页、N+1 查询看慢 SQL 和 ORM 加载
所有接口都慢CPU、数据库、网络看机器和依赖
登录接口慢密码 hash、数据库、限流看 auth 日志
RAG 检索慢向量库、embedding、top_k 太大看检索耗时

7. 常见错误

错误后果修正
只打印 print()线上难收集、难过滤使用 logging
日志没有 request_id多条日志串不起来每次请求生成 request_id
只看平均响应时间慢接口被平均值盖住看 P95/P99
告警太敏感大家疲劳,不再处理设置持续时间和阈值
日志里打印密码/token安全风险敏感字段脱敏
没有慢查询记录数据库问题难定位开启慢查询日志或埋点

8. 检查清单

[ ] 每个请求有 request_id
[ ] 日志包含 method、path、status_code、duration_ms
[ ] 错误日志包含堆栈
[ ] 日志不打印密码、token、密钥
[ ] 有健康检查
[ ] 有 QPS、响应时间、错误率监控
[ ] 能看到数据库慢查询
[ ] 告警有阈值、持续时间、排查入口

9. 小结

名词大白话
日志系统日记
指标系统仪表盘
告警系统报警器
request_id一次请求的小票号
P95大部分用户真实感受到的速度
慢查询数据库里拖慢接口的 SQL

上一篇建议:先看《FastAPI 项目配置、多环境和部署上线》,知道服务怎么上线。

下一篇建议:继续看《CI/CD、发布和回滚》,把上线流程变得可重复。