需借助外部脚本实现nginx每分钟5xx错误率统计与告警:解析access.log→提取60秒内5xx状态码→按分钟聚合计算占比→超阈值(如5%)触发邮件/webhook等告警。

要在 Nginx 中统计每分钟 5xx 错误率并实现超标自动告警,核心思路是:**解析 Nginx 访问日志 → 实时提取 5xx 状态码 → 按分钟聚合计算错误率 → 达到阈值触发告警**。Nginx 本身不内置该功能,需借助外部脚本(如 Bash/Python)配合日志轮转与定时任务完成。
1. 确保 Nginx 日志格式支持状态码提取
默认 log_format 已包含 $status,但建议显式确认或优化为便于解析的格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time';
确保日志路径明确(如 /var/log/nginx/access.log),且日志未被压缩或归档——实时监控依赖可读的最新日志文件。
2. 编写每分钟统计脚本(以 Bash 为例)
脚本需满足:按分钟窗口滚动统计、计算 5xx 占比、支持阈值判断。以下为轻量可靠实现:
- 用
awk提取最近 60 秒内日志行,过滤出 5xx 状态码(500–599) - 统计总请求数和 5xx 数量,计算错误率(如:5xx 数 / 总数 × 100%)
- 设定阈值(如 5%),超限时调用告警方式(邮件、Webhook、短信网关等)
简易脚本片段(save as /usr/local/bin/check_5xx.sh):
#!/bin/bash
LOG="/var/log/nginx/access.log"
THRESHOLD=5 # 警戒百分比
WINDOW=60 # 统计窗口秒数
<h1>获取最近 WINDOW 秒内的日志行(要求日志时间格式为 "DD/MMM/YYYY:HH:MM:SS")</h1><p>END=$(date -d "now" "+%d/%b/%Y:%H:%M:%S")
START=$(date -d "$END $WINDOW seconds ago" "+%d/%b/%Y:%H:%M:%S")</p><h1>提取该时间段日志,统计总数和 5xx 数</h1><p>TOTAL=$(awk -v start="$START" -v end="$END" '
BEGIN { count=0; bad=0 }
match($4, /[([0-9]{2}\/[A-Za-z]{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2})/, arr) {
ts = arr[1]
if (ts >= start && ts /dev/null | awk '{print $1}')</p><p>BAD=$(awk -v start="$START" -v end="$END" '
BEGIN { count=0; bad=0 }
match($4, /[([0-9]{2}\/[A-Za-z]{3}\/[0-9]{4}:[0-9]{2}:[0-9]{2}:[0-9]{2})/, arr) {
ts = arr[1]
if (ts >= start && ts /dev/null)</p><p>if [[ -z "$TOTAL" || "$TOTAL" = "0" ]]; then exit 0; fi
RATE=$(echo "scale=2; $BAD * 100 / $TOTAL" | bc -l 2>/dev/null)
if (( $(echo "$RATE > $THRESHOLD" | bc -l) )); then
echo "$(date): 5xx rate $RATE% ($BAD/$TOTAL) exceeds $THRESHOLD%" | logger -t nginx_5xx</p><h1>这里添加告警逻辑,例如:</h1><h1>echo "ALERT: 5xx rate $RATE%" | mail -s "Nginx 5xx Alert" admin@example.com</h1><h1>curl -X POST -d "text=5xx rate $RATE%" <a href="https://www.php.cn/link/1ef219209ce95303626829fbf3629889">https://www.php.cn/link/1ef219209ce95303626829fbf3629889</a>
</h1><p>fi
</p>
3. 通过 cron 每分钟执行一次
避免使用 too frequent polling(如每 10 秒),推荐标准每分钟触发一次:
*/1 * * * * /usr/local/bin/check_5xx.sh >/dev/null 2>&1
注意:
– 确保脚本有执行权限:chmod +x /usr/local/bin/check_5xx.sh
– 使用 root 或具备读取日志权限的用户运行 cron
– 若日志启用了 rotate(如 logrotate),需确保脚本能读取当前 active 文件(通常无问题)
4. 告警方式选型与加固建议
生产环境不建议只发邮件,推荐组合方式:
- 基础层:写入 syslog(如上例中的
logger),便于集中采集(如 ELK / Loki) - 通知层:集成企业微信、钉钉 Webhook,或调用短信平台 API
- 抑制机制:添加“5 分钟内重复告警仅发一次”逻辑,避免风暴
- 可观测性延伸:将指标导出为 Prometheus 格式,配合 Grafana 可视化趋势
若需更高精度与稳定性,可改用 Python + tail -f + 时间滑动窗口(如 collections.deque),避免频繁读盘;但对中小流量站点,上述 Bash 方案足够轻量可靠。











