Skip to content

11-nginx-log 日志介绍

nginx 官网 ngx_http_log_module

https://nginx.org/en/docs/http/ngx_http_log_module.html

The ngx_http_log_module module writes request logs in the specified format.

Requests are logged in the context of a location where processing ends. It may be different from the original location, if an internal redirect happens during request processing.

翻译成中文

ngx_http_log_module 模块按指定格式记录请求日志。

请求在处理结束的位置上下文中被记录。如果在请求处理期间发生内部重定向,它可能与原始位置不同。

1. 在 Windows PowerShell 中运行 Nginx 容器

powershell
docker run --name mynginx -d -p 8080:80  -v "${PWD}/logs:/var/log/nginx" nginx
  • docker run: 使用 Docker 运行一个新容器。
  • --name mynginx: 将容器命名为 mynginx
  • -d: 后台运行容器。
  • -p 8080:80: 将容器的 80 端口映射到宿主机的 8080 端口。
  • -v "${PWD}/logs:/var/log/nginx": 将宿主机当前目录下的 logs 文件夹挂载到容器的 /var/log/nginx 目录,用于存储 Nginx 的日志文件。
  • nginx: 指定使用的镜像是 nginx

2. 在 Mac/Linux 终端中运行 Nginx 容器

bash
docker run --name mynginx -d -p 8080:80 -v $PWD/logs:/var/log/nginx nginx
  • 与 PowerShell 命令相同,只是在 shell 环境中使用了 $PWD 而不是 ${PWD}

3. 从运行中的 Nginx 容器中拷贝配置文件到宿主机

bash
docker cp mynginx:/etc/nginx ./nginx
  • docker cp: 用于从 Docker 容器中拷贝文件或文件夹。
  • mynginx:/etc/nginx: 指定从名为 mynginx 的容器中的 /etc/nginx 目录拷贝数据。
  • ./nginx: 指定拷贝到宿主机的当前目录下的 nginx 文件夹中。

4. Nginx 配置文件详解

nginx
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    include /etc/nginx/conf.d/*.conf;
}
  • user nginx;: 指定 Nginx 服务运行的用户为 nginx。
  • worker_processes auto;: 自动设置工作进程的数量。
  • error_log /var/log/nginx/error.log notice;: 错误日志文件的位置和日志级别。
  • log_format main: 定义了日志格式 main
  • access_log /var/log/nginx/access.log main;: 访问日志的存储位置和使用的日志格式。
  • sendfile on;: 启用 sendfile 系统调用,提高文件传输的效率。
  • keepalive_timeout 65;: 保持连接的超时时间为 65 秒。

5. 修改配置文件,重新指定 Nginx 配置的 Docker 命令

powershell
docker run --name mynginx -d -p 8080:80  -v "${PWD}/logs:/var/log/nginx"  -v "${PWD}/conf:/etc/nginx" nginx
  • 此命令与之前的命令类似,但增加了 -v "${PWD}/conf:/etc/nginx",这意味着宿主机的 conf 文件夹被挂载到容器的 /etc/nginx 目录。这允许用户自定义 Nginx 配置。

6. 详细展开 error_log /var/log/nginx/error.log notice;

在 Nginx 的配置文件中,error_log 指令用于指定错误日志的存储位置和记录级别。这是关于服务器运行中的问题(例如配置错误、客户端连接问题等)的关键诊断信息。下面详细解释这个配置项:

语法

nginx
error_log path [level];
  • path: 指定日志文件的存储路径。
  • [level]: 可选参数,用于定义记录日志的级别。如果不指定,默认为 error 级别。

日志级别

Nginx 支持以下几种错误日志级别,从最低到最高分别是:

  • debug: 提供最详细的信息,用于调试。
  • info: 记录一般的信息性消息。
  • notice: 正常但重要的条件,通常是一些关键事件的记录。
  • warn: 警告级别,表示有一些非错误的异常发生,但仍需留意。
  • error: 发生错误,无法执行某个请求或操作。
  • crit: 严重情况,这种级别的错误影响到多个请求或整个系统的稳定性。
  • alert: 必须立即采取行动的问题。
  • emerg: 紧急情况,通常是系统不可用。

示例和解释

在你的 Nginx 配置中:

nginx
error_log  /var/log/nginx/error.log notice;
  • /var/log/nginx/error.log: 这是日志文件的存放路径。在 Linux 系统中,/var/log/nginx 是 Nginx 日志文件的标准目录。
  • notice: 这个级别意味着日志中将记录所有 notice 级别以上的消息(包括 warn, error, crit, alert, 和 emerg 级别的消息)。

应用场景

使用 notice 级别的好处是它可以捕捉到正常操作中的关键事件,而不会记录大量的详细调试信息。这在生产环境中非常有用,因为它既不会生成过多的日志文件,也能提供足够的信息来追踪潜在的问题。例如,它可以帮助管理员了解到如何调整系统配置,优化性能,或是诊断配置中的错误。

总的来说,适当选择错误日志的级别对于维护和监控 Nginx 服务器是非常重要的,它直接影响到日志文件的大小和日志内容的有用性。

log_format 指令

在 Nginx 配置文件中,log_format 指令用于定义日志文件的格式。通过定制化日志格式,管理员可以根据需要选择性地记录请求和响应的详细信息。这对于问题调试、性能监测、安全审查等都非常有帮助。下面是你的配置中 log_format 的详细解释:

语法

nginx
log_format name string ...;
  • name: 定义日志格式的名称,在 access_log 指令中引用此名称。
  • string ...: 日志格式的具体内容,可以包含文字和变量。

配置中的 log_format 示例

nginx
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
  • main: 这是此日志格式的名称,可以在 access_log 指令中引用它来使用这种格式记录日志。

  • 格式字符串中包含了多个变量和文字,下面是各个变量的含义:

    • $remote_addr: 客户端的 IP 地址。
    • $remote_user: 如果使用了 HTTP 基本认证,这里会显示被认证的用户名。
    • $time_local: 请求到达服务器的本地时间。
    • $request: 客户端的请求行,通常包含 HTTP 方法、请求的 URI 和 HTTP 协议版本。
    • $status: 响应的 HTTP 状态码。
    • $body_bytes_sent: 发送给客户端的响应体的字节数,不包括响应头。
    • $http_referer: 引用当前请求的上一网页的 URL(即“来路”信息)。
    • $http_user_agent: 客户端的 user-agent 字符串,包含有关客户端软件的信息。
    • $http_x_forwarded_for: 表示请求的来源地址,通常用于识别通过 HTTP 代理或负载均衡器转发的客户端原始 IP 地址。
txt
172.17.0.1 - - [25/Apr/2024:16:22:58 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"

应用场景

使用这种详细的日志格式可以帮助你分析和理解:

  • 用户访问来源,包括地理位置(通过 IP 地址)和引用网页。
  • 客户端的设备和浏览器类型(通过用户代理信息)。
  • 网站的哪些页面或资源收到最多的访问以及响应状态,有助于优化用户体验。
  • 问题诊断,如哪些请求返回了错误的状态码或产生了大量数据传输。

在实际的服务器运维中,这样的日志信息对于实现有效的监控、警报和长期的性能优化至关重要。它也使得安全团队能够追踪潜在的恶意活动或异常行为。通过调整 log_format,你可以确保记录下对特定场景最有用的信息。

详细展开 access_log /var/log/nginx/access.log main;

在 Nginx 配置中,access_log 指令用来指定访问日志文件的路径和格式,这是监控和分析服务器流量的重要工具。访问日志记录了关于每个请求的信息,包括客户端的 IP 地址、请求的时间、请求的页面、HTTP 状态码等。这些信息对于调试、安全监控和性能分析都非常重要。下面是对 access_log 指令的详细展开:

语法

nginx
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
  • path: 指定日志文件的存放路径。可以设置为 off 关闭访问日志记录。
  • format: 可选,定义日志的格式。这个格式必须是之前用 log_format 指令定义的名称。
  • buffer=size: 可选,指定写入日志的内存缓冲区大小。
  • gzip[=level]: 可选,开启压缩,并可指定压缩级别。
  • flush=time: 可选,指定日志写入磁盘的时间间隔。
  • if=condition: 可选,根据条件写入日志。

配置示例和解释

在你的 Nginx 配置文件中,access_log 如下所示:

nginx
access_log  /var/log/nginx/access.log  main;
  • /var/log/nginx/access.log: 这是访问日志文件存放的路径。/var/log/nginx 是标准的 Nginx 日志目录,而 access.log 是常用的文件名,用于存储访问日志。
  • main: 指定使用名为 main 的日志格式,该格式应该已经在配置中通过 log_format 指令定义。此格式决定了日志文件中每条记录的具体内容。

功能和应用场景

  • 监控与安全分析:通过分析访问日志,管理员可以检测到潜在的安全威胁,如暴力破解攻击、注入攻击等,并监控网站的访问模式。
  • 性能评估:日志数据可以用来识别高流量的时间段,页面或功能,帮助优化网站性能和资源分配。
  • 用户行为分析:通过记录的请求和来源页面,可以分析用户行为和偏好,优化网站结构和内容。
  • 错误诊断:在出现问题时,访问日志提供了请求的详细历史,帮助快速定位问题源头。

总的来说,access_log 指令是 Nginx 配置中不可或缺的一部分,对于确保网站的稳定运行和安全具有重要作用。通过精心设计的日志格式,可以获得对业务和技术都极具价值的数据。

nginx logs 日志格式和日志时区

1. Dockerfile 编写

Dockerfile
# 使用官方Nginx基础镜像
FROM nginx:latest

2. 构建镜像

bash
docker build -t log-nginx .
bash
docker images

3. 运行镜像

bash
docker run --name mynginx -d -p 8080:80 -v "${PWD}/logs:/var/log/nginx" log-nginx
bash
docker ps -a

浏览器访问:

http://localhost:8080/

logs/access.log 日志信息如下:

txt
172.17.0.1 - - [25/Apr/2024:20:12:35 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"

4. 拷贝 容器的默认 nginx.conf 配置文件

bash
docker cp mynginx:/etc/nginx/nginx.conf ./nginx.conf

nginx.conf

nginx

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

5. 修改日期格式

  • $time_local - 默认
  • $time_iso8601

nginx.conf 的$time_local修改为 $time_iso8601 查看 logs/access.log 日志信息的变化

修改前

nginx
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

修改后

nginx
    log_format  main  '$remote_addr - $remote_user [$time_iso8601] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

Dockerfile

nginx
# 使用官方Nginx基础镜像
FROM nginx:latest
# 复制Nginx配置文件
COPY ./nginx.conf /etc/nginx/nginx.conf

删除正在运行的容器

bash
docker rm -f mynginx

重新构建镜像

bash
docker build -t log-nginx .

重新运行容器

bash
docker run --name mynginx -d -p 8080:80 -v "${PWD}/logs:/var/log/nginx" log-nginx

浏览器访问 http://localhost:8080

查看 logs/access.log 日志信息的变化,默认是零时区

txt
172.17.0.1 - - [25/Apr/2024:20:12:35 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [2024-04-25T20:18:53+00:00] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [2024-04-25T20:18:53+00:00] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"

6. 修改时区

Dockerfile

nginx
# 使用官方Nginx基础镜像
FROM nginx:latest

# 设置环境变量
ENV TZ=Asia/Shanghai

# 运行命令设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 复制Nginx配置文件
COPY ./nginx.conf /etc/nginx/nginx.conf

# 其他配置...

# 暴露端口
EXPOSE 80

# 启动Nginx
CMD ["nginx", "-g", "daemon off;"]

重新构建镜像

bash
docker build -t log-nginx .

删除正在运行的容器

bash
docker rm -f mynginx

重新运行

bash
docker run --name mynginx -d -p 8080:80 -v "${PWD}/logs:/var/log/nginx" log-nginx

浏览器访问 http://localhost:8080

查看 logs/access.log 日志信息的变化,现在是北京时间 2024-04-26T04:22:07+08:00

txt
172.17.0.1 - - [25/Apr/2024:20:12:35 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [2024-04-25T20:18:53+00:00] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [2024-04-25T20:18:53+00:00] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"
172.17.0.1 - - [2024-04-26T04:22:07+08:00] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"

7. 自定义时间格式

代码参考

nginx.conf

nginx
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # 自定义时间变量 $log_time
    map $time_iso8601 $log_time {
        "~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2})" "${year}-${month}-${day} ${hour}:${minutes}:${seconds}";
    }
    log_format  main  '$remote_addr - $remote_user [$log_time] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

8. log 日志改为 json 行方式(作业)

txt
{"log_time":"2024-04-26 04:22:07","remote_addr":"172.17.0.1","request":"GET / HTTP/1.1","status":200,"body_bytes_sent":615,"http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"}
{"log_time":"2024-04-26 04:22:07","remote_addr":"172.17.0.1","request":"GET / HTTP/1.1","status":304,"body_bytes_sent":0,"http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"}
{"log_time":"2024-04-26 04:22:07","remote_addr":"172.17.0.1","request":"GET / HTTP/1.1","status":304,"body_bytes_sent":0,"http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"}