Nginx日志格式化及分析结合应用实践

一、背景介绍:

        Nginx作为Web架构中流行的代理工具之一,作为网站流量入口, 日志文件包含了大量有价值的信息。我们可以通过分析这些日志,了解网站的实际运行状况、用户行为模式,并及时发现潜在问题。但由于配置格式不统一,不规范,导致日志记录无价值或者分析难度较大。本文将介绍从日志格式配置到深入分析,通过日志对系统的访问情况进行全方位的分析。

二、 Nginx日志格式解析(通用配置一般在nginx.conf,系统自己用的配置集合实际判断)

典型的Nginx访问日志格式如下(可以在nginx.conf中通过log_format指令自定义):

log_format  timed_combined  '$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';

这个 Nginx 日志格式 timed_combined 定义了多个字段,每个字段记录了 HTTP 请求的不同信息。

  • $remote_addr: 客户端的 IP 地址(直接访问服务器的 IP。若使用了代理服务器,字只能获取到代理地址)

  • $remote_user: HTTP 基本认证中的用户名(如果启用认证)

  • $time_local: 服务器本地时间的访问时间戳,格式通常为 [日/月/年:时:分:秒 时区]

  • $request: 客户端请求的原始 HTTP 方法、路径和协议版本。

  • $status: 服务器返回的 HTTP 状态码。

  • $body_bytes_sent: 发送给客户端的响应体字节数(不含响应头)

  • $http_referer: 请求的来源页面 URL(用户从哪个链接跳转过来)

  • $http_user_agent: 客户端的用户代理(浏览器、设备等信息)

  • $http_x_forwarded_for: 此字段记录客户端 IP(获得客户端真实地址)

  • $request_time: 服务器处理请求的总时间(从接收到客户端第一个字节到发送完响应,单位:秒)。

  • $upstream_response_time: 如果请求被代理到上游服务器(如 PHP-FPM、后端服务),此字段记录上游服务器的响应时间(单位:秒)

更改完后,重启Nginx服务,让配置生效。

./nginx -s reload

一条实际的日志记录可能如下所示:tail -f access.log:

10.*.1*.29 - - [30/Apr/2025:09:19:49 +0800] "GET /******/gvfd/byhmuj/tempate.action?cond.syscode=KJ&cond.syscodeid=201682&cond.tablecode=KJ&cond.tableid=1682&cond.syscodeversion=16&winid=IFrame_LEVEL1 HTTP/1.1" 200 90250 "https://****.bgnh/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36" "-" 2.344 2.344

 

三、 常用日志分析(重头戏)

首先进入到log目录下

1、统计某个时间段请求最多的URL

awk '$4 >= "[30/Apr/2025:9:10:00" && $4 < "[30/Apr/2025:09:40:00"' access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -n 20

2、统计今日请求最多的URL

grep $(date +%d/%b/%Y) access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -n 20

3. 找出访问次数最多的10个IP

awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 10

4. 找出某个时间段访问最多的IP

awk '$4 >= "[30/Apr/2025:09:10:00" && $4 < "[30/Apr/2025:09:40:00"' access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10

5、结合grep进行实时筛选,例如只显示200:

tail -f access.log | grep '200'

6、找出响应超过n秒的URL

当我们想找出响应时间超过3秒的请求(需要日志中包含响应时间字段,需要在log_format中添加$request_time):

awk '$NF > 3 {print $7}' access.log | sort | uniq -c | sort -nr | head -5

7、统计每秒的QPS(帮助分析业务流量情况)


awk '{print $4}' access.log | cut -d: -f2-3 | uniq -c

8、精确到每秒QPS统计:

awk '{split($4, a, ":"); print a[2]":"a[3]":"a[4]}' access.log | sort | uniq -c

9、统计特定时间段的QPS变化:

awk '$4 >= "[30/Apr/2025:09:10:00" && $4 < "[30/Apr/2025:09:40:00"' access.log | awk '{split($4, a, ":"); print a[2]":"a[3]":"a[4]}' | sort | uniq -c

10. 实时统计QPS:

tail -f access.log | awk '{
    split($4, time, ":");
    key = time[2] ":" time[3] ":" time[4];
    count[key]++;
    print key, count[key];
}'

、 自动化日志监控方案

异常请求报警脚本nginx_mon.sh

#!/bin/bash
# 监控最近10分钟内404错误率
ng_log=/usr/local/nginx/log/access.log
ERROR_COUNT=$(awk -v d1="$(date --date="-10 min" "+[%d/%b/%Y:%H:%M")" -v d2="$(date "+[%d/%b/%Y:%H:%M")" '$4 >= d1 && $4 <= d2 && $9 == 404' $ng_log | wc -l)
TOTAL_COUNT=$(awk -v d1="$(date --date="-10 min" "+[%d/%b/%Y:%H:%M")" -v d2="$(date "+[%d/%b/%Y:%H:%M")" '$4 >= d1 && $4 <= d2' $ng_log | wc -l)
ERROR_RATE=$(echo "scale=2; $ERROR_COUNT*100/$TOTAL_COUNT" | bc)

if (( $(echo "$ERROR_RATE > 5" | bc -l) )); then
    echo "High error rate detected: $ERROR_RATE%" | mail -s "Nginx Error 404 up 50%!" admin@example.com
fi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值