【转载&翻译】Nginx 日志探索:access.log 访问日志与 error.log 错误日志
原文链接:www.digitalocean.com/community/t…
原作者:Meghna Gangwar 和 Vinayak Baranwal
日志除了在故障排除时提供宝贵信息外,对于监控应用程序的活动也非常有用。与其他应用程序一样,Nginx 会将网站访客、遇到的问题等事件记录到日志文件中。这些信息可以帮助您在发现日志事件出现严重差异时,采取预防措施。
本文将详细介绍如何配置 Nginx 日志记录,以便您更好地了解其活动。
前置条件
在 Linux 操作系统(Ubuntu、Debain 发行版本)中安装 Nginx。
(推荐)使用 Docker 启动 Nginx 容器。
Nginx 日志
默认情况下,Nginx 将其事件写入两种类型的日志中:错误日志 error.log、访问日志 access.log。
在大多数流行的 Linux 发行版(例如 Ubuntu、CentOS 或 Debian)中,访问日志和错误日志位于/var/log/nginx
目录中。
让我们进一步了解 Nginx 访问日志和错误日志,以及如何启用它们。
什么是 Nginx 访问日志?
Nginx 会将网站访客活动记录在访问日志中。
您可以在这里找到访问了哪些文件、Nginx 如何响应请求、客户端使用的浏览器、客户端的 IP 地址等等。
您可以使用访问日志中的信息来分析流量,从而了解网站随时间变化的使用情况。此外,通过正确监控访问日志,可以发现用户是否发送了异常请求,从而查找已部署的 Web 应用程序中的缺陷。
Nginx 错误日志是什么?
另一方面,如果 Nginx 遇到任何问题或故障,它会将这些事件记录在错误日志中。例如,如果您的配置文件中存在错误,就可能发生这种情况。
如果 Nginx 无法启动或突然停止运行,检查错误日志将有助于您找到有关该问题的更多详细信息。
您可能还会注意到错误日志中的警告——虽然这些警告并不总是表示紧急问题,但它们可能预示着以后可能会变得严重的问题。
有关使用错误日志诊断和解决常见 Nginx 错误的分步方法,请参阅如何排查常见的 Nginx 错误。
如何启用 Nginx 访问日志?
通常,访问日志可以通过 http
或 server
部分中的 access_log
指令启用。
第一个参数 log_file
是必需的,而第二个参数 log_format
是可选的。如果您未指定任何格式,则日志将以默认的组合格式写入。
access_log log_file log_format;
Nginx 核心配置文件的 http 上下文中默认启用访问日志。这意味着所有虚拟主机的访问日志都将记录在同一个文件中。
http {
...
...
access_log /var/log/nginx/access.log;
...
...
}
将所有虚拟主机的访问日志记录到单独的文件中,始终是一个更好的选择。为此,需要用服务器上下文中的access_log
指令覆盖 http 部分中定义的 access_log
指令。
http {
...
...
access_log /var/log/nginx/access.log;
server {
listen 80;
server_name domain1.com
access_log /var/log/nginx/domain1.access.log;
...
...
}
}
重新加载 Nginx 以应用新配置。要在文件 /var/log/nginx/domain1.access.log
中查看 domain1.com 的访问日志,在终端中使用 tail
命令:
tail -f /var/log/nginx/domain1.access.log
在访问日志中使用自定义格式
访问日志中用于记录事件的默认日志格式是组合日志格式。可以通过创建自定义日志格式并在 access_log
指令中指定自定义格式的名称来覆盖默认配置。
以下示例通过扩展预定义的组合格式(其中包含 gzip 压缩率值)以实现自定义日志格式,并应用该格式。
http {
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
gzip on;
...
access_log /var/log/nginx/domain1.access.log custom;
...
}
}
在您的环境中应用上述日志格式后,请重新加载 Nginx。
现在,查看访问日志,可以看到日志条目末尾的 gzip 压缩率。
# tail -f /var/log/nginx/domain1.access.log
47.29.201.179 - - [28/Feb/2019:13:17:10 +0000] "GET /?p=1 HTTP/2.0" 200 5316 "https://domain1.com/?p=1" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36" "2.75"
如何启用错误日志?
error_log
指令定义了要记录的错误消息的最低严重级别,并记录到文件、stderr 或 syslog。
error_log
指令语法如下:
error_log log_file log_level;
第一个参数 log_file
定义日志文件的路径,第二个参数 log_level
定义要记录的日志事件的严重级别。如果未指定 log_level
,则默认情况下仅记录严重性级别为 error
的日志事件。例如,以下示例将要记录的错误消息的严重性级别设置为crit
。此外,http
上下文中的 error_log
指令意味着所有虚拟主机的错误日志都将包含在一个文件中。
http {
...
error_log /var/log/nginx/error_log crit;
...
}
也可以通过覆盖服务器上下文中的 error_log
指令,为所有虚拟主机分别记录错误日志,如下所示:
http {
...
...
error_log /var/log/nginx/error_log;
server {
listen 80;
server_name domain1.com;
error_log /var/log/nginx/domain1.error_log warn;
...
}
server {
listen 80;
server_name domain2.com;
error_log /var/log/nginx/domain2.error_log debug;
...
}
}
上述所有示例都将日志事件记录到文件中。也可以配置 error_log
指令,将日志事件发送到 syslog 服务器。以下 error_log
指令将错误日志以 debug 格式发送到 IP 地址为 192.168.10.11 的 syslog 服务器。
error_log syslog:server=192.168.10.11 debug;
在某些情况下,想要禁用错误日志,将日志文件名设置为 /dev/null
。
error_log /dev/null;
Nginx 错误日志严重级别
日志级别有很多种,它们与日志事件关联,并具有不同的优先级。在以下日志级别中,debug级别具有最高优先级,并且也包含其他级别。例如,如果您将error级别指定为日志级别,那么它还会捕获标记为crit、alert和emergency日志事件。
- emerg:当系统可能不稳定时发出的紧急消息。
- alert:严重问题的警报消息。
- crit:需要立即处理的关键问题。
- error:发生错误,处理页面时出现问题。
- warn:警告消息。
- notice:可忽略的简单日志通知。
- info:可能想知道的信息消息。
- debug:用于查明错误位置的调试信息。
错误日志级别设置为 debug,将输出上述所有级别的日志。
错误日志级别设置为 error,将输出error、crit、alert、emerg级别的日志。
更改 Nginx 中的日志详细程度
Nginx 通过严重级别控制错误日志的详细程度。例如,在开发或故障排除期间,将日志级别设置为 debug
,提供包含请求处理、配置解析和模块交互的全面输出,调整配置:
error_log /var/log/nginx/error.log debug;
完成此更改后,重新加载 Nginx:
sudo systemctl reload nginx
在生产系统中,通常将日志级别设置为 warn
或 error
以降低详细程度并限制磁盘使用量。这些级别仅捕获可操作的错误,并避免日志中充斥大量良性错误信息。但是,在发生严重事件或跟踪细微错误时,暂时切换到 info
或debug
可以提供更细致的可见性。
高级配置还可能涉及使用基于变量的条件日志记录,或为每个虚拟主机配置不同的日志级别。例如,可以在 warn
级别记录一般流量,并在不同上下文中使用info
或 debug
选择性地记录可疑或敏感路由。
为了进行更精细的控制,在 events
块中使用 debug_connection
指令为特定连接启用调试:
events {
debug_connection 192.168.1.100;
}
将调试输出限制到仅受信任的客户端,这在 NAT 或反向代理后面进行故障排除时特别有用。
使用 Nginx 日志排除性能和安全问题
Nginx 日志有助于识别服务器上的潜在瓶颈和可疑行为。例如,可以使用自定义日志格式筛选响应时间较长的访问日志,从而检测高延迟端点。还可以通过分析请求模式和状态代码(例如 403、404 或 500)来发现试图进行暴力攻击或扫描漏洞。
基本方法包括:
- 分析状态码以查找错误中的异常峰值。
- 跟踪产生大量流量或重复失败请求的IP 地址。
- 检查 user-agents 以识别机器人。
- 查看 referer headers 以检测来自可疑域的流量重定向。
- 比对
$request_time
和$upstream_response_time
,隔离高延迟的后端或数据库。
用于性能调整的自定义日志格式示例:
log_format perf_monitor '$remote_addr [$time_local] "$request" $status '
'$request_time $upstream_response_time';
使用命令行工具(如 awk
、cut
或)grep
对慢速请求进行排序和分析:
awk '{print $NF}' /var/log/nginx/access.log | sort -nr | head -n 20
可以通过编写日志解析器脚本来进一步增强安全审计:
- 计数登录
/admin
、/login
、/wp-login.php
的失败次数 - 检测对不存在的 URL 的重复点击(探测)
- 标记不寻常的用户代理 user-agent 字符串(例如 curl、sqlmap)
- 使用类似
GoAccess
或Grafana
的工具来可视化访问趋势
将 Nginx 日志与监控和分析工具集成
为了获得更深入的见解并自动化日志管理,可以将 Nginx 日志与行业标准监控工具集成。
Logrotate(用于轮转和清理)
使用 logrotate
管理文件大小并防止磁盘膨胀。适当的轮转可防止不受控制的磁盘消耗,确保日志的长期可用性,并符合审计策略。
可靠的 logrotate
配置示例:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
systemctl reload nginx > /dev/null 2>/dev/null || true
endscript
}
通过附加 email
指令启用失败时的电子邮件警报,或通过 /var/lib/logrotate/status
中的 logrotate 状态进行审计。
ELK Stack(用于集中日志分析)
ELK Stack(Elasticsearch、Logstash、Kibana)广泛用于采集、存储和可视化日志。
- Filebeat:轻量级代理,用于收集 Nginx 日志并转发。
-
Logstash:使用
grok
模式解析日志并提取字段。 - Elasticsearch:以索引格式存储日志,支持实时查询。
- Kibana:用于趋势分析、异常检测和深入探究的仪表板。
典型的管道:
Filebeat (Nginx host) → Logstash → Elasticsearch → Kibana
此设置可以识别 5xx 峰值、映射地理 IP 流量、将延迟与特定路由关联起来,并按国家或浏览器对流量可视化。
Better Stack、Datadog 和 Loki
这些工具提供快速部署和管理仪表板:
- Better Stack:可视化警报、Slack 集成、保留策略、正常运行时间监控
- Datadog 日志:全文搜索、监视器、基于角色的访问、APM 关联
- Grafana Loki:可扩展、与 Prometheus 一致的日志聚合(非常适合云原生环境)
启用远程系统日志记录以直接从 Nginx 发送日志:
access_log syslog:server=192.168.0.10:514,tag=nginx_access;
error_log syslog:server=192.168.0.10:514,tag=nginx_error;
对于安全的云日志传输,最好使用 TLS 安全输出或 HTTP API 提取(例如,通过 Fluentd 或 Vector)。
Nginx 日志格式变量详解
了解日志条目中每个变量的含义有助于调试和分析。访问日志条目示例如下:
192.168.0.1 - - [10/May/2025:13:00:00 +0000] "GET /index.html HTTP/1.1" 200 1024 "-" "Mozilla/5.0"
以下是具体内容:
-
$remote_addr
:客户端的IP地址。 -
$remote_user
:已验证的用户(如果有)。 -
$time_local
:请求的时间戳。 -
$request
:完整的 HTTP 请求行。 -
$status
:HTTP 响应状态代码。 -
$body_bytes_sent
:响应体的大小。 -
$http_referer
:链接到所请求资源的页面。 -
$http_user_agent
:使用的浏览器或机器人。 -
$request_time
:Nginx 端处理请求所花费的时间。 -
$upstream_response_time
:上游服务器(后端/API)响应所需的时间。 -
$host
:客户端发送的主机头。 -
$http_x_forwarded_for
:代理服务器转发的 IP(在负载均衡器后面很有用)。 -
$scheme
:使用的协议(http 或 https)。 -
$request_length
:来自客户端的传入请求的大小。 -
$connection_requests
:通过保持连接发出的请求数。
这些变量可以组合成复杂的格式,用于自定义日志解析器,或被引入集中式 SIEM 平台以进行安全关联和行为分析。
常见问题解答 Q&A
1. Nginx 访问日志和错误日志存储在哪里?
默认情况下,Nginx 将其日志存储在 Linux 系统上的 /var/log/nginx/
目录中。两个日志文件是 access.log
和 error.log
,分别记录访问流量和服务器端错误。
可以通过检查 Nginx 配置中的 access_log
指令和 error_log
指令(通常在/etc/nginx/nginx.conf
定义)来验证确切的日志文件路径。
在安装了 Homebrew 的 macOS 上,日志可能位于 /usr/local/var/log/nginx/
。
可以在服务器或 HTTP 块中自定义这些默认路径。
2. 如何更改 Nginx 日志格式?
要更改 Nginx 中的日志格式,请在配置文件的http
代码块中使用 log_format
指令。
可以通过指定 $remote_addr
、$status
、$request_time
等变量来自定义格式。定义完成后,请像下面这样将格式分配给访问日志:access_log /var/log/nginx/custom_access.log custom_format;
。
自定义格式可帮助您捕获其他上下文信息,例如压缩率、上游时间或 Cookie,以便进行更深入的分析。更改后,请务必重新加载 Nginx。
3. Nginx 中的错误日志级别有哪些?
Nginx 错误日志支持多种严重级别,用于控制日志记录的详细程度:
-
debug
:最大细节,有助于故障排除 -
info
和notice
:信息性消息 -
warn
:不会停止执行的警告 -
error
:阻碍进程的常见错误 -
crit
、alert
、emerg
:关键系统级问题
每个级别都包含更高严重程度的日志条目。
例如,error
将记录 crit
、alert
和 emerg
。
在配置中使用 error_log /path/to/error.log warn;
来设置 warn
级别。
4. 我可以实时监控 Nginx 日志吗?
是的。可以使用 tail
命令实时监控 Nginx 日志。例如,tail -f /var/log/nginx/access.log
将在访问日志条目写入时持续流式传输。
像 multitail
或 less +F
这样的工具提供了增强的查看功能。对于更高级的设置,可以将实时日志监控与集中式日志平台(例如 ELK Stack、Graylog 或 BetterStack)集成,从而启用跨服务器的警报、仪表板和搜索功能。
5. 如何禁用特定文件或路由的 Nginx 日志记录?
可以在特定的 location
块中,使用 access_log off;
来禁用访问日志,使用 error_log /dev/null
来禁用错误日志。
这对于不需要日志记录的静态资源(例如 CSS、JS 和图片)非常有用,这可以减少磁盘使用量并使日志更干净。
location /static/ {
access_log off;
error_log /dev/null crit;
}
6. Nginx 中的组合日志格式是什么?
组合日志格式是 Nginx 访问日志的默认格式。它包含客户端 IP、时间戳、HTTP 方法、URI、响应状态和用户代理等信息。以下是一个典型示例:
192.168.1.1 - - [22/May/2025:10:55:22 +0000] "GET /index.html HTTP/1.1" 200 2326 "http://referrer.com" "Mozilla/5.0"
此格式有助于进行基本分析并与大多数日志解析器兼容,可以使用 log_format
指令进行扩展。
7. 如何在 Nginx 中启用调试日志?
要启用调试日志,请为 error_log
指令设置所输出的日志文件,并指定为 debug
级别。例如:
error_log /var/log/nginx/error.log debug;
您还必须使用 --with-debug
标志编译 Nginx,或使用 debug_connection
启用特定模块的调试功能。
请谨慎操作,因为调试日志记录可能非常冗长,会占用大量磁盘空间,最好在故障排除期间临时使用。
8. 我可以将 Nginx 日志发送到远程服务器吗?
是的,Nginx 可以使用 syslog:
协议将错误日志发送到远程 syslog 服务器。例如:
error_log syslog:server=192.168.1.100:514,facility=local7,tag=nginx warn;
然而,访问日志原生并不支持 syslog,可以使用 Filebeat、Fluentd 或 Vector 等日志传送代理将日志条目转发到 ELK、Graylog 或 BetterStack 等集中式系统。这样可以实现跨多个节点的可扩展日志聚合。
9. 如何轮换 Nginx 日志?
Nginx 日志不会自动轮换。在 Linux 上使用 logrotate
等工具来管理它们。
在配置文件中添加 /etc/logrotate.d/nginx
,如下指令:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1`cat /var/run/nginx.pid
endscript
}
此设置每天轮换日志、压缩,并优雅地向 Nginx 发出信号以开始写入新文件。
10. 如何使用 Nginx 日志识别安全问题?
Nginx 日志可以揭示暴力攻击、路径遍历和探测尝试的迹象。例如:
- 来自同一 IP 的多次失败登陆尝试
- 不常见的 HTTP 方法,例如
PUT
、DELETE
- 向非 CMS 网站发出
/wp-admin
或/phpmyadmin
请求 - 大量 404 或 5xx 错误
通过利用 GoAccess 或 AWStats 等日志分析工具,或将 Nginx 日志与安全平台集成,可以自动检测可疑模式并应对潜在威胁。定期检查日志对于维护服务器安全至关重要。
此外,使用 SSL/TLS 保护 Nginx 服务是防御常见攻击的关键步骤。有关使用 Let's Encrypt 设置 SSL 的分步指南,请参阅教程如何在 Ubuntu 20.04 上使用 Let's Encrypt 保护 NGINX。
结论
Nginx 访问日志和错误日志对于监控用户活动和简化调试流程至关重要。可以自定义访问日志格式,以根据需要捕获更多详细信息。
强烈建议同时启用访问日志和错误日志,因为它们为 Nginx 服务器的维护和故障排除提供了宝贵的见解。