如何在 Debian 8 上为 Nginx 添加日志模块

简介

服务器管理不仅涉及服务的初始配置。它还包括监督这些服务,确保它们尽可能顺畅地运行。日志文件是管理员最重要的知识来源之一,其中包含有关系统事件的信息。

对于像 Nginx 这样的网络服务器,日志包含了每次试图通过网络服务器访问资源的宝贵信息。每个网站访问者、看到的图像或下载的文件都会被仔细记录在日志中。出现错误时,也会保存在日志中。处理结构良好的日志文件要容易得多。

在本指南中,我们将了解如何使用 Nginx 的日志模块。我们将为不同的服务器块设置单独的日志文件,然后自定义日志输出。除 Nginx 默认包含的信息外,我们还将在访问日志中添加有关请求的其他信息(在本教程的示例中,为请求提供服务所需的时间)。

先决条件

要学习本教程,您需要

步骤 1 - 创建测试文件

在这一步中,我们将在默认的 Nginx 网站目录中创建几个测试文件。我们将使用这些文件测试日志配置。

当Nginx(或任何其他网络服务器)接收到文件的HTTP请求时,就会打开该文件,并通过网络传输文件内容,为用户提供服务。文件越小,传输速度越快。当文件全部传输完毕后,请求才算完成,此时才会记录传输过程。

在本教程的稍后部分,我们将修改日志记录配置,以包含每次请求耗时的有用信息。要测试修改后的配置并发现不同请求之间的差异,最简单的方法是创建几个大小不同的测试文件,这些文件将在不同的时间内传输。

让我们使用 truncate 在 Nginx 默认目录下创建一个 1 兆字节的文件,文件名为 1mb.test

1sudo truncate -s 1M /var/www/html/1mb.test

同样,让我们再创建两个不同大小的文件,先是 10 兆字节,然后是 100 兆字节,并相应地命名它们。

1sudo truncate -s 10M /var/www/html/10mb.test
2sudo truncate -s 100M /var/www/html/100mb.test

最后,我们也创建一个空文件:

1sudo touch /var/www/html/empty.test

我们将在下一步中使用这些文件以默认配置填充日志文件,然后在教程的稍后部分演示自定义配置。

第 2 步 - 了解默认配置

日志模块是 Nginx 的核心模块,因此无需单独安装即可使用。不过,默认配置是最低限度的。在本步骤中,我们将看到默认配置是如何工作的。

刚安装时,Nginx会将所有请求记录到两个独立文件:访问日志和错误日志。错误日志位于"/var/log/nginx/error.log",存储异常服务器错误或处理请求过程中的错误信息。

访问日志位于/var/log/nginx/access.log,使用频率较高。这里保存了所有对Nginx的请求信息。在该日志中,可以看到用户访问的文件、使用的网络浏览器、IP地址,以及Nginx对每个请求的HTTP状态代码。

让我们看看访问日志文件的示例行是什么样的。首先,向 Nginx 申请我们在步骤 1 中创建的空文件,这样日志文件就不会是空的了。

1curl -i http://localhost/empty.test

对此,您应该会看到几个 HTTP 响应头:

 1[label Nginx response headers]
 2HTTP/1.1 200 OK
 3Server: nginx/1.6.2
 4Date: Fri, 09 Dec 2016 23:05:18 GMT
 5Content-Type: application/octet-stream
 6Content-Length: 0
 7Last-Modified: Fri, 09 Dec 2016 23:05:13 GMT
 8Connection: keep-alive
 9ETag: "584b38a9-0"
10Accept-Ranges: bytes

从这个回答中,你可以学到几件事:

  • HTTP/1.1 200 OK 表示 Nginx 响应了 200 OK 状态代码,告诉我们没有错误。
  • Content-Length: 0 表示返回的文档长度为零。
  • 请求处理时间为Fri, 09 Dec 2016 23:05:18 GMT

让我们看看这是否与 Nginx 存储在访问日志中的内容一致。日志文件只能由管理员用户读取,因此必须使用 sudo 访问。

1sudo tail /var/log/nginx/access.log

日志中将包含这样一行内容,与我们之前发出的测试请求相对应。

1[label Access log entry]
2127.0.0.1 - - [09/Dec/2016:23:07:02 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.38.0"

Nginx使用_Combined Log Format_,这是网络服务器为实现互操作性而普遍使用的访问日志标准化格式。在这种格式中,每条信息都用一个空格分隔;连字符代表缺失的信息。

从左到右依次为

  • 请求资源的用户 的** IP 地址。由于您在本地使用了 curl,该地址指向本地主机 127.0.0.1
  • 远程登录 信息。这里总是一个连字符,因为 Nginx 不支持此信息。
  • 根据HTTP基本认证, 登录用户的** 用户名。对于所有匿名请求,该信息将为空。 请求日期 。你可以从我们的响应头中看到这个日期。
  • 请求路径 ,包括请求方法(GET)、请求文件的路径(/empty.text)以及使用的协议(HTTP/1.1)。 响应状态代码 ,即 "200 OK",表示成功。
  • 传输文件的 长度** ,此处为 "0",因为文件为空。 HTTP Referer 头信息 ,其中包含请求源文件的地址。在本例中,它是空的,但如果这是一个图像文件,引用头就会指向使用该图像的页面。 HTTP Referer 头信息是 "referrer "一词的拼写错误,它可以追溯到 HTTP 的起源,是 HTTP 标准的一部分。 用户代理 ,这里是 "curl"。

即使是访问日志中的一个日志条目,也包含了大量有关请求的宝贵信息。然而,其中缺少了一个重要信息。虽然我们请求了 http://localhost/empty.test 的确切位置,但日志条目中只有 /empty.test 文件的路径,而主机名(此处为 localhost)的信息却丢失了。

第 3 步 - 配置单独的访问日志

接下来,我们将覆盖默认日志配置(Nginx为所有请求存储一个访问日志文件),让Nginx为默认服务器块存储单独的日志文件。你可以阅读如何在Debian 7上设置Nginx服务器块教程,熟悉Nginx服务器块。

为每个服务器区块存储单独的日志文件是一种很好的做法,可以有效地将不同网站的日志相互分离。这不仅能使日志文件更小,更重要的是能使日志更容易分析,从而发现错误和可疑活动。

要更改 Nginx 服务器模块的默认配置,请使用 nano 或最喜欢的文本编辑器打开 Nginx 服务器模块配置文件。

1sudo nano /etc/nginx/sites-available/default

找到 "服务器 "配置块,它看起来像这样:

 1[label /etc/nginx/sites-available/default]
 2. . .
 3# Default server configuration
 4#
 5
 6server {
 7    listen 80 default_server;
 8    listen [::]:80 default_server;
 9
10. . .

并将标红的两行添加到配置中:

 1[label /etc/nginx/sites-available/default]
 2. . .
 3# Default server configuration
 4#
 5
 6server {
 7    listen 80 default_server;
 8    listen [::]:80 default_server;
 9
10    access_log /var/log/nginx/default-access.log;
11    error_log /var/log/nginx/default-error.log;
12. . .

access_log "指令设置了存储访问日志的文件路径,"error_log "指令也设置了存储错误日志的文件路径。我们使用与 Nginx 默认日志相同的目录(/var/log/nginx),但文件名不同。如果有多个服务器区块,最好以一致且有意义的方式命名日志文件,例如在文件名中使用域名。

保存并关闭文件退出。

<$>[注] 注意: 请记住,为了为每个服务器块维护单独的日志文件,每次在 Nginx 配置中创建新的服务器块时,都必须应用上述配置更改。 <$>

要启用新配置,请重启 Nginx。

1sudo systemctl restart nginx.service

要测试新配置,请对空测试文件执行与之前相同的请求。

1curl -i http://localhost/empty.test

检查是否已将与之前相同的日志行写入我们刚刚配置的独立文件。

1sudo tail /var/log/nginx/default-access.log

下一步,我们将自定义新文件中的日志格式,并添加其他信息。

第 4 步 - 配置自定义日志格式

在这里,我们将设置自定义日志格式,使 Nginx 记录更多信息(请求处理时间),并配置默认服务器块以使用这种新格式。

我们需要定义新的日志格式,然后才能使用。在 Nginx 中,每种日志格式都有一个唯一的名称,是整个服务器的全局名称。稍后,只需参考其名称,就能配置单个服务器块使用这些格式。

要定义新的日志格式,请在 Nginx 额外配置目录下创建一个名为 timed-log-format.conf 的新配置文件。

1sudo nano /etc/nginx/conf.d/timed-log-format.conf

添加以下内容

1[label /etc/nginx/conf.d/timed-log-format.conf]
2log_format timed '$remote_addr - $remote_user [$time_local] '
3                 '"$request" $status $body_bytes_sent '
4                 '"$http_referer" "$http_user_agent" $request_time';

保存并关闭文件退出。

日志格式 "设置指令定义了新的日志格式。下一个元素是该格式的唯一标识符;这里我们使用 timed ,但也可以选择任何名称。

接下来是日志格式本身,为便于阅读,分为三行。Nginx 在命名的系统变量中公开所有请求的信息,并在前面加上美元符号。在将请求详细信息写入访问日志时,这些变量将被请求的实际信息所取代(例如,"$request_addr "将被替换为访问者的 IP 地址)。

上述格式与前面讨论的通用日志格式相同,唯一不同的是:在最后添加了"$request_time "系统变量。Nginx使用该变量以毫秒为单位存储请求花费的时间,通过在日志格式中使用该变量,我们告诉Nginx将该信息写入日志文件。

现在,我们在 Nginx 配置中定义了名为 timed 的自定义日志格式,但默认服务器块还没有使用这种格式。接下来,打开服务器块的Nginx配置文件。

1sudo nano /etc/nginx/sites-available/default

找到我们之前修改过的 server 配置块,并将 timed 日志格式名称添加到 access_log 设置中,如下图红色部分所示:

 1[label /etc/nginx/sites-available/default]
 2. . .
 3# Default server configuration
 4#
 5
 6server {
 7    listen 80 default_server;
 8    listen [::]:80 default_server;
 9
10    access_log /var/log/nginx/default-access.log timed;
11    error_log /var/log/nginx/default-error.log;
12. . .

保存并关闭文件退出。

要启用新配置,请重启 Nginx。

1sudo systemctl restart nginx.service

现在,一切都已就绪,让我们来检查一下它是否能正常工作。

第 5 步 - 验证新配置

我们可以像步骤 2 所做的那样,使用 curl 向 Nginx 调用一些请求,以测试新配置。这次我们将使用步骤 1 中创建的示例文件:

1curl -i http://localhost/empty.test
2curl -i http://localhost/1mb.test
3curl -i http://localhost/10mb.test
4curl -i http://localhost/100mb.test

你会注意到,由于文件越来越大,传输所需的时间也越来越长,因此每条后续命令的执行时间都会延长。

让我们在执行这些请求后显示访问日志。

1sudo tail /var/log/nginx/default-access.log

现在日志将包含更多行,但最后四行将与您刚刚执行的测试请求相对应。

1[label Access log entries]
2127.0.0.1 - - [09/Dec/2016:23:07:02 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.38.0"
3127.0.0.1 - - [09/Dec/2016:23:08:28 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.38.0" 0.000
4127.0.0.1 - - [09/Dec/2016:23:08:28 +0000] "GET /1mb.test HTTP/1.1" 200 1048576 "-" "curl/7.38.0" 0.000
5127.0.0.1 - - [09/Dec/2016:23:08:28 +0000] "GET /10mb.test HTTP/1.1" 200 10485760 "-" "curl/7.38.0" 0.302
6127.0.0.1 - - [09/Dec/2016:23:08:39 +0000] "GET /100mb.test HTTP/1.1" 200 68516844 "-" "curl/7.38.0" 7.938

你会看到,路径每次都不一样,显示的是正确的文件名,请求大小每次都在增加。重要的部分是最后一个突出显示的数字,这是我们刚刚在自定义日志格式中配置的请求处理时间,单位是毫秒。正如你所料,文件越大,传输所需的时间就越长。

如果是这种情况,说明你已经在 Nginx 中成功配置了自定义日志格式!

结论

虽然查看较大文件的传输时间并不是特别有用,但当 Nginx 用于服务动态网站时,请求处理时间却非常有用。它可以用来追踪网站的瓶颈,轻松找到耗时过长的请求。

request_time "只是Nginx提供的众多系统变量之一,可用于自定义日志配置。其他变量包括,例如,与响应一起发送给客户端的响应头的值。在日志格式中添加其他变量就像在日志格式字符串中添加"$request_time "一样简单。这是一个功能强大的工具,您可以在为网站配置日志时充分利用它。

Nginx日志模块文档](http://nginx.org/en/docs/http/ngx_http_log_module.html)中描述了可用于Nginx日志格式的变量列表。

Published At
Categories with 技术
comments powered by Disqus