原文链接:www.digitalocean.com/community/t…
原作者:Meghna Gangwar 和 Vinayak Baranwal
日志不仅是故障排查的重要依据,更是监控应用程序运行状态的关键工具。与大多数服务类似,Nginx 会详细记录网站访问情况和系统运行事件,包括访客行为、服务异常等信息。通过分析这些日志数据,能够在发现异常指标时及时采取预防性措施,防患于未然。
本文将详细介绍如何配置 Nginx 日志记录,以更好地了解其活动。
前置条件
在 Linux 操作系统(Ubuntu、Debian 发行版本)中安装 Nginx。
(推荐)使用 Docker 启动 Nginx 容器。
Nginx 日志
默认情况下,Nginx 将其事件写入两种类型的日志中:错误日志 error.log、访问日志 access.log。
在大多数流行的 Linux 发行版(例如 Ubuntu、CentOS 或 Debian)中,访问日志和错误日志位于 /var/log/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;
...
...
}
将特定服务器的访问日志单独记录,可以在 server 块中,使用 access_log 指令覆盖 override。
http {
...
...
access_log /var/log/nginx/access.log;
server {
listen 80;
server_name domain1.com;
access_log /var/log/nginx/domain1.access.log;
...
...
}
}
重新加载 Nginx 以应用新配置。
查看 domain1.com 的访问日志,在 /var/log/nginx/domain1.access.log 目录下,使用 tail 命令:
tail -f /var/log/nginx/domain1.access.log
在访问日志中使用自定义格式
访问日志中用于记录事件的默认日志格式是组合日志格式。可以通过创建自定义日志格式并在 access_log 指令中指定来覆盖默认配置。
如下示例,定义 custom 日志格式并应用于 server 块中。
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 服务器的维护和故障排除提供了宝贵的见解。
关注微信公众号,获取运维资讯
如果此篇文章对你有所帮助,感谢你的点赞与收藏,也欢迎在评论区友好交流。
微信搜索关注公众号:持续运维