log_not_found off仅抑制Nginx自身静态文件查找失败(如try_files/alias/root触发)产生的404类error_log日志,不影响proxy_pass后端返回的404或access_log记录;应精准配置于静态资源location块,避免全局关闭。

直接关 log_not_found 就能大幅减少 error log 里的 404 刷屏,但别全局关——它只影响 Nginx 自己找文件失败的日志,对 proxy_pass 返回的 404 完全无效。
为什么 log_not_found 关了还看到 404 日志?
因为 log_not_found 只控制这一类错误:
- Nginx 在
location块里用root/alias/try_files查找静态文件时,发现路径不存在,报open() "/xxx" failed (2: No such file or directory) - 这类日志写进
error.log,级别是crit或error
但它完全不管:
- 后端(如 Node.js、Python)返回的 404 —— 这走的是
proxy_pass,Nginx 当作正常响应处理,不触发log_not_found -
access_log里的 404 状态码记录 —— 这是另一套机制,关log_not_found对它没任何影响
在哪关、怎么关才安全?
推荐在匹配静态资源的 location 块里精准关闭,而不是放在 http 或 server 根块:
location ~* \.(js|css|png|jpg|gif|ico|svg|woff2?)$ { log_not_found off; }-
location = /favicon.ico { log_not_found off; return 204; }—— 顺手返回空响应,省一次磁盘查找 location /static/ { alias /data/static/; log_not_found off; }
避免这么做:
- 在
server块顶部写log_not_found off;—— 万一某个try_files是用于 fallback 到后端的逻辑,关掉后就丢掉了关键错误线索 - 在
location /里关 —— 容易误杀真正需要排查的缺失资源路径
想连 access_log 里的 404 都过滤?用 if= + map
如果目标是降低磁盘 I/O 和日志体积,access_log 里大量 status=404 请求(比如爬虫扫路径、旧链接残留)才是更重的负担。这时得靠条件日志:
- 先定义过滤变量:
map $status $log_404 { "404" 0; default 1; } - 再在对应
location或server中启用:access_log /var/log/nginx/app.log main if=$log_404; - 配合 UA 过滤更彻底:
map $http_user_agent $log_ua { "~*ELB-HealthChecker|curl.*k8s-probe" 0; default 1; },然后access_log ... if=$log_ua;
注意:if= 不支持嵌套或复杂表达式,所有判断必须提前塞进 map,且 map 必须定义在 http 块顶层。
关完之后怎么确认真问题没被掩盖?
关掉日志不是关掉事实。真正要盯的 404 其实藏在 access_log 里:
- 用
awk '$9 == "404" {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20找高频 404 路径 - 重点看来源是否集中(比如某页面 JS 里写了错误的 API 地址),而不是单条
error.log提示 - 前端构建产物中引用了已删文件?检查
index.html和打包后dist/目录的一致性
最常被忽略的一点:关了 log_not_found 后,error.log 量骤降,反而让真正的 500、connection refused 类错误更容易被看见——这才是调优的真实收益。


















