- Nginx 日志的类型
- 日志格式的定义
- 如何配置日志
- 日志轮转与切割(防止日志文件过大)
- 日志分析工具与实战
- 日志的最佳实践
Nginx 日志的类型
Nginx 主要有两种类型的日志:

a) 访问日志
这是最常用、最重要的日志,它记录了每一个客户端(如浏览器、爬虫)与 Nginx 服务器交互的详细信息。
- 作用:
- 分析网站流量:访问量、独立访客数、页面浏览量。
- 了解用户行为:用户从哪里来(
Referer)、访问了哪些页面(URI)、使用什么浏览器和操作系统(User-Agent)。 - 性能分析:哪些页面响应慢(响应时间
request_time)。 - SEO 优化:分析搜索引擎的抓取情况。
- 安全审计:发现异常的访问模式,如暴力破解、爬虫扫描。
b) 错误日志
当 Nginx 在处理请求时遇到问题,或者自身启动、运行出错时,它会记录错误日志。
- 作用:
- 服务器排错:是解决 Nginx 配置问题、应用问题(如后端服务不可用)的“第一手”资料。
- 监控服务器健康状态:可以设置监控工具,当错误日志出现特定错误(如
502 Bad Gateway)时发出警报。 - 调试:包含详细的错误级别和上下文信息,帮助定位问题根源。
日志格式的定义
Nginx 允许你自定义日志的格式,以便记录你关心的任何信息,默认情况下,Nginx 已经定义了两种格式:
combined:这是最常用的访问日志格式,包含了丰富的信息。main:在某些版本中是默认格式,信息比combined少一些。
你可以在 Nginx 的配置文件(通常是 nginx.conf 或 conf.d/ 目录下的 .conf 文件)中使用 log_format 指令来定义自己的格式。

log_format 指令语法
log_format name [escape=default|json] string ...;
name:给这个格式定义一个名字,my_custom_format。escape:指定如何转义特殊字符,json是个好选择,方便后续程序解析。string的模板,可以包含变量和文本。
常用变量列表
| 变量 | 含义 |
|---|---|
$remote_addr |
客户端 IP 地址 |
$http_x_forwarded_for |
当你使用了反向代理(如 Nginx 代理 Tomcat)时,记录客户端的真实 IP。 |
$time_local |
服务器本地时间(标准格式) |
$request |
完整的原始请求行(如 GET /index.html HTTP/1.1) |
$status |
HTTP 响应状态码(如 200, 404, 500) |
$body_bytes_sent |
发送给客户端的 body 内容大小(字节) |
$http_referer |
引用页面的地址(从哪里点进来的) |
$http_user_agent |
客户端的浏览器信息(User-Agent 字符串) |
$request_time |
整个请求处理完毕所花费的时间(秒,毫秒级精度) |
$upstream_response_time |
Nginx 与后端服务器建立连接到接收完响应头的时间(不包括响应体传输时间) |
$upstream_addr |
后端服务器的地址 |
默认 combined 格式示例
Nginx 自带的 combined 格式定义如下:
log_format combined '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
这个格式产生的日志行就像这样:
168.1.100 - - [10/Oct/2025:13:55:36 +0800] "GET /api/users HTTP/1.1" 200 512 "https://www.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" "-"
如何配置日志
配置日志主要在 server 块或 http 块中进行。
a) 配置访问日志
在 server 块中,使用 access_log 指令指定日志文件的路径和使用的格式。

示例 1:基本配置
server {
listen 80;
server_name www.example.com;
# 访问日志记录到 /var/log/nginx/www.example.com.access.log,
# 使用默认的 combined 格式
access_log /var/log/nginx/www.example.com.access.log;
location / {
root /var/www/html;
index index.html;
}
}
示例 2:使用自定义格式
# 在 http 块中定义一个新的日志格式
http {
# ... 其他 http 配置 ...
log_format json escape=json '{'
'"timestamp": "$time_iso8601",'
'"remote_addr": "$remote_addr",'
'"request": "$request",'
'"status": $status,'
'"body_bytes_sent": $body_bytes_sent,'
'"request_time": $request_time,'
'"upstream_response_time": "$upstream_response_time"'
'}';
server {
listen 80;
server_name api.example.com;
# 使用我们刚刚定义的 json 格式
access_log /var/log/nginx/api.example.com.access.log json;
location / {
# 假设这是一个反向代理
proxy_pass http://backend_server;
}
}
}
b) 配置错误日志
错误日志通常在 main(主)配置级别或 http 级别定义,这样所有虚拟主机都会共享同一个错误日志,你也可以在 server 块中为特定网站单独配置。
使用 error_log 指令。
语法:
error_log file [level];
file:日志文件路径。level:日志级别,级别从低到高为:debug,info,notice,warn,error,crit,alert,emerg,记录的级别是 及以上 的,设置为error,则会记录error,crit,alert,emerg级别的日志。
示例:
# 在 http 块或主配置文件中设置
error_log /var/log/nginx/error.log warn;
# 在某个 server 块中覆盖
server {
# ...
error_log /var/log/nginx/www.example.com.error.log; # 不指定级别,默认是 error
# ...
}
日志轮转与切割
Nginx 的日志文件会不断增长,如果不加以处理,很快就会占满整个硬盘,必须配置日志轮转。
Linux 系统通常使用 logrotate 工具来自动完成这项工作。
/etc/logrotate.d/nginx 文件示例:
这个文件通常由 Nginx 安装包自动创建或提供。
/var/log/nginx/*.log {
daily # 每天轮转一次
missingok # 如果日志文件不存在,不报错
rotate 7 # 保留7个旧日志文件
compress # 轮转后进行压缩,节省空间
delaycompress # 延迟一天再压缩,这样最新的旧日志可以方便排查问题
notifempty # 如果日志为空,则不轮转
create 0644 www-data www-data # 创建新日志文件时的权限和所有者
sharedscripts # 脚本只在所有日志轮转后执行一次
postrotate
# Nginx 正在运行,则需要向其发送 USR1 信号,
# 通知它重新打开日志文件,继续写入新的日志文件
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
logrotate 通常由 cron 每天自动执行,它会检查配置文件,对满足条件的日志文件进行轮转。
日志分析工具与实战
拿到日志文件后,如何分析呢?
a) 命令行工具(Linux/Unix)
-
查看日志尾部(实时监控):
tail -f /var/log/nginx/access.log
这是最常用的实时查看日志的方法,
-f表示跟随文件末尾的变化。 -
统计访问量最高的 URL:
# 统计访问次数最多的前10个URL awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10awk '{print $7}':提取日志中的第7个字段(通常是请求的 URI)。sort:排序。uniq -c:合并连续的相同行,并计数。sort -nr:按数字(-n)逆序(-r)排序。head -n 10:显示前10行。
-
统计访问量最高的 IP:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10 -
统计 HTTP 状态码:
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr这可以帮你快速定位 404、500 等错误。
-
使用
goaccess进行可视化分析:goaccess是一个非常强大的、实时的、交互式的日志分析器,它能生成漂亮的 HTML 报告。安装:
# Ubuntu/Debian sudo apt-get install goaccess # CentOS/RHEL sudo yum install goaccess
使用:
# 分析日志并生成 HTML 报告 goaccess /var/log/nginx/access.log -o /var/www/html/report.html --real-time-html
然后你就可以在浏览器中访问
http://your_server_ip/report.html查看实时更新的分析报告。
b) ELK/EFK 栈(企业级方案)
对于大型网站,通常会将日志发送到集中的日志分析平台,如 ELK Stack (Elasticsearch, Logstash, Kibana) 或 EFK Stack (Elasticsearch, Fluentd, Kibana)。
- 流程:Nginx 日志 -> (Filebeat/Fluentd) -> Logstash/Fluentd -> Elasticsearch -> Kibana
- 优点:
- 集中管理:所有服务器的日志都在一个地方。
- 强大的搜索和聚合:可以基于任意字段进行复杂查询和聚合分析。
- 可视化:通过 Kibana 创建各种图表和仪表盘,直观展示网站数据。
- 告警:可以设置阈值,当满足条件时(如 5xx 错误超过 100 次/分钟)发送邮件或短信告警。
日志的最佳实践
- 为每个虚拟主机使用独立的访问日志:便于隔离和分析特定网站的数据。
- 为后端 API 使用 JSON 格式日志:结构化日志更易于机器解析和分析。
- 记录关键性能指标:如
$request_time和$upstream_response_time,对性能优化至关重要。 - 配置并测试日志轮转:这是服务器运维的基石,避免磁盘被撑爆。
- 保护日志文件安全:日志文件可能包含敏感信息(如用户 IP、路径),确保日志文件权限设置正确(如
640),并限制只有授权用户才能访问。 - 建立监控和告警:监控错误日志的增长率和特定错误码的出现频率,及时发现并解决问题。
- 定期归档和分析:不要让日志文件堆积如山,定期将旧日志归档到对象存储(如 S3)中,并进行分析,为业务决策提供数据支持。
