Nginx 是一款流行的开源 Web 服务器,以其高性能、稳定性和丰富的功能集而闻名。它在互联网上为众多网站提供服务,从小型个人博客到大型企业应用程序。
日志管理是 Nginx 使用中需要特别关注的一方面,因为它提供了有关服务器活动的宝贵信息。通过分析这些日志,您可以深入了解用户行为、跟踪潜在问题并衡量服务器性能。
使用 Docker 运行 Nginx
借助官方的 Docker 镜像来启动 Nginx 是最为简便的方式,它极大地简化了安装流程,并确保在不同系统上都能保持一致的表现。
首先,创建一个新的“nginx-logging-tutorial”目录,进入该目录,并执行以下“docker run”命令:
mkdir nginx-logging-tutorial && cd nginx-logging-tutorial
docker run --name nginx-server --rm -p 80:80 nginx
在上述命令中:
-
--name nginx-server:为容器指定名称“nginx-server”。 -
--rm:在容器停止时自动删除它,适用于测试或临时设置。 -
-p 80:80:将主机的 80 端口映射到容器内部的 80 端口。
如果你的系统上没有“nginx”镜像,Docker 会在启动容器之前自动进行下载。
如果你遇到如下错误:
docker: Error response from daemon: driver failed programming external connectivity on endpoint nginx (28402db69fec7c17e179ea87882667f1e054391138f77ffaf0c3eb388efc3ffb): Bind for 0.0.0.0:80 failed: port is already allocated.
这表明你的系统上的另一个应用程序正在使用端口 80。在重试命令之前,请确保该端口上没有其他服务在运行。
如果 Nginx 成功启动,你将在终端中看到类似以下的日志:
...
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/11/04 03:01:30 [notice] 1#1: using the "epoll" event method
2024/11/04 03:01:30 [notice] 1#1: nginx/1.27.2
2024/11/04 03:01:30 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/11/04 03:01:30 [notice] 1#1: OS: Linux 6.10.12-orbstack-00282-gd1783374c25e
2024/11/04 03:01:30 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/11/04 03:01:30 [notice] 1#1: start worker processes
2024/11/04 03:01:30 [notice] 1#1: start worker process 29
现在,打开你的 Web 浏览器并访问http://localhost。你应该会看到默认的 Nginx 欢迎页面,这意味着 Nginx 成功启动并正在运行。
返回终端后,你会看到如下日志:
2024/11/04 03:04:37 [error] 31#31: *5 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.215.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/"
192.168.215.1 - - [04/Nov/2024:03:04:37 +0000] "GET /favicon.ico HTTP/1.1" 404 153 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15" "-"
这些日志显示你的浏览器成功获取到了网页内容,但在尝试获取favicon.ico文件时遇到了 404 错误,因为该文件不在默认的 Nginx 目录中。
在继续下一步之前,你可以使用Ctrl-C停止 Nginx 容器,接着我们将深入探讨这些日志的含义。
Nginx 日志文件的位置
与大多数 Web 服务器一样,Nginx 会在两个不同的日志文件中记录信息:
-
访问日志:此文件记录每个传入请求,记录关键详细信息,如客户端的 IP 地址、请求的时间戳、请求的资源(URI)、响应的 HTTP 状态码以及客户端的用户代理(浏览器和操作系统)。
-
错误日志:此文件用作诊断使用,记录在请求处理和其他 Nginx 操作期间遇到的错误和问题。它记录诸如时间戳、错误级别、错误消息以及任何相关上下文等信息,有助于进行故障定位和解决。
这些日志文件的位置因你的操作系统和 Nginx 安装方法而异。
Linux 发行版
在大多数 Linux 发行版中,Nginx 日志文件通常位于/var/log/nginx/目录中。你会分别找到名为access.log和error.log的文件。
如果你在默认位置找不到日志文件,则需要检查特定的 Nginx 配置。首先确定你的 Nginx 配置文件的位置(通常为/etc/nginx/nginx.conf):
sudo nginx -t
如果配置文件有效,此命令应输出配置文件的位置:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
打开配置文件并查找error_log和access_log指令,以确定它们各自所在的位置。
/etc/nginx/nginx.conf
error_log /var/log/nginx/error.log
http {
...
access_log /var/log/nginx/access.log;
...
}
默认情况下,Nginx 全局应用error_log指令,而access_log通常放置在http块内。
你可以使用tail命令实时查看这些文件的内容:
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
Docker 容器
由于 Docker 容器是临时的,因此将日志直接存储在容器内重启会丢失。官方的 Nginx Docker 镜像通过创建从/var/log/nginx/access.log和/var/log/nginx/error.log到容器的标准输出(/dev/stdout)和标准错误(/dev/stderr)流的符号链接来解决此问题。这使 Docker 能够收集和管理日志。
你可以在 Dockerfile 中找到相关行:
mainline/debian/Dockerfile
...
ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
再次启动nginx-server容器,但使其从当前终端会话分离:
docker run --name nginx-server -d -p 80:80 nginx
输出:
50a5f9d89802d7283f72f6bfff6aacfae0bb22ae4f5a7a74686becfd132048f7
容器运行后,再次访问http://localhost以生成一些日志,然后使用docker logs命令相应地查看它们:
docker logs -f nginx-server
你将看到熟悉的 Nginx 日志输出,其中包含访问日志和错误日志:
...
2024/11/04 04:51:42 [error] 35#35: *8 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.215.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/"
192.168.215.1 - - [04/Nov/2024:04:51:42 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" "-"
192.168.215.1 - - [04/Nov/2024:04:52:14 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" "-"
要仅查看访问日志,需要将标准错误重定向到/dev/null:
docker logs -f nginx-server 2>/dev/null
输出:
...
192.168.215.1 - - [04/Nov/2024:04:52:14 +0000] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" "-"
192.168.215.1 - - [04/Nov/2024:04:52:29 +0000] "GET / HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" "-"
同样,要仅查看错误日志,需要将标准输出重定向到/dev/null:
docker logs -f nginx-server 1>/dev/null
输出:
...
2024/11/04 04:51:42 [error] 35#35: *8 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.215.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/"
现在你知道如何在各种环境中定位和访问 Nginx 日志文件,让我们继续探索如何根据需要自定义访问日志格式。
配置 Nginx 访问日志
默认情况下,Nginx 访问日志以combined格式生成。此格式定义为:
'$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
此配置生成类似于以下的日志:
192.168.215.1 - - [04/Nov/2024:04:54:10 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" "-"
让我们分解一下日志中每个标记的含义:
-
172.17.0.1:发出请求的客户端的 IP 地址。 -
-:如果使用了身份验证,这是经过身份验证的用户名;否则,为连字符(-)。 -
[04/Nov/2024:04:54:10 +0000]:处理请求的本地时间。 -
"GET / HTTP/1.1":请求方法、路径和 HTTP 协议版本。 -
200:返回给客户端的 HTTP 状态码。 -
615:响应体的大小(以字节为单位)。 -
"-":引用页面的 URL(如果有)。 -
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36":客户端提供的浏览器和操作系统信息。 -
"-":如果请求通过代理,此变量包含原始客户端 IP 地址。
虽然此格式记录了大量的信息,对于分析流量、故障排除和了解用户行为很有用,但你可能希望根据自身需求自定义它,以仅记录对你最重要的数据。接下来让我们看看如何操作。
你可以使用log_format指令在主 Nginx 配置文件(/etc/nginx/nginx.conf)或/etc/nginx/sites-enabled中的主机特定配置中自定义访问日志格式。
如果 Nginx 直接在你的主机上运行,你可以编辑相关文件。对于 Docker 实例,执行以下命令从nginx镜像中提取 Nginx 配置文件并将其保存到主机上的nginx.conf文件中:
docker run --rm --entrypoint=cat nginx /etc/nginx/nginx.conf > nginx.conf
再次启动容器将修改后的文件从主机挂载到容器内的/etc/nginx/nginx.conf:
docker run --name nginx-server -v./nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
自定义访问日志格式
可以使用log_format指令自定义访问日志的格式:
log_format <name> '<formatting_variables>';
你只需为自定义格式命名,并使用提供的核心变量和日志变量定义日志的结构。以下是一个示例:
nginx.conf
...
http {
...
log_format custom '$remote_addr - $remote_user [$time_local] $status '
'"$host" "$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
...
}
此示例在日志格式中添加了$host变量,以便在日志中展示请求的域名。要应用此自定义格式,需要修改access_log指令:
access_log /var/log/nginx/access.log custom;
保存更改,然后使用以下命令停止并删除现有的nginx-server容器:
docker container stop nginx-server
docker container rm nginx-server
再次启动:
docker run --name nginx-server --rm -p 80:80 -v./nginx.conf:/etc/nginx/nginx.conf:ro nginx
现在访问http://localhost时,你会观察到域名记录在相应的日志中:
192.168.215.1 - - [04/Nov/2024:05:16:22 +0000] 200 "localhost" "GET / HTTP/1.1" 615 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0.1 Safari/605.1.15" "-"
设置日志记录条件
Nginx 的访问日志在流量较大时可能会变得非常大。日志记录条件允许你根据特定条件选择性地过滤日志,以减少日志量并提高性能。
语法如下:
access_log /path/to/access.log <log_format> if=<condition>;
<condition>是一个布尔表达式,Nginx 会为每个请求对其进行求值。如果求值结果为true,则记录日志;否则,跳过。
以下示例展示了如何从访问日志中排除成功(2xx)和重定向(3xx)状态码:
http {
map $status $loggable {
~^[23] 0; # 匹配2xx和3xx状态码
default 1; # 记录其他所有内容
}
access_log /var/log/nginx/access.log combined if=$loggable;
}
日志记录条件的一些实际应用包括:
-
仅记录错误响应(4xx 和 5xx)方便进行故障排查。
-
排除已知为机器人的特定用户代理或 IP 地址。
-
仅记录对应用程序特定部分的请求。
-
记录一定比例的请求,以降低日志记录成本,同时仍记录具有代表性的样本。
禁用访问日志
如果你已经通过 Web 应用程序收集请求日志,则可能希望通过使用特殊值off或重定向到/dev/null来禁用 Nginx 访问日志:
access_log off;
access_log /dev/null;
结构化 Nginx 访问日志
在云原生分布式系统和微服务的世界中,结构化日志由于其相对于传统纯文本日志的众多优势而备受关注。虽然 Nginx 本身不生成 JSON 格式的日志,但你可以使用log_format指令结合escape=json参数来实现,该参数可确保对 JSON 中无效的字符进行正确转义。
让我们看看这是如何工作的:
nginx.conf
...
http {
...
log_format custom_json escape=json '{'
'"level":"info",'
'"ts": "$time_iso8601",'
'"message": "handled request $request_method $request_uri",'
'"request": {'
'"id": "$http_x_request_id",'
'"remote_ip": "$remote_addr",'
'"remote_port": "$remote_port",'
'"protocol": "$server_protocol",'
'"method": "$request_method",'
'"host": "$host",'
'"uri": "$request_uri",'
'"headers": {'
'"user-agent": "$http_user_agent",'
'"accept": "$http_accept",'
'"accept-encoding": "$http_accept_encoding",'
'"traceparent": "$http_traceparent",'
'"tracestate": "$http_tracestate"'
'}'
'},'
'"bytes_read": $request_length,'
'"duration_msecs": $request_time,'
'"size": $bytes_sent,'
'"status": $status,'
'"resp_headers": {'
'"content_length": "$sent_http_content_length",'
'"content_type": "$sent_http_content_type"'
'}'
'}';
access_log /var/log/nginx/access.log custom_json;
...
}
在这个配置中:
-
我们定义了一个名为
custom_json的新日志格式,并使用escape=json启用了 JSON 转义。 -
在 JSON 结构中,我们记录了各种信息:
-
基础信息,如日志级别、时间戳(ts)和消息。
-
请求的详细信息。
-
指标,如读取的字节数、响应时间和响应大小。
-
响应细节,如状态和使用
$sent_http_<header_name>的特定响应头部。 -
最后,将
custom_json格式应用于访问日志。
保存配置并重新启动 Nginx 后,使用一些虚构的分布式追踪头发出请求:
curl -v -H "traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01" \
-H "tracestate: rojo=00f067aa0ba902b7" \
-H "X-Request-Id: f45a82a7-7066-40d4-981d-145952c290f8" \
http://localhost
你将观察到新的访问日志以的 JSON 格式打印:
{
"level": "info",
"ts": "2024-11-04T05:27:29+00:00",
"message": "handled request GET /",
"request": {
"id": "f45a82a7-7066-40d4-981d-145952c290f8",
"remote_ip": "192.168.215.1",
"remote_port": "28842",
"protocol": "HTTP/1.1",
"method": "GET",
"host": "localhost",
"uri": "/",
"headers": {
"user-agent": "curl/8.7.1",
"accept": "*/*",
"accept-encoding": "",
"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
"tracestate": "rojo=00f067aa0ba902b7"
}
},
"bytes_read": 229,
"duration_msecs": 0,
"size": 853,
"status": 200,
"resp_headers": {
"content_length": "615",
"content_type": "text/html"
}
}
这种结构化格式使你的日志更易于解析和分析。
配置 Nginx 错误日志
Nginx 错误日志是诊断和解决问题的关键工具。它记录在各种 Nginx 操作期间发生的错误、警告和其他重要事件。
error_log指令控制 Nginx 的错误日志记录行为。它接受两个参数:日志文件的路径和日志的最低严重级别。
error_log /var/log/nginx/error.log <severity_level>;
Nginx 将错误日志消息分类为以下级别,从最不严重到最严重:
-
debug:调试消息,记录最多的信息,通常只在开发环境中使用。
-
info:信息性消息,用于常规操作和状态信息。
-
notice:公告,用于不太重要的信息,但可能对系统管理员有用。
-
warn:警告,表示有潜在问题,但不影响服务的正常运行。
-
error:错误,表示处理请求时出现的错误,通常需要关注。
-
crit:关键问题,表示严重问题,需要立即采取行动。
-
alert:警报,表示非常严重的问题,必须立即采取行动。
-
emerg:紧急情况,表示系统处于无法使用的状态。
如果在你的 Nginx 配置中未显式配置错误严重级别,你将看到error级别及以上(crit、alert和emerg)的消息。但是,官方 Nginx Docker 镜像的默认级别设置为notice。
要更改默认错误日志级别,将所需级别作为error_log指令的第二个参数提供:
error_log /var/log/nginx/error.log warn;
此配置将记录warn级别及更高的日志消息。
Nginx 错误日志格式
Nginx 错误日志遵循一种为人类可读性和便于工具解析而设计的格式。一般格式为:
YYYY/MM/DD HH:MM:SS [<severity_level>] <pid>#<tid>: *<cid> <message>
其中:
-
<pid>:进程 ID -
<tid>:线程 ID -
<cid>:连接 ID
以下是一个实际错误日志的示例:
2024/11/04 05:18:13 [error] 34#34: *3 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.215.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/"
记录错误到多个文件
与访问日志类似,你可以配置 Nginx 将错误记录到多个文件,甚至可以使用不同的严重级别:
error_log /var/log/nginx/error.log info;
error_log /var/log/nginx/emerg_error.log emerg;
在此设置中,除了debug级别消息外,所有事件都将记录到error.log,而紧急事件将记录到名为emerg_error.log的单独文件中。
禁用错误日志
如果你需要完全禁用 Nginx 错误日志(虽然一般不建议这样做),可以将其重定向到/dev/null。
error_log /dev/null;
结构化 Nginx 错误日志
虽然 Nginx 没有为其错误日志提供内置的 JSON 格式化功能,但我们可以利用外部日志处理工具,如 Logstash、Fluentd 或 Vector,来解析、重新格式化这些日志,以便更好地分析并与现代日志系统集成。
在本节中,将演示如何使用 Vector 将 Nginx 错误日志转换为结构化 JSON 格式,提供与我们在上一步中对访问日志所实现的类似的功能。
如果你尚未安装 Vector,请在你的机器上安装或拉取官方 Docker 镜像:
docker pull timberio/vector:0.40.0-alpine
输出:
0.40.0-alpine: Pulling from timberio/vector
c6a83fedfae6: Already exists
b9fc015ecb16: Pull complete
f7f83e464043: Pull complete
fe91b3a632fb: Pull complete
5312bc41fca9: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:7a81fdd62e056321055a9e4bdec4073d752ecf68f4c192e676b85001721523c2
Status: Downloaded newer image for timberio/vector:0.40.0-alpine
docker.io/timberio/vector:0.40.0-alpine
接下来,在当前目录中创建一个vector.yaml文件,内容如下:
sources:
nginx:
type: docker_logs
include_images:
- nginx
transforms:
nginx_json:
type: remap
inputs:
- nginx
source: |
.context = parse_json(.message) ?? parse_nginx_log(.message, "error") ?? set!(value: {}, path: ["message"], data: .message)
.message = .context.message
del(.context.message)
.
sinks:
print:
type: console
inputs:
- nginx_json
encoding:
codec: json
-
sources:定义日志源。这里我们从基于nginx镜像的 Docker 容器中收集日志。 -
transforms:定义一个名为nginx_json的转换器。 -
它首先尝试使用
parse_json()将消息字段解析为 JSON。 -
如果失败,它尝试使用
parse_nginx_log()将其解析为 Nginx 错误日志。 -
如果两次解析尝试都失败,它创建一个空对象并将其分配给
.context.message。 -
然后将顶级消息字段设置为
.context.message并删除.context.message。 -
最后,末尾的
.返回修改后的事件。 -
type: remap:使用 Vector Remap Language(VRL)进行转换。 -
inputs:从nginx源获取输入。 -
source:包含 VRL 脚本: -
sinks:定义转换后日志的目的地,这里是控制台,格式为 JSON。
注意:对于基于文件的日志:如果你从文件中读取 Nginx 日志,sources部分应更改为:
sources:
nginx:
type: file
include:
- /var/log/nginx/error.log
- /var/log/nginx/access.log
. . .
要查看实际效果,让我们使用 Docker Compose 启动 Nginx 和 Vector 容器。在继续之前,在你的nginx-logging-tutorial目录中创建一个docker-compose.yml文件,内容如下:
name: nginx-logging-tutorial
services:
nginx:
container_name: nginx-server
image: nginx:alpine
restart: always
ports:
- 80:80
vector:
container_name: vector
image: timberio/vector:0.40.0-alpine
restart: always
volumes:
- ./vector.yaml:/etc/vector/vector.yaml
- /var/run/docker.sock:/var/run/docker.sock:ro
在docker-compose.yml中配置 vector 服务时,需要将你创建的vector.yaml文件挂载到容器中,以替换默认配置。
你还需要将 Docker 套接字(/var/run/docker.sock)挂载到容器中。这使 Vector 能够与 Docker 守护进程进行通信,从而使其能够识别和监控你指定的其他容器的日志。
然而,在生产环境中,将 Docker 套接字直接暴露给容器可能存在安全风险。考虑以下替代方法:
-
配置 Vector 通过 SSH 或 HTTPS 与 Docker 守护进程交互。
-
不将 Vector 运行在容器中,而是直接在主机上安装它,以避免需要挂载套接字。
这些措施有助于保护你的 Docker 环境,同时仍允许 Vector 有效地收集和处理你的 Nginx 日志。
要启动服务,请确保在运行以下命令之前,通过按CTRL-C停止正在运行的nginx-server容器:
docker compose up -d
输出:
[+] Running 3/3
✔ Network nginx-logging-tutorial_default Created 0.3s
✔ Container nginx-server Started 0.6s
✔ Container vector Started 0.6s
回你的浏览器,访问http://localhost并刷新页面几次。
然后你可以使用以下命令查看处理后的日志:
docker logs -f vector
如果你安装了 jq,可以使用以下命令将输出管道到 jq,同时忽略非 JSON 对象:
docker logs -f vector | jq -R 'fromjson? | select(type == "object")'
你将看到以下日志输出:
{
"container_created_at": "2024-11-04T05:41:57.790404857Z",
"container_id": "3f459d539a5c3efbb22586f77887f388247b22912513c22cc322d3df13e94117",
"container_name": "nginx-server",
"context": {},
"host": "86d5bb6db884",
"image": "nginx:alpine",
"label": {
"com.docker.compose.config-hash": "92bbc57bd73614a031c6c9fea1145a5f271d854186f2b4885c27f5857cf03ccf",
"com.docker.compose.container-number": "1",
"com.docker.compose.depends_on": "",
"com.docker.compose.image": "sha256:577a23b5858b94a1a92e4263bd5d6da99fbd997fb9839bc0f357c9d4b858f431",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "nginx-logging-tutorial",
"com.docker.compose.project.config_files": "/Users/test/Code/work/nginx-logging-tutorial/docker-compose.yml",
"com.docker.compose.project.working_dir": "/Users/test/Code/work/nginx-logging-tutorial",
"com.docker.compose.service": "nginx",
"com.docker.compose.version": "2.29.7",
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"message": "192.168.117.1 - - [04/Nov/2024:05:59:50 +0000] \"GET / HTTP/1.1\" 200 615 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36\" \"-\"",
"source_type": "docker_logs",
"stream": "stdout",
"timestamp": "2024-11-04T05:59:50.378929954Z"
}
context属性包含了之前使用parse_json()函数解析的原始 Nginx JSON 对象。其他属性是 Vector 在从 Docker 容器收集日志时添加的。
要查看解析后的错误日志,可以请求一个不存在的文件:
curl http://localhost/favicon.ico
随后你将在 Docker 日志中观察到以下内容:
{
"container_created_at": "2024-11-04T05:41:57.790404857Z",
"container_id": "3f459d539a5c3efbb22586f77887f388247b22912513c22cc322d3df13e94117",
"container_name": "nginx-server",
"context": {},
"host": "86d5bb6db884",
"image": "nginx:alpine",
"label": {
"com.docker.compose.config-hash": "92bbc57bd73614a031c6c9fea1145a5f271d854186f2b4885c27f5857cf03ccf",
"com.docker.compose.container-number": "1",
"com.docker.compose.depends_on": "",
"com.docker.compose.image": "sha256:577a23b5858b94a1a92e4263bd5d6da99fbd997fb9839bc0f357c9d4b858f431",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "nginx-logging-tutorial",
"com.docker.compose.project.config_files": "/Users/test/Code/work/nginx-logging-tutorial/docker-compose.yml",
"com.docker.compose.project.working_dir": "/Users/test/Code/work/nginx-logging-tutorial",
"com.docker.compose.service": "nginx",
"com.docker.compose.version": "2.29.7",
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"message": "192.168.117.1 - - [04/Nov/2024:05:55:58 +0000] \"GET /favicon.ico HTTP/1.1\" 404 153 \"-\" \"curl/8.7.1\" \"-\"",
"source_type": "docker_logs",
"stream": "stdout",
"timestamp": "2024-11-04T05:55:58.294892739Z"
}
有了针对访问和错误事件的结构化 JSON 日志,你现在就能够更方便的观察 Nginx 服务器的行为和性能了。
结论
在本篇文章中,我们介绍了如何查看和配置 Nginx 访问日志和错误日志。我们涵盖了从查找配置文件到自定义日志格式和路径的所有内容。
通过有效地利用 Nginx 日志记录功能,您可以深入了解服务器性能、用户行为和潜在问题,从而优化您的 Web 应用程序并提供更好的用户体验。
请记住,定期审查和分析日志是服务器管理和维护的重要组成部分。通过这样做,您可以及时问题发现并解决它们,确保服务器的平稳运行。