把应用部署到生产环境后,真正的挑战才刚刚开始。程序可能变慢、报错、资源耗尽,如果没有一套监控体系,就只能等用户来告诉你“系统挂了”。这一节讲三件必须做的事:性能监控、日志收集、错误告警。
性能监控
目标:实时掌握应用的健康状况——CPU、内存、请求延迟、吞吐量、错误率等。
常用方案
- 应用级指标暴露
使用 prometheus_client 库在 Python 应用中内置指标端点。例如,记录每个接口的请求数和耗时分位数:
from prometheus_client import Counter, Histogram, generate_latest
REQUEST_COUNT = Counter('http_requests_total', 'Total requests', ['method', 'endpoint'])
REQUEST_DURATION = Histogram('http_request_duration_seconds', 'Request duration', ['method', 'endpoint'])
在 FastAPI/Flask 中暴露 /metrics 接口,Prometheus 定期抓取。
- 系统级监控
部署 Node Exporter(机器指标)、cAdvisor(容器指标),与 Prometheus 配合,可监控整机 CPU、内存、磁盘、网络以及每个容器的资源占用。
- 可视化与告警
Grafana 连接 Prometheus 作为数据源,搭建实时仪表盘,一眼看清 QPS、错误率、延迟分布。结合 Prometheus Alertmanager 设置阈值告警。
- APM 工具(应用性能监控)
对于复杂系统,可引入 Sentry Performance、Elastic APM 或商业方案如 Datadog,自动跟踪请求链路,定位慢查询、慢接口。
实用要点:至少做到“四个黄金指标”——延迟、流量、错误率、饱和度。
日志收集
目标:将分散在各服务器、各容器中的日志集中存储、查询和分析。单靠 tail -f 是不行的。
日志规范
- 结构化输出:使用 JSON 格式,方便检索。例如 Python 中可以用
python-json-logger或自定义 Formatter。 - 关键字段:时间戳、日志级别、模块名、请求 ID(用于串联整个链路)、消息体。
- 避免在日志中输出敏感信息(密码、Token)。
收集架构
- 轻量级方案:应用将日志写到文件或 stdout,用 Filebeat 或 Promtail 采集,写入 Elasticsearch(或 Loki),通过 Kibana(或 Grafana)查询。
- 容器化环境:Docker 或 Kubernetes 默认收集 stdout/stderr,可直接使用 EFK(Elasticsearch + Fluentd + Kibana) 或 PLG(Promtail + Loki + Grafana) 方案。
- 处理管道:Logstash 或 Fluentd 可对日志进行过滤、解析、增强,比如从 user-agent 中提取浏览器信息。
实用要点:日志一定要有“请求链路追踪 ID”,在微服务调用链中,一个 ID 串起所有相关日志,排查问题效率极高。
错误告警
目标:出现异常时,第一时间通知相关人员,而不是靠人工巡检。
异常捕获
- 代码内兜底:用
try/except捕获并记录详细上下文,然后上报。 - 全局未捕获异常:使用
sys.excepthook或 FastAPI 的异常处理器,拦截未预料到的错误。 - 专用工具:Sentry 是最成熟的异常监控平台,几行代码即可接入:
import sentry_sdk
sentry_sdk.init(dsn="你的DSN", traces_sample_rate=1.0)
它会自动捕获未处理异常,收集完整的堆栈、局部变量、请求信息,支持按版本、环境聚合和责任人分发。
告警规则与通知
- 基于监控指标告警:Prometheus Alertmanager 可设置规则,如“5 分钟内错误率 > 5%”则触发告警。
- 基于日志告警:Elasticsearch Watcher 或 Grafana Alerting 检测日志中出现
ERROR或特定关键词的频次。 - 通知渠道:邮件、企业微信、钉钉、Slack、PagerDuty 等,按严重程度分级,避免告警风暴。
实用的告警设计原则
- 可行动性:收到告警必须知道该做什么,否则是噪音。
- 抑制重复:同一问题不要连续发多条告警,使用分组和冷却时间。
- 分级处理:核心业务故障立即通知电话值班,非紧急问题发到频道异步处理。
三者协同
性能监控告诉你“系统变慢了”,日志收集帮你查出“是哪个请求、因为什么原因”,错误告警确保你在用户反馈之前就动手修复。把这三者纳入部署流程,才算真正完成了“从写代码到稳定运行”的闭环。