0%

Nginx日志设置

Nginx 日志配置详解:访问日志、错误日志与日志切割

Nginx 的日志系统是监控服务状态、排查问题的核心工具,主要分为访问日志(access_log)错误日志(error_log)。本文详细讲解日志的配置方法、格式自定义、级别设置及日志切割方案,帮助高效管理日志数据。

访问日志(access_log):记录客户端请求细节

访问日志用于记录客户端的每一次请求,包括请求来源、路径、响应状态等信息,是分析用户行为、排查接口问题的关键依据。

基础配置语法

1
2
3
4
5
6
7
8
9
10
# 完整语法(可省略可选参数)
access_log path [format [buffer=size] [gzip=level] [flush=time] [if=condition]];

# 示例:在server块中启用访问日志
server {
listen 80;
server_name example.com;
# 日志路径为/var/log/nginx/example.access.log,使用main格式
access_log /var/log/nginx/example.access.log main;
}

参数说明

  • path:日志文件路径(必填),如/var/log/nginx/access.log
  • format:日志格式名称(需通过log_format定义,默认使用combined格式);
  • buffer=size:日志写入缓存大小(默认 64k),减少磁盘 IO 次数;
  • gzip=level:日志写入前压缩(1-9 级,级别越高压缩率越高但速度越慢);
  • flush=time:缓存过期时间(如5s),超时后强制写入磁盘;
  • if=condition:条件判断(如if=$request_method=POST),满足条件才写入日志。

自定义日志格式(log_format)

通过log_format可定义个性化日志格式,灵活记录所需字段。语法如下:

1
log_format 名称 [escape=default|json] '格式字符串';

常用变量与示例
Nginx 提供丰富的内置变量(如客户端 IP、请求方法等),以下是典型的日志格式定义:

1
2
3
4
5
6
7
8
9
10
11
12
http {
# 定义名为main的日志格式(通用格式)
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

# 定义名为json的JSON格式日志(便于日志分析工具解析)
log_format json '{"time":"$time_iso8601", "client_ip":"$remote_addr", '
'"request":"$request", "status":$status, '
'"bytes_sent":$body_bytes_sent, "referer":"$http_referer", '
'"user_agent":"$http_user_agent"}';
}

关键变量解析

变量 含义
$remote_addr 客户端 IP 地址
$remote_user 认证用户名称(未认证则为-
$time_local 本地时间(如10/Jul/2025:15:30:00 +0800
$request 完整请求行(如GET /api/user HTTP/1.1
$status 响应状态码(如 200、404)
$body_bytes_sent 发送给客户端的字节数(不含响应头)
$http_referer 来源页面(Referer 头)
$http_user_agent 客户端浏览器标识(User-Agent 头)
$http_x_forwarded_for 代理链中的客户端 IP(多层代理时使用)
$bytes_sent 发送给客户端的总字节数
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小
$connection 连接序列号
$connection_requests 当前通过连接发出的请求数量
$msec 日志写入时间,单位为秒,精度是毫秒
$pipe 如果请求是通过http流水线发送,则其值为”p”,否则为“.”
$request_length 请求长度(包括请求行,请求头和请求体)
$request_time 请求处理时长,单位为秒,精度为毫秒,从读入客户端的第一个字节开始,直到把最后一个字符发送张客户端进行日志写入为止
$time_iso8601 标准格式的本地时间,形如“2017-05-24T18:31:27+08:00”
$time_local 通用日志格式下的本地时间,如”24/May/2017:18:31:27 +0800”
$request_uri 完整的请求地址,如 “https://daojia.com/

关闭访问日志

如需关闭某一范围的访问日志(如静态资源,减少日志量),可设置access_log off

1
2
3
4
location ~* \.(jpg|css|js)$ {
access_log off; # 不记录静态资源请求日志
root /var/www/static;
}

错误日志(error_log):记录服务异常信息

错误日志用于记录 Nginx 运行中的错误(如配置错误、连接失败),帮助排查服务故障,级别从低到高分为debuginfonoticewarnerrorcritalertemerg

配置语法

1
error_log file [level];

示例

1
2
3
4
5
6
7
8
9
10
11
http {
# 全局错误日志(记录所有级别的错误)
error_log /var/log/nginx/error.log error; # 仅记录error及以上级别

server {
listen 80;
server_name example.com;
# 该虚拟主机的错误日志(更详细,包含debug信息)
error_log /var/log/nginx/example.error.log debug;
}
}

级别说明

  • debug:最详细(仅调试时使用,会产生大量日志);
  • error:默认级别,记录错误(如连接超时、配置错误);
  • crit:严重错误(如磁盘满、权限不足,需立即处理)。

常见错误日志示例

1
2025/07/10 15:30:00 [error] 1234#0: *567 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET /api HTTP/1.1", upstream: "http://127.0.0.1:8080/api", host: "example.com"
  • 含义:客户端192.168.1.100请求/api时,Nginx 无法连接后端8080端口(连接被拒绝)。

日志切割:避免文件过大

随着请求量增长,日志文件会不断膨胀,导致查看和备份困难。通过定时切割脚本可将日志按时间拆分(如每日切割)。

1. 切割脚本(log_rotate.sh)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

# 日志路径
LOG_PATH="/var/log/nginx"
# Nginx PID文件路径
PID_PATH="/var/run/nginx.pid"

# 以当前日期命名备份文件(如20250710_access.log)
DATE=$(date +%Y%m%d)
ACCESS_BAK="${LOG_PATH}/access_${DATE}.log"
ERROR_BAK="${LOG_PATH}/error_${DATE}.log"

# 备份当前日志
mv "${LOG_PATH}/access.log" "${ACCESS_BAK}"
mv "${LOG_PATH}/error.log" "${ERROR_BAK}"

# 发送USR1信号给Nginx,重新生成新日志文件
kill -USR1 $(cat "${PID_PATH}")

# 压缩7天前的日志(可选)
find "${LOG_PATH}" -name "access_*.log" -mtime +7 -exec gzip {} \;
find "${LOG_PATH}" -name "error_*.log" -mtime +7 -exec gzip {} \;

2. 定时执行(crontab)

通过crontab设置每日凌晨 1 点执行切割脚本:

1
2
3
4
5
# 编辑定时任务
crontab -e

# 添加以下内容(每天1:00执行)
0 1 * * * /bin/bash /path/to/log_rotate.sh

最佳实践

  1. 日志分级存储
    • 访问日志按虚拟主机拆分(如example.access.logapi.access.log);
    • 错误日志全局统一存储,便于集中排查。
  2. 控制日志量
    • 关闭静态资源(图片、CSS)的访问日志;
    • 生产环境避免使用debug级别错误日志。
  3. 结合日志分析工具
    • 使用 ELK(Elasticsearch+Logstash+Kibana)或 Grafana 等工具分析日志,可视化请求趋势、错误分布。
  4. 日志备份策略
    • 切割后的日志定期备份到远程存储(如 S3),并设置过期清理(如保留 30 天)。

欢迎关注我的其它发布渠道