Nginx 日志详解

213 阅读4分钟

nginx 日志类型

我们进入到nginx目录下的log目录中,可以看到里面存放着三个文件,分别是access.logerror.lognginx.pid文件,其中nginx.pid是用来记录当前nginx进程的pid号的,不属于日志文件。真正属于日志文件的是另外两个文件。

-rw-r--r-- 1 root root 90261926 Jun  9 09:38 access.log
-rw-r--r-- 1 root root 21159964 Jun  8 16:36 error.log
-rw-r--r-- 1 root root        5 May 24 15:18 nginx.pid

日志参数

nginx日志共三个参数
access_log: 定义日志的路径及格式。
log_format: 定义日志的模板。
open_log_file_cache: 定义日志文件缓存。

1.access.log日志文件

access.log文件的介绍

access文件用于存放每个用户访问网站的请求日志,开发运维人员通过访问日志来分析用户的浏览器行为。默认情况下,nginx会在log目录下生成该文件,无需用户配置。

image.png

2.access_log日志配置

access_log用来定义日志级别,日志位置,可以定义在http模块下,也可以定义在server 模块下,或者location 模块下。

image.png

server {
        listen 9600;
        location / {
                root html;
                access_log logs/mine_access.log mine_format;
        }
}


image.png

日志配置语法access_log格式:

用来指定日志文件的路径及使用何种日志格式记录日志

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;

  • 默认值 : access_log logs/access.log combined;
  • 作用域 : http, server, location, if in location, limit_except

实例一:

access_log /spool/logs/nginx-access.log compression buffer=32k;

nginx记录日志的默认参数配置如下:

access_log  logs/access.log  main;

2.定义日志log_format格式

用来定义记录日志的格式(可以定义多种日志格式,取不同的名字即可),其配置位置在http标签内。其中,log_format为日志格式关键参数,不能变。main是为日志格式指定的标签,记录日志时通过这个main标签选择指定的格式。其后所接的所有内容都是可以记录的日志信息,所有的日志段以空格分割,一行可以记录多个,如果不指定日志格式就会采用默认的combined格式记录日志。不同列的意义如下:

语法格式: log_format name [escape=default|json] string ...;  
默认值 : log_format combined "...";  
作用域 : http

实例一

log_format compression '$remote_addr - $remote_user [$time_local] '  
'"$request" $status $bytes_sent '  
'"$http_referer" "$http_user_agent" "$gzip_ratio"';  
  
access_log /spool/logs/nginx-access.log compression buffer=32k;

实例二

image.png

nginx日志格式中默认的参数配置如下:

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

image.png

参数说明示例
$remote_addr 记录访问网站的客户端地址;211.28.65.253
$remote_user远程客户端用户名称;--
$time_local记录访问时间与时区;18/Jul/2012:17:00:01 +0800
$request用户的http请求起始行信息;"GET /article-10000.html HTTP/1.1"
$status  http状态码,记录请求返回的状态,例如200、404、301等;200
$body_bytes_sent服务器发给客户端的响应body字节数;该变量与Apache模块mod_log_config里的“%B”参数兼容1504
$http_referer记录此次请求是从哪个链接访问呢过来的,可以根据referer进行防盗链设置;"http://11.226.40.122:5021/xxx-web/task/home-task"   
$http_user_agent  记录客户端访问信息,例如:浏览器、手机客户端等;"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
$http_x_forwarded_for当前端有代理服务器时,设置web节点记录客户端地址的配置,此参数生效的前提是代理服务器上也进行了相关的x_forwarded_for设置;
$ssl_protocolSSL协议版本TLSv1
$ssl_cipher交换数据中的算法RC4-SHA
$upstream_addr后台upstream的地址,即真正提供服务的主机地址10.10.10.100:80
$request_time整个请求的总时间0.205
$upstream_response_time请求过程中,upstream响应时间0.002
$bytes_sent发送给客户端的总字节数。
$connection连接的序列号
$connection_requests-  当前通过一个连接获得的请求数量。
$msec-  日志写入时间。单位为秒,精度是毫秒。
$pipe如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”
$request_length- 请求的长度(包括请求行,请求头和请求正文)。
$request_time请求处理时间,单位为秒,精度毫秒;从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$time_iso8601 ISO8601- 标准格式下的本地时间。
$time_local- 通用日志格式下的本地时间。

3. open_log_file_cache

使用open_log_file_cache来设置日志文件缓存(默认是off)。

  • max:设置缓存中的最大文件描述符数量,如果缓存被占满,采用LRU算法将描述符关闭。
  • inactive:设置存活时间,默认是10s
  • min_uses:设置在inactive时间段内,日志文件最少使用多少次后,该日志文件描述符记入缓存中,默认是1次
  • valid:设置检查频率,默认60s
  • off:禁用缓存

语法格式: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
默认值: open_log_file_cache off;
作用域: http, server, location

实例一

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

nginx 的日志级别

event 定义日志级别:

debug > info > notice > warn > error > crit > alert > emerg

日志调试技巧

当你设置日志级别成 debug,如果你在调试一个在线的高流量网站的话,你的错误日志可能会记录每个请求的很多消息,这样会变得毫无意义。

events{...}

中配置如下内容,可以使 Nginx 记录仅仅来自于你的 IP 的错误日志。

events {  
debug_connection 1.2.3.4;  
}

调试 nginx rewrite 规则

调试rewrite规则时,如果规则写错只会看见一个404页面,可以在配置文件中开启nginx rewrite日志,进行调试。

server {  
error_log /var/logs/nginx/example.com.error.log;  
rewrite_log on;  
}

rewrite_log on;

开启后,它将发送所有的 rewrite 相关的日志信息到 error_log 文件中,使用 [notice] 级别。随后就可以在error_log 查看rewrite信息了。

proxy_set_header X-Forwarded-For :如果后端Web服务器上的程序需要获取用户IP,从该Header头获取。 proxy_set_header X-Forwarded-For $remote_addr;

nginx访问日志轮训切割

默认情况下nginx会把所有的访问日志生成到一个指定的访问日志文件access_log里,但这样一来,时间长了就会导致日志文件很大,不利于日志的分析和处理,因此,有必要对nginx日志按天或小时进行切割,使其分成不同的文件保存。这里使用按天切割的方法。 具体切割脚本如下:

[root@nginx shell]# cat cut_nginx_log.sh
#!/bin/bash
#Author:Mr.Ding
#Created Time:2018-08-27 07:19:30
#Name:cut_nginx_log.sh
#Description:
Dateformat=`date +%Y%m%d`
Basedir="/application/nginx"
Nginxlogdir="$Basedir/logs"
Logname="access_dmtest1"
[ -d $Nginxlogdir ] && cd $Nginxlogdir || exit 1
[ -f ${Logname}.log ] || exit 1
/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log
#$Basedir/sbin/nginx -s reload
systemctl reload nginx

脚本实现切割nginx的思想为将正在写入的nginx日志(access_dmtest1.log)改名为带日期的格式文件(20180827_access_dmtest1.log),然后平滑重新加载nginx,生成新的nginx日志(access_dmtest1.log)。 把脚本加入计划任务:

[root@nginx shell]# cat >>/var/spool/cron/root << EOF
> #cut ngixn access log by dm 2018-8-27
> 00 00 * * * /bin/sh /server/scripts/shell/cut_nginx_log.sh >/dev/null 2&1
> EOF
[root@nginx shell]# crontab -l
#time sync by dm at 2018-8-20
*/5 * * * * /usr/sbin/ntpdate -u ntp.api.bz >/dev/null 2>$1
#cut ngixn access log by dm 2018-8-27
00 00 * * * /bin/sh /server/scripts/shell/cut_nginx_log.sh >/dev/null 2&1

最终日志切割效果如下:

[root@nginx logs]# ll
总用量 32
-rw-r--r-- 1 root root     0 8月  27 07:35 20180827_access_dmtest1.log
-rw-r--r-- 1 root root     0 8月  27 07:35 access_dmtest1.log
-rw-r--r-- 1 root root 14076 8月  27 04:41 access.log
-rw-r--r-- 1 root root 10098 8月  27 06:36 error.log
-rw-r--r-- 1 root root     5 8月  26 21:56 nginx.pid