温馨提示×

怎样利用Nginx日志进行流量监控

小樊
41
2026-01-05 20:32:49
栏目: 编程语言

利用 Nginx 日志进行流量监控

一 核心指标与日志字段

  • 关键字段:
    • $body_bytes_sent:发送给客户端的响应体字节数,是 HTTP 流量统计的核心指标。
    • $request_time / $upstream_response_time:请求总耗时与上游耗时,用于识别慢请求与瓶颈。
    • $status:HTTP 状态码,用于区分成功与异常流量。
    • $remote_addr / $http_x_forwarded_for:客户端 IP,用于来源分析、黑白名单与分维度统计。
  • 建议的日志格式(示例):
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    '$request_time $upstream_response_time '
                    '$upstream_connect_time $upstream_header_time';
    access_log /var/log/nginx/access.log main;
    
    说明:上述字段覆盖“带宽/流量”“时延”“来源”三大类监控需求,便于后续聚合与告警。

二 快速命令行统计

  • 总流量与请求量(按天)
    # 当天总请求数
    wc -l < /var/log/nginx/access.log
    
    # 当天总出站流量(字节)
    awk '{sum+=$10} END {print sum}' /var/log/nginx/access.log
    
    # 换算为 MB
    awk '{sum+=$10} END {printf "%.2f MB\n", sum/1024/1024}' /var/log/nginx/access.log
    
  • 按小时/分钟聚合(滚动窗口)
    # 最近 60 分钟总流量
    awk -v d1="$(date -d '-60 minutes' +'%d/%b/%Y:%H:%M:%S')" \
        -v d2="$(date +'%d/%b/%Y:%H:%M:%S')" \
        '$4 >= "["d1 && $4 <= "["d2 {sum+=$10} END {printf "%.2f MB\n", sum/1024/1024}' \
        /var/log/nginx/access.log
    
    # 按小时汇总当天流量
    awk -F: '{h=$2; sum[h]+=$10} END {for (i in sum) printf "%s: %.2f MB\n", i, sum[i]/1024/1024}' \
        /var/log/nginx/access.log
    
  • 按 URL/域名/状态码/来源 IP 维度
    # Top 10 URL 流量
    awk '{bytes[$7]+=$10} END {for (u in bytes) printf "%.2f MB %s\n", bytes[u]/1024/1024, u}' \
        /var/log/nginx/access.log | sort -nr | head
    
    # 按状态码分布
    awk '{code[$9]++} END {for (c in code) printf "%s: %d\n", c, code[c]}' \
        /var/log/nginx/access.log | sort -nr
    
    # Top 10 来源 IP 流量
    awk '{ip[$1]+=$10} END {for (i in ip) printf "%.2f MB %s\n", ip[i]/1024/1024, i}' \
        /var/log/nginx/access.log | sort -nr | head
    
  • 说明:以上命令以 $body_bytes_sent 作为流量口径;若需“请求量/并发/时延”等,可结合 $status、$request_time、$upstream_response_time 做扩展。

三 可视化与实时监控

  • GoAccess(控制台/HTML 实时报告)
    # 控制台实时
    goaccess /var/log/nginx/access.log --log-format=COMBINED
    
    # 生成 HTML 报告(含带宽/流量)
    goaccess /var/log/nginx/access.log -o /var/www/report.html --log-format=COMBINED
    
    # 实时 HTML(需浏览器自动刷新)
    goaccess /var/log/nginx/access.log \
      --log-format=COMBINED --real-time-html --port=7890 \
      -o /var/www/realtime.html
    
    提示:可结合 –ignore-crawlers 过滤爬虫,或用 –geoip-database 做地域分布。
  • ELK/EFK 体系(集中化与告警)
    • 架构:Filebeat → Logstash → Elasticsearch → Kibana
    • 能力:按 域名/URL/状态码/客户端IP/$request_time 多维聚合与可视化;对异常状态码、爬虫、突发流量设定阈值告警。

四 阈值告警与自动处置

  • 轻量阈值脚本(按小时流量阈值)
    #!/usr/bin/env bash
    LOG=/var/log/nginx/access.log
    LIMIT_MB=1024   # 每小时阈值(MB)
    NOW=$(date +%d/%b/%Y:%H:00:00)
    PREV=$(date -d '1 hour ago' +%d/%b/%Y:%H:00:00)
    
    usage=$(awk -v d1="[$PREV" -v d2="[$NOW" \
             '$4 >= d1 && $4 < d2 {sum+=$10} END {print int(sum/1024/1024)}' "$LOG")
    
    if [ "$usage" -gt "$LIMIT_MB" ]; then
      echo "$(date) 流量告警: 最近1小时 ${usage}MB > ${LIMIT_MB}MB" \
        | mail -s "Nginx 流量告警" admin@example.com
      # 可选:触发限流/封禁
      # iptables -A INPUT -s <IP> -j DROP
    fi
    
  • 进阶联动(超标自动封禁与次日恢复)
    • 思路:解析日志按端口/域名汇总,超过阈值调用 firewalld/iptables 临时封禁,次日定时任务清空封禁列表并恢复端口。
    • 参考实践:基于 TCP/UDP 访问日志 的端口级监控与自动封锁脚本,配合 crontab 每日切割与恢复。

五 日志管理与口径一致性

  • 日志切割与归档
    # 手动切割
    mv /var/log/nginx/access.log /var/log/nginx/access_$(date +%Y%m%d).log
    systemctl reload nginx
    
    # 自动清理 30 天前日志
    find /var/log/nginx -name "*.log" -mtime +30 -exec gzip {} \;
    
  • 口径说明
    • 仅统计 HTTP 响应体字节数($body_bytes_sent),不包含 HTTP 头TCP/IP 头开销;若需“网卡层”吞吐,请结合系统/网卡监控。
    • 启用 $request_time / $upstream_response_time 才能做时延与慢请求分析。
    • 使用 $http_x_forwarded_for 时,注意可信代理与真实来源判定,避免统计偏差。

0