Nginx(三):日志文件管理

时间:2022-12-16 08:11:13

一、Nginx日志描述

通过访问日志,你可以得到用户地域来源、跳转来源、使用终端、某个URL访问量等相关信息;

通过错误日志,你可以得到系统某个服务或server的性能瓶颈等。因此,将日志好好利用,你可以得到很多有价值的信息。

打开nginx.conf配置文件:vim /usr/local/nginx/conf/nginx.conf

Nginx日志相关的指令主要有两条,一条是log_format,用来设置日志的格式,另外一条是access_log,用来指定日志文件的存放路径、格式和缓存大小两条指令在Nginx配置文件中的位置可以在http{......}之间,也可以在虚拟主机之间,即server{......}两个大括号之间

二、用log_format指令设置日志格式

log_format指令用来设置日志的记录格式,它的语法如下:

log_format name format [format...]

其中name表示定义的格式名称,format表示定义的格式样式。log_format有一个默认的、无须设置的combined日志格式设置,也就是“main”日志格式,相当于Apache的combined日志格式,其具体参数如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent"';
#access_log  logs/access.log  main;

您也可以自定义一份日志的记录格式,不过要注意,log_format指令设置的name名称在Nginx 配置文件中是不能重复的

假设将 Nginx 服务器作为 Web 服务器,位于负载均衡设备、 Squid 、Nginx 反向代理之后, 就不能获取到客户端的真实IP地址了。原因是经过反向代理后,由于在客户端和 Web 服务器之 间地加了中间层,因此 Web 服务器无法直接拿到客户端的 IP,通过$remote_addr 变量拿到的将是反向代理服务器的 IP 地址。但是,反向代理服务器在转发请求的 HTTP 头信息中,可以增加 X-Forwarded-For信息,用以记录原有的客户端 IP 地址和原来客户端请求的服务器地址。 

这时候,就要用 log_format 指令来设置日志格式 ,让日志记录 X-Forwarded-For 信息中的IP 地址 ,即客户的真实IP。 

例如,创建一个名为mylogformat的日志格式,再$http_x_forwarded_forlog_for变量记录用户的X_Forwarded-For IP 地址:

log_format mylogformat '$http_x_forwarded_for_$remote_user [$time_local]''"$request" $status $body_bytes_sent'
 '"$http_referer" "$http_user_agent"'

日志格式参数明细表:

$remote_addr

客户端的ip地址(代理服务器,显示代理服务ip)

$remote_user

用于记录远程客户端的用户名称(一般为“-”)

$time_local

用于记录访问时间和时区

$request

用于记录请求的url以及请求方法

$status

响应状态码,例如:200成功、404页面找不到等。

$body_bytes_sent

给客户端发送的文件主体内容字节数

$http_user_agent

用户所使用的代理(一般为浏览器)

$http_x_forwarded_for

可以记录客户端IP,通过代理服务器来记录客户端的ip地址

$http_referer

可以记录用户是从哪个链接访问过来的

三、用access_log指令指定日志文件存放路径

用 log_format 指令设置了日志格式之后,需要用  access_log 指令指定日志文件存放路径。access_log 指令的语法如下:

access_log path [format [buffer=size | off]]  

其中: 
path 表示日志文件的存放路径; 
format 表示使用 log_format 指令设置的日志格式的名称, 
buffer=size 表示设置内存缓冲区的大小,例如可以设置 buffer=32k。 


(1)如果不想记录日志,可以使用以下指令关闭日志记录: 

access_log off; 

(2)如果想使用默认的 combined 格式的日志记录,可以使用以下示例: 

access_log /data1/1ogs/filename.log; 

或者 

access_log /data1/1ogs/filename.log combined; 

(3)如果想使用自定义格式的日志记录,可以使用以下示例,其中的  mylogformat 是日志格 式名称: 

log_format mylogformat '$remote_addr -  $remote_user  [$time_local] "$request" ‘ 
  ‘$status $body_þytes_sent  "$http_referer" ‘ 
‘ “$http_user_agent'' $http_x_forwarded_for'; 

access_log  /data1/logs/access.log mylogformat buffer=32k; 

(4)在 Nginx 0.7.4之后的版本中,access_log 指令中的日志文件路径可以包含变量,例如: 

access_log /data1/1ogs/$server_name.log combined; 

假设 server_name 指令设置的虚拟主机名称为 test.domain.com ,那么access_log 指令将把访问日志记录在/data1/logs/test.domain.com.log 文件中。 如果日志文件路径中含有变量,将存在以下一些限制

(1) Nginx 进程设置的用户和组必须有对该路径创建文件的权限。假设 Nginx 的 user 指令 设置的用户名和用户组都是  WWW ,而/data1/logs/ 目录的用户名和用户组为 root ,日志文件/data1/logs/test.domain.com.log 将无法被 Nginx 创建: 
(2)缓存将不会被使用; 
(3)对于每一条日志记录,日志文件都将先打开文件,再写入日志记录,然后马上关闭。 为了提高包含变量的日志文件存放路径的性能,需要使用  open_log_file_cache  指令设置经常被使用的日志文件描述符缓存。 

open_log_file_cache  指令主要用来设置含有变量的日志路径的文件描述符缓存,它的语法如下: 

open_log_file_cache  max=N [inactive=time]  [mim_uses=N]  [valid=time]  | off 

该指令默认是禁止的,等同于: 

open_log_file_cache off; 

open_log_file_cache 指令的各项参数说明如下: 

max: 设置缓存中的最大文件描述符数量。如果超过设置的最大文件描述符数量,则采用  LRU (Least Recently Used) 算法清除"较不常使用的文件描述符"。  LRU (Least Recently Used) 算 法的基本概念是:当内存缓冲区剩余的可用空间不够时,缓冲区尽可能地先保留使用者最常使用 的数据,将最近未使用的数据移出内存,腾出空间来加载另外的数据。 
inactive:  设置一个时间,如果在设置的时间内没有使用此文件描述符,则自动删除此描述符。 此参数为可选参数,默认的时间为 10 秒钟。 
min_uses: 在参数 inactive 指定的时间范围内,如果日志文件超过被使用的次数,则将该日 志文件的描述符记入缓存。默认次数为 1。 
valid: 设置多长时间检查一次,看一看变量指定的日志文件路径与文件名是否仍然存在。默 认时间为 60秒。 
off: 禁止使用缓存。 

open_log_file_cache 指令的设置示例如下: 

open_log_file_cache  max=1000  inactive=20s  min_uses=2  valid=1m; 

查看日志命令

tail -f /usr/local/nginx/logs/access.log

 Nginx(三):日志文件管理

打开nginx.conf配置文件去掉#注释见下图:

 Nginx(三):日志文件管理

自定义某一个server配置的日志,使用“main”日志格式。

 Nginx(三):日志文件管理

日志生成的到Nginx根目录logs/access.log文件,默认使用“main”日志格式,也可以自定义格式。

重新读取加载Nginx配置文件:

执行命令

./sbin/nginx -s reload

查看日志文件:

执行命令:

tail -100f /usr/local/nginx/logs/abc.access.log

 Nginx(三):日志文件管理

四、Nginx日志切割

生产环境中的服务器,由于访问日志文件增长速度非常快,日志太大会严重影响服务器效率。 同时,为了方便对日志进行分析计算,须要对日志文件进行定时切割.定时切割的方式有按月切 割、按天切割、按小时切割等。最常用的是按天切割。 

所谓自动分割Nginx日志文件,就是指Rotate Nginx log files,即让Nginx每天(或每个星期,可自定义控制)生成一个日志文件,而不是将Nginx所有的运行日志都放置在一个文件中,这样每个日志文件都相对较小,定位问题也更容易。

比如Nginx产生的访问日志文件默认一直就是一个,不会自动地进行切割,如果访问量很大的话,将导致日志文件容量非常大,不便于管理。当然了,我们也不希望看到这么庞大的一个访问日志文件,那需要手动对这个文件进行切割。

如何切割?

由于 Nginx 的日志都是写在一个文件当中的,因此,我们需要每天零点将前一天的日志存为另外一个文件,这里我们就将 Nginx 位于 logs 目录中的 access.log 存为 access_[yyyy-MM-dd].log 的文件。其实 logs 目录中还有个 error.log 的错误日志文件,这个文件也需要每天切割一个,在这里就说 access.log 了,error.log 的切割方法类似。

在 Linux 平台上进行切割,需要使用 date 命令以获得昨天的日期、使用 kill 命令向 Nginx 进程发送重新打开日志文件的信号,以及 crontab 设置执行任务周期。

crontab Linux计划任务详情参阅这篇:Linux定时任务Crontab命令详解

先创建一个 Shell 脚本,如下:

#!/bin/bash
LOGS_PATH=/usr/local/nginx/logs
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
mv ${LOGS_PATH}/sdk_acc.log ${LOGS_PATH}/sdk_acc_${YESTERDAY}.log
mv ${LOGS_PATH}/sell_acc.log ${LOGS_PATH}/sell_acc_${YESTERDAY}.log
kill -USR1 $(cat /usr/local/nginx/nginx.pid)       ## 向 Nginx 主进程发送 USR1 信号。USR1 信号是重新打开日志文件

上面这个脚本中的最后一行必须向 Nginx 的进程发送 USR1 信号以重新打开日志文件,如果不写的话,Nginx 会继续将日志信息写入 access_[yyyy-MM-dd].log 的那个文件中,这显然是不正确的。

脚本完成后将其存入 Nginx 安装目录的 sbin 中,取名为 cut-log.sh,之后使用 crontab -e 新增一个定时任务,在其中增加执行这个脚本:

0 0 * * * /bin/bash /usr/local/nginx/sbin/cut-log.sh