如何解析 Nginx 日志(提取字段做分析)?

解析 Nginx 访问日志的方法:awk/grep 命令行快速分析、Python 脚本批量处理、日志平台自动解析。本文对比各种方案及常用分析命令。

最佳实践
如何解析 Nginx 日志(提取字段做分析)?封面

Nginx 访问日志默认是 Combined 格式(IP、时间、请求、状态码、大小、Referer、User-Agent)。快速排查用 awk/grep,批量分析用脚本,生产环境建议用日志平台自动解析。

日志格式示例

192.168.1.1 - - [15/Jan/2024:10:30:45 +0800] "GET /api/users HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0 ..."

命令行快速分析

# 统计访问量 TOP 10 的 IP
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# 统计各状态码数量
awk '{print $9}' access.log | sort | uniq -c | sort -rn

# 统计访问量 TOP 10 的 URL
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -10

# 查看所有 5xx 错误
awk '$9 >= 500 && $9 < 600 {print $1, $7, $9}' access.log

# 统计每秒请求量(QPS 趋势)
awk '{print substr($4, 2), $5}' access.log | sort | uniq -c

Python 脚本解析

import re

pattern = re.compile(
    r'(\S+) \S+ \S+ \[([^\]]+)\] "(\S+) (\S+) \S+" (\d+) (\d+) "([^"]*)" "([^"]*)"'
)

with open('/var/log/nginx/access.log') as f:
    for line in f:
        m = pattern.match(line)
        if m:
            ip, time_str, method, url, status, size, referer, ua = m.groups()
            print(f"{ip} {method} {url} -> {status}")

自定义日志格式

如果 Nginx 配置了自定义 log_format(如加入 $request_time、$upstream_response_time),解析时需要对应调整字段位置或正则。使用 DataKit 时同样应检查日志采集配置中的 Pipeline,拿修改格式后的原始记录测试:只有 log_format 实际输出的耗时字段才能被解析,默认 Combined 日志不会因此多出 request_time。

常见问题(FAQ)

Q:如何分析某个时间段内的日志?
A:应把时间字段按 %d/%b/%Y:%H:%M:%S %z 解析成带时区时间,再比较 开始 <= 时间 < 结束。awk 的起止匹配范围依赖边界行恰好存在,不是可靠的时间范围筛选。

Q:日志文件很大(GB 级)怎么快速处理?
A:先用 grep 缩小范围再交给 awk;或按时间切割日志文件后分别处理。

Q:request_time 和 upstream_response_time 有什么区别?
A:request_time 是完整请求处理时间(含客户端传输),upstream_response_time 只是后端服务的响应时间。两者差值不能单独证明瓶颈;还可能涉及缓冲、重试、排队和多 upstream 值,应结合各阶段指标与请求记录。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台