问题出现得很突然,日志倒是留得挺全。一次上游限流让 429 占满日志的 92%,值班按错误数排序只看到 429,实际 500 只有 30 条,等发现时连接池耗尽的报错已经滚出了保留窗口。
刚开始盯着「日志保留期短,被限流日志挤掉」,折腾了半个多小时,排掉了。
这类报错背后常见的原因有几处,逐个排除就行。错误统计只按总数排序,不区分状态码族。还有一种是告警阈值被大量 429 提前打满,5xx 反而没触发。
不容易想到的是,采集端对同一错误做了聚合,明细被合并。
上来先按状态码分组统计条数
python agg.py --log app.log --field status --group 1
给 5xx 单独设一条告警规则
python -c "print('alert on 5xx > 5 per min')"
429 改成只留计数与低比例采样
python -c "print({'sample_rate':0.01,'counter':True})"
延长 5xx 日志的保留天数
python -c "print('retain_days=14')"
怎么算真的好了,看的是同一批现象。5xx 从出现到告警小于 2 分钟,429 在日志里的占比被压到 10% 以下,5xx 记录在保留期内可查。
提醒一点。限流本身不算故障,但它会淹没真正的故障,把日志按状态码分流比反复调告警阈值有效。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
