Nginx 日志配置

Nginx 把每次请求的处理记录写入访问日志(access log),把运行期错误写入错误日志(error log)。合理定制字段、级别与切割策略,是排查问题与统计流量(见第 25 章监控)的基础。

默认日志与格式

访问日志默认按内置 combined 格式输出;用 log_format 自定义格式后,在 access_log 中引用格式名:

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;   # 路径 + 格式名
}

log_format 里常用的内置变量:

变量含义
$remote_addr客户端 IP
$time_local服务器本地时间
$request原始请求行,如 GET /index.html HTTP/1.1
$status响应状态码
$body_bytes_sent发给客户端的响应体字节数
$http_user_agent客户端 User-Agent
$http_referer来源页面(无则为 -)
$request_time处理请求耗时(秒)

重载后查看效果:

nginx -s reload
tail -n 2 /var/log/nginx/access.log
# 输出:127.0.0.1 - - [14/Mar/2025:10:20:11 +0800] "GET / HTTP/1.1" 200 612 "-" "curl/8.5.0" "-"

错误日志与级别

error_log 记录启动、配置语法、上游连接等错误,语法为 error_log 路径 [级别]:

级别严重程度说明
emerg/alert/crit系统级紧急错误
error默认级别,记录运行错误
warn/notice较低警告与提示
info/debug调试信息(debug 级需编译带 --with-debug)
error_log /var/log/nginx/error.log warn;    # 记录 warn 及以上级别

日志切割

日志无限增长会占满磁盘。reopen 思路:先改名旧日志,再向 master 进程发 USR1 信号令其重新打开日志文件:

mv /var/log/nginx/access.log /var/log/nginx/access.log.$(date +%F)
kill -USR1 $(cat /var/run/nginx.pid)        # 重新打开日志文件

生产环境更推荐交给 logrotate 自动执行,/etc/logrotate.d/nginx 大致如下:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

条件日志

健康检查等高频接口会刷爆日志。access_log 支持 if= 参数按变量开关,也可以在 location 内直接关闭:

map $request_uri $loggable {       # 请求 /health 时值为 0,不记日志
    default 1;
    /health 0;
}
server {
    access_log /var/log/nginx/access.log main if=$loggable;
    location = /health {
        access_log off;            # 另一种做法:此 location 直接关日志
        return 200 'ok';
    }
}

小结

日志配置三件事:log_format 定义字段并用 access_log 落盘、按需调整 error_log 级别、配 logrotate 定时切割(本质是 mv 旧文件 + USR1 reopen)。字段留足 IP、耗时、状态码,排查问题就多了一半线索。

笔记加载中…