Nginx 通过自定义 log_format 将 $status 置为独立首字段(如用 | 分隔),可高效支持离线统计;需在 access_log 中启用该格式,配合 awk 等工具按状态码快速分析,并建议结合 logrotate 与定时任务实现自动化趋势追踪。

在 Nginx 中,通过自定义 log_format 并结合 $status 变量,可以将访问日志按 HTTP 状态码结构化输出,为后续离线统计(如用 awk、grep、Python 或 ELK 分析)提供清晰的数据基础。关键在于让状态码成为独立、易提取的字段,避免嵌套或拼接干扰解析。
定义含独立 status 字段的日志格式
Nginx 默认的 combined 日志不保证 $status 位置固定,直接使用不利于脚本批量提取。应显式将其作为独立字段放在开头或固定分隔位置:
log_format status_split '$status | $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';说明:
• 使用 | 作分隔符(也可用 \t 或 ||),确保 $status 是首字段,便于 awk '{print $1}' 直接取值
• 保留原始字段满足审计需求,但把 $status 单独前置,提升可解析性
• 注意:$status 输出的是纯数字(如 200、404、502),无需额外清洗
在 server 或 location 块中启用该格式
仅定义格式不生效,需绑定到 access_log 指令:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">access_log /var/log/nginx/example.status.log status_split;
# 其他配置...}
建议:
• 为状态码分析单独建日志文件(如 .status.log),避免与常规日志混杂
• 若需同时保留原始日志,可添加第二行:access_log /var/log/nginx/access.log combined;
• 修改后执行 nginx -t && nginx -s reload 生效
离线统计常用命令示例
日志按行记录,每行以状态码开头,适合流式处理:
-
统计各状态码出现次数:
awk '{count[$1]++} END {for (c in count) print c, count[c]}' /var/log/nginx/example.status.log | sort -n -
提取 5xx 错误详情(含 URL 和时间):
awk '$1 ~ /^5[0-9]{2}$/ {print $0}' /var/log/nginx/example.status.log -
按小时统计 404 请求量:
awk '$1 == "404" {gsub(/\[/, "", $4); print substr($4, 1, 13)}' /var/log/nginx/example.status.log | sort | uniq -c
提示:若日志量大,可先用 zcat 处理压缩归档,或用 goaccess、lnav 等工具做交互式分析
进阶:配合 logrotate 与定时任务自动化
真实场景中需持续采集与聚合:
- 配置
/etc/logrotate.d/nginx,对*.status.log启用 daily + compress,避免磁盘占满 - 写简单 shell 脚本(如
daily_status.sh),每日凌晨运行 awk 统计并追加到/var/log/nginx/status_daily.csv - 用 crontab 定时触发:
0 2 * * * /path/to/daily_status.sh
这样就能积累历史趋势数据,支撑容量规划或故障复盘

















