线上Nginx应设error_log为warn或error级:warn记录故障前兆(如证书过期、upstream临时下线),error记录明确失败(如502/504、权限拒绝);debug禁用,info/notice慎用;需结合access_log与$request_id关联分析。

线上环境不追求“全量日志”,而要“关键可读”。error_log 级别本质是过滤器:级别越低,记录越细(含调试变量、配置加载过程),但磁盘和I/O压力剧增;级别越高,只留致命错误(如进程崩溃、端口绑定失败),容易漏掉早期隐患。生产中真正实用的是 warn 和 error 两级,它们在信息量与系统开销之间取得平衡。
各级别实际记录内容对比
nginx error_log 支持 8 级:debug → info → notice → warn → error → crit → alert → emerg(从低到高)。关键不是记多少,而是记什么:
- warn:记录潜在风险,比如证书即将过期、重定向循环、upstream 被临时标记为 down、client body 超限但已截断——这些不会直接返回 500,但往往是故障前兆;
- error:默认级别,记录明确失败事件,如 502/504(后端不可达)、模块加载失败、rewrite 规则语法错、open() 权限拒绝(Permission denied);
- notice:偏运维提示,如 worker 进程重启、配置重载成功、SSL handshake 完成——日常可忽略,调试启动流程时有用;
- debug:仅限编译时启用 --with-debug,会输出每个请求的变量值、内存分配路径、配置解析树——生产禁用,否则日志量轻松破 GB/天。
线上推荐配置与动态调整方法
不要一上线就写死 debug 或 info。建议按阶段推进:
- 日常运行:用
error_log /var/log/nginx/error.log error;——稳、轻、易读; - 排查连接类问题(如 connect refused、connection reset):临时提至
warn,执行nginx -s reload生效,无需重启; - 确认某虚拟主机异常?可在 server 块内单独设
error_log /var/log/nginx/app1_error.log warn;,隔离定位; - 切忌在 main 区块配
info或更低——会记录每次 SSL 握手细节、每个 map 变量计算过程,IO 压力陡升,还可能暴露敏感路径。
结合 access_log 快速定位真实问题
单看 error_log 常常不够。例如 error.log 记了一条 connect() failed (111: Connection refused) while connecting to upstream,但你不知道是哪个请求触发的。这时要:
- 查对应时间点的 access_log,找 status=502/504 的请求,提取 $request_id(需在 log_format 中提前定义);
- 用 request_id 关联 error_log 中的上下文(nginx 1.11.0+ 默认在 error 日志中打印 request id);
- 若 error_log 中出现
client intended to send too large body,立刻检查 access_log 中该请求的 $body_bytes_sent 和 $request_length,确认是否真因 body 过大被拒(而非 client_max_body_size 配小了)。
MySQL 错误日志的对应参考
MySQL 的 log_error_verbosity 逻辑类似:取值 1(仅 error)、2(error + warning,默认)、3(+note + debug)。线上建议保持 2;只有在排查初始化失败、复制中断等深层问题时,才临时设为 3 并配合 tail -f 实时观察。注意 MySQL error log 默认不记录 SQL 语句本身,敏感操作需靠 general_log 或 audit plugin 补充。










