nginx 不支持按错误等级自动分流日志到不同文件,仅能通过 syslog 路由或 logrotate + 脚本后处理实现间接分级;其 error_log 为阈值控制,非过滤器,设 warn 则 warn 及更高级别均记录。

Nginx 本身不支持按错误等级(如 emerg、alert、crit、error、warn、notice、info、debug)将日志自动分流到不同文件。它的 error_log 指令只允许指定一个文件(或 stderr/syslog)和一个全局最低日志级别,所有等于或高于该级别的日志都会写入该目标,无法按级别拆分存储。
但可以通过以下两种实用方式间接实现“按等级分类存储”的效果:
方式一:用 syslog + 系统日志服务做分级路由
这是最标准、生产环境推荐的做法。Nginx 将错误日志发给本地 syslog(如 rsyslog 或 systemd-journald),由 syslog 根据日志优先级(priority)匹配规则,分发到不同文件。
- 在 nginx.conf 中配置 error_log 使用 syslog:
- 编辑 /etc/rsyslog.conf 或新建 /etc/rsyslog.d/nginx.conf:
local7.* /var/log/nginx/error_all.log
local7.=crit /var/log/nginx/error_crit.log
local7.=err /var/log/nginx/error_err.log
local7.=warning /var/log/nginx/error_warn.log
local7.=notice /var/log/nginx/error_notice.log
# 注意:rsyslog 中的 err 对应 nginx 的 error,warning 对应 warn,crit 对应 crit
- 重启服务:systemctl restart rsyslog nginx
- 验证:触发不同级别错误(如配置语法错误是 emerg,上游超时通常是 error 或 warn),检查对应文件是否收到日志
方式二:用 logrotate + 后处理脚本做离线分级
适用于无法改用 syslog 的场景(如容器环境)。先让 Nginx 写单一 error.log,再通过定时任务解析并按 level 拆分归档。
- 保持 nginx.conf 原配置(例如):
- 写一个简单拆分脚本(如 /usr/local/bin/split-nginx-error.sh):
LOG=/var/log/nginx/error.log
awk '/emerg/ {print > "/var/log/nginx/level/emerg.log"}
/alert/ {print > "/var/log/nginx/level/alert.log"}
/crit/ {print > "/var/log/nginx/level/crit.log"}
/error/ {print > "/var/log/nginx/level/error.log"}
/warn/ {print > "/var/log/nginx/level/warn.log"}
/notice/ {print > "/var/log/nginx/level/notice.log"}
/info/ {print > "/var/log/nginx/level/info.log"}
/debug/ {print > "/var/log/nginx/level/debug.log"}' "$LOG"
- 配合 logrotate 清理原始日志,并在 postrotate 中调用该脚本
- 注意:此法是离线处理,有延迟;且需确保 awk 匹配准确(Nginx 错误日志行开头为 YYYY/MM/DD HH:MM:SS [level],可用正则更可靠)
关键提醒
nginx 的 error_log 级别是“阈值”,不是“过滤器”:设为 warn,则 warn、error、crit、alert、emerg 都会记录;设为 info,连 info 和 notice 也会记——它不会丢弃高级别日志,只会控制最低输出门槛。
真正想隔离高危错误(如 emerg/crit),建议结合监控告警(如 Prometheus + Alertmanager 抓取 nginx 日志指标),而不是仅依赖文件分离。











