阅读视图

发现新文章,点击刷新页面。

【转载&翻译】Nginx 日志探索:access.log 访问日志与 error.log 错误日志

原文链接:www.digitalocean.com/community/t…

原作者:Meghna Gangwar 和 Vinayak Baranwal


日志除了在故障排除时提供宝贵信息外,对于监控应用程序的活动也非常有用。与其他应用程序一样,Nginx 会将网站访客、遇到的问题等事件记录到日志文件中。这些信息可以帮助您在发现日志事件出现严重差异时,采取预防措施。

本文将详细介绍如何配置 Nginx 日志记录,以便您更好地了解其活动。

NGINX-access-logs-error-logs.png

前置条件

在 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 访问日志?

通常,访问日志可以通过 httpserver 部分中的 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级别指定为日志级别,那么它还会捕获标记为critalertemergency日志事件。

  • emerg:当系统可能不稳定时发出的紧急消息。
  • alert:严重问题的警报消息。
  • crit:需要立即处理的关键问题。
  • error:发生错误,处理页面时出现问题。
  • warn:警告消息。
  • notice:可忽略的简单日志通知。
  • info:可能想知道的信息消息。
  • debug:用于查明错误位置的调试信息。

错误日志级别设置为 debug,将输出上述所有级别的日志。

错误日志级别设置为 error,将输出errorcritalertemerg级别的日志。

更改 Nginx 中的日志详细程度

Nginx 通过严重级别控制错误日志的详细程度。例如,在开发或故障排除期间,将日志级别设置为 debug,提供包含请求处理、配置解析和模块交互的全面输出,调整配置:

error_log /var/log/nginx/error.log debug;

完成此更改后,重新加载 Nginx:

sudo systemctl reload nginx

在生产系统中,通常将日志级别设置为 warnerror 以降低详细程度并限制磁盘使用量。这些级别仅捕获可操作的错误,并避免日志中充斥大量良性错误信息。但是,在发生严重事件或跟踪细微错误时,暂时切换到 infodebug 可以提供更细致的可见性。

高级配置还可能涉及使用基于变量的条件日志记录,或为每个虚拟主机配置不同的日志级别。例如,可以在 warn 级别记录一般流量,并在不同上下文中使用infodebug 选择性地记录可疑或敏感路由。

为了进行更精细的控制,在 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';

使用命令行工具(如 awkcut 或)grep 对慢速请求进行排序和分析:

awk '{print $NF}' /var/log/nginx/access.log | sort -nr | head -n 20

可以通过编写日志解析器脚本来进一步增强安全审计:

  • 计数登录 /admin/login/wp-login.php的失败次数
  • 检测对不存在的 URL 的重复点击(探测)
  • 标记不寻常的用户代理 user-agent 字符串(例如 curl、sqlmap)
  • 使用类似 GoAccessGrafana 的工具来可视化访问趋势

将 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.logerror.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:最大细节,有助于故障排除
  • infonotice:信息性消息
  • warn:不会停止执行的警告
  • error:阻碍进程的常见错误
  • critalertemerg:关键系统级问题

每个级别都包含更高严重程度的日志条目。

例如,error 将记录 critalertemerg

在配置中使用 error_log /path/to/error.log warn; 来设置 warn 级别。

4. 我可以实时监控 Nginx 日志吗?

是的。可以使用 tail 命令实时监控 Nginx 日志。例如,tail -f /var/log/nginx/access.log 将在访问日志条目写入时持续流式传输。

multitailless +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 方法,例如 PUTDELETE
  • 向非 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 服务器的维护和故障排除提供了宝贵的见解。

❌