如何在CentOS7上将日志模块添加到Nginx
介绍
服务器管理不仅仅是服务的初始配置。 它还涉及监督这些服务并确保它们尽可能顺利地运行。 管理员最重要的知识来源之一是日志文件,其中包含有关系统事件的信息。
对于 Web 服务器,如 Nginx,日志包含有关每次尝试通过 Web 服务器访问资源的有价值信息。 每个网站访问者和看到的图像或下载的文件都被精心记录在日志中。 发生错误时,它们也会保存在日志中。 使用结构良好的日志文件要容易得多。
在本指南中,我们将了解如何利用 Nginx 的日志记录模块。 我们将为不同的服务器块设置单独的日志文件,然后自定义日志输出。 除了 Nginx 默认包含的内容之外,我们还将在访问日志中添加有关请求的其他信息(在本教程的示例中,即服务请求所需的时间)。
先决条件
要遵循本教程,您将需要:
- 使用 this initial server setup tutorial 设置的一台 CentOS 7 服务器,包括 sudo 非 root 用户。
- 按照 如何在 CentOS 7 上安装 Nginx 教程 在您的服务器上安装 Nginx。
第 1 步 - 创建测试文件
在这一步中,我们将在默认的 Nginx 网站目录中创建几个测试文件。 我们将使用这些来测试我们的日志记录配置。
当 Nginx(或任何其他 Web 服务器)接收到对文件的 HTTP 请求时,它会打开该文件并通过网络传输其内容将其提供给用户。 文件越小,传输速度越快。 当文件被完全传输时,请求被认为是完整的,然后才会记录传输。
在本教程的后面部分,我们将修改日志配置,以包含有关每个请求所用时间的有用信息。 测试修改后的配置并注意不同请求之间的差异的最简单方法是创建几个不同大小的测试文件,这些文件将在不同的时间内传输。
让我们使用 truncate
在默认 Nginx 目录中创建一个名为 1mb.test
的 1 MB 文件。
sudo truncate -s 1M /usr/share/nginx/html/1mb.test
同样,让我们再创建两个不同大小的文件,首先是 10 兆字节,然后是 100 兆字节,并相应地命名它们。
sudo truncate -s 10M /usr/share/nginx/html/10mb.test sudo truncate -s 100M /usr/share/nginx/html/100mb.test
最后但同样重要的是,让我们也创建一个空文件:
sudo touch /usr/share/nginx/html/empty.test
我们将在下一步中使用这些文件来使用默认配置填充日志文件,然后在本教程的后面部分演示自定义配置。
第 2 步 — 了解默认配置
日志模块是一个核心的 Nginx 模块,这意味着它不需要单独安装即可使用。 然而,默认配置是最低限度的。 在这一步中,我们将看到默认配置是如何工作的。
在全新安装中,Nginx 将所有请求记录到两个单独的文件中:访问日志和错误日志。 错误日志位于 /var/log/nginx/error.log
中,存储有关异常服务器错误或处理请求中的错误的信息。
访问日志位于 /var/log/nginx/access.log
中,使用频率更高。 它是保存所有对 Nginx 请求的信息的地方。 在此日志中,您可以看到用户正在访问哪些文件、他们正在使用哪些 Web 浏览器、他们拥有哪些 IP 地址以及 Nginx 对每个请求响应的 HTTP 状态代码等。
让我们看看访问日志文件的示例行是什么样的。 首先,从 Nginx 请求我们在步骤 1 中创建的空文件,这样日志文件就不会为空。
curl -i http://localhost/empty.test
作为响应,您应该会看到几个 HTTP 响应标头:
Nginx 响应头
HTTP/1.1 200 OK Server: nginx/1.6.3 Date: Fri, 05 Aug 2016 22:05:03 GMT Content-Type: application/octet-stream Content-Length: 0 Last-Modified: Fri, 05 Aug 2016 22:04:55 GMT Connection: keep-alive ETag: "57a50d87-0" Accept-Ranges: bytes
从这个回复中,你可以学到几件事:
HTTP/1.1 200 OK
告诉我们 Nginx 以200 OK
状态码响应,告诉我们没有错误。Content-Length: 0
表示返回的文档长度为零。- 该请求已在
Fri, 05 Aug 2016 22:05:03 GMT
上处理。
让我们看看这是否与 Nginx 存储在其访问日志中的内容相匹配。 日志文件只能由管理用户读取,因此必须使用 sudo
来访问它们。
sudo tail /var/log/nginx/access.log
日志将包含这样的一行,对应于我们之前发出的测试请求。
访问日志条目
::1 - - [05/Aug/2016:22:05:03 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
Nginx 使用 Combined Log Format,这是 Web 服务器为了互操作而常用的访问日志的标准化格式。 在这种格式中,每条信息都由一个空格分隔; 连字符表示缺失的信息。
从左到右,类别是:
请求资源的用户 的 IP 地址。 因为你在本地使用了
curl
,所以地址指向本地主机,::1
。远程记录信息。 这将始终是一个连字符,因为 Nginx 不支持此信息。
根据 HTTP 基本身份验证,登录用户 的 用户名。 对于所有匿名请求,这将为空。
请求日期。 您可以看到这与我们响应标头中的日期匹配。
请求路径,包括请求方法(
GET
)、请求文件的路径(/empty.text
)以及使用的协议([X151X ])。响应状态码,即
200 OK
,表示成功。传输文件的长度,这里是
0
,因为文件是空的。HTTP Referer 标头,其中包含发起请求的文档的地址。 在此示例中,它是空的,但如果这是一个图像文件,则引用者将指向使用该图像的页面。
HTTP Referer 标头是“referrer”一词的拼写错误,它可以追溯到 HTTP 的起源,是 HTTP 标准的一部分。
用户代理,这里是
curl
。X-Forwarded-For 标头,此处为空,如果原始请求已通过代理转发,则包含有关源 IP 地址的信息。
即使是访问日志中的单个日志条目,也包含大量有关请求的有价值信息。 但是,缺少一个重要的信息。 虽然我们已经请求了 http://localhost/empty.test
的确切位置,但日志条目中只有 /empty.test
文件的路径; 有关主机名的信息(此处为 localhost
)丢失。
第 3 步 — 配置单独的访问日志
接下来,我们将覆盖默认日志配置(其中 Nginx 为所有请求存储一个访问日志文件)并让 Nginx 为干净 Nginx 安装附带的默认服务器块存储单独的日志文件。 您可以通过阅读 How To Set Up Nginx Server Blocks (Virtual Hosts) on CentOS 7 教程来熟悉 Nginx 服务器块。
为每个服务器块存储单独的日志文件是一种很好的做法,可以有效地将来自不同网站的日志彼此分开。 这不仅使日志文件更小,而且重要的是使日志更易于分析以发现错误和可疑活动。
要更改默认的Nginx服务器块配置,在vi
中打开服务器块Nginx配置文件(这里有一个对vi'的简单介绍,以防你不熟悉)或者你喜欢的文本编辑器。
sudo vi /etc/nginx/nginx.conf
找到 server
配置块,如下所示:
/etc/nginx/nginx.conf
. . . server { listen 80 default_server; listen [::]:80 default_server; . . .
并将红色标记的两行添加到配置中:
/etc/nginx/nginx.conf
. . . server { listen 80 default_server; listen [::]:80 default_server; access_log /var/log/nginx/default-access.log; error_log /var/log/nginx/default-error.log; . . .
access_log
指令设置将存储访问日志的文件的路径,error_log
对错误日志执行相同的操作。 我们使用与默认 Nginx 日志 (/var/log/nginx
) 相同的目录,但文件名不同。 如果您有多个服务器块,最好以一致且有意义的方式命名日志文件,例如在文件名中使用域名。
保存并关闭文件以退出。
注意: 请记住,为了为每个服务器块维护单独的日志文件,每次在 Nginx 配置中创建新的服务器块时,都必须应用上述配置更改。
要启用新配置,请重新启动 Nginx。
sudo systemctl restart nginx
要测试新配置,对我们的空测试文件执行与之前相同的请求。
curl -i http://localhost/empty.test
检查与我们之前看到的日志行相同的日志行是否写入了我们刚刚配置的单独文件。
sudo tail /var/log/nginx/default-access.log
在下一步中,我们将自定义此新文件中日志的格式并包含其他信息。
第 4 步 — 配置自定义日志格式
在这里,我们将设置自定义日志格式以使 Nginx 记录附加信息(处理请求所需的时间),并配置默认服务器块以使用这种新格式。
我们需要先定义新的日志格式,然后才能使用它。 在 Nginx 中,每种日志格式都有一个唯一的名称,对于整个服务器来说是全局的。 单个服务器块可以配置为稍后使用这些格式,只需参考它们的名称即可。
要定义新的日志记录格式,请在 Nginx 额外配置目录中创建一个名为 timed-log-format.conf
的新配置文件。
sudo vi /etc/nginx/conf.d/timed-log-format.conf
添加以下内容:
/etc/nginx/conf.d/timed-log-format.conf
log_format timed '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$http_x_forwarded_for" $request_time';
保存并关闭文件以退出。
log_format
设置指令定义了新的日志格式。 下一个元素是这种格式的唯一标识符; 这里我们使用 timed,但您可以选择任何名称。
接下来是日志格式本身,为了便于阅读,分为三行。 Nginx 在以美元符号开头的命名系统变量中公开有关所有请求的信息。 这些将替换为有关请求的实际信息,同时将请求详细信息写入访问日志(例如,$request_addr
将替换为访问者的 IP 地址)。
上面的格式与前面讨论的通用日志格式相同,但有一个区别:在最后添加了 $request_time
系统变量。 Nginx 使用这个变量来存储请求花费了多长时间(以毫秒为单位),并且通过在我们的日志格式中使用这个变量,我们告诉 Nginx 将该信息写入日志文件。
现在我们在 Nginx 配置中定义了一个名为 timed 的自定义日志格式,但是默认的服务器块还没有使用这种格式。 接下来,打开服务器块 Nginx 配置文件。
sudo vi /etc/nginx/nginx.conf
找到我们之前修改的 server
配置块,并将 timed
日志格式名称添加到 access_log
设置中,如下图红色突出显示:
/etc/nginx/nginx.conf
. . . server { listen 80 default_server; listen [::]:80 default_server; access_log /var/log/nginx/default-access.log timed; error_log /var/log/nginx/default-error.log; . . .
保存并关闭文件以退出。
要启用新配置,请重新启动 Nginx。
sudo systemctl restart nginx
现在一切都设置好了,让我们检查它是否有效。
第 5 步 — 验证新配置
我们可以通过使用 curl
向 Nginx 调用一些请求来测试新配置,就像我们在步骤 2 中所做的那样。 这次我们将使用在步骤 1 中创建的示例文件:
curl -i http://localhost/empty.test curl -i http://localhost/1mb.test curl -i http://localhost/10mb.test curl -i http://localhost/100mb.test
您会注意到每个后续命令将需要更长的时间来执行,因为文件变得更大并且需要更多时间来传输它们。
让我们在执行这些请求后显示访问日志。
sudo tail /var/log/nginx/default-access.log
日志现在将包含更多行,但最后四行将对应于您刚刚执行的测试请求。
访问日志条目
::1 - - [05/Aug/2016:22:14:04 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.29.0" "-" 0.000 ::1 - - [05/Aug/2016:22:14:04 +0000] "GET /1mb.test HTTP/1.1" 200 1048576 "-" "curl/7.29.0" "-" 0.000 ::1 - - [05/Aug/2016:22:14:07 +0000] "GET /10mb.test HTTP/1.1" 200 10485760 "-" "curl/7.29.0" "-" 2.063 ::1 - - [05/Aug/2016:22:15:10 +0000] "GET /100mb.test HTTP/1.1" 200 104857600 "-" "curl/7.29.0" "-" 47.318
您将看到路径每次都不同,显示正确的文件名,并且请求大小每次都增加。 重要的部分是最后一个突出显示的数字,这是我们刚刚以自定义日志格式配置的请求处理时间(以毫秒为单位)。 如您所料,文件越大,传输所需的时间就越长。
如果是这样,您已经成功在 Nginx 中配置了自定义日志格式!
结论
虽然看到更大的文件需要更长的传输时间并不是特别有用,但当使用 Nginx 为动态网站提供服务时,请求处理时间可能非常有用。 它可用于跟踪网站中的瓶颈,并轻松找到花费时间超过应有时间的请求。
$request_time
只是 Nginx 公开的可用于自定义日志配置的众多系统变量之一。 其他包括,例如,与响应一起发送给客户端的响应标头的值。 将其他变量添加到日志格式就像将它们放入日志格式字符串一样简单,就像我们使用 $request_time
所做的那样。 它是一个强大的工具,您可以在为您的网站配置日志记录时发挥您的优势。
可用于 Nginx 日志格式的变量列表在 Nginx 的日志模块文档 中有描述。