1. Nginx访问日志介绍
Nginx软件会把每隔用户访问网站的日志信息记录到指定的日志文件里,供网站提供者分析用户浏览行为等,此功能由ngx_http_log_module模块负责。
2. 访问日志参数
Nginx的访问日志主要由下表中的两个参数控制。
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记录日志的默认参数配置如下:
access_log logs/access.log main;
3. 访问日志配置说明
3.1 日志格式定义说明
定义语法 log_format name string ...;
配置位置 http标签内
日志格式说明如下:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
其中,log_format为日志格式关键参数,不能变。
main是为日志格式指定的标签,记录日志时通过这个main标签选择指定的格式。其后所接的所有内容都是可以记录的日志的信息,具体见下表。注意,所有的日志段以空格分隔,一行可以记录多个,不同列的意义也在下表中进行了说明。
在没有特殊要求的情况下,采用默认的配置即可。
3.2 记录日志的access_log参数说明
语法:
access_log path [format [buffer=size [flush=time]] [if=condition]];
access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
access_log syslog:server=address[,parameter=value] [format [if=condition]];
buffer=size为存放访问日志的缓冲区大小,flush=time为将缓冲区的日志刷到磁盘的时间,gzip[=level]表示压缩级别,[if=condition]表示其他条件,一般的场景,这些参数都无需配置,极端优化才可能会考虑这些参数。
access_log off中的off,表示不记录访问日志。
默认配置:access_log logs/access.log combined;
放置位置:HTTP、Server、Location、if in location、limit_except。
4. 配置访问日志实战
编辑主配置文件nginx.conf,配置日志的格式如下:
[root@web01 conf]# sed -n '21,23 s/#//gp' nginx.conf.default
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
把上述内容放入到nginx.conf的HTTP标签的首部,配置完后的结果如下:
[root@web01 conf]# cat -n nginx.conf
1 worker_processes 1;
2 error_log logs/error.log
3 events {
4 worker_connections 1024;
5 }
6 http {
7 include mime.types;
8 default_type application/octet-stream;
9 sendfile on;
10 keepalive_timeout 65;
11 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
12 '$status $body_bytes_sent "$http_referer" '
13 '"$http_user_agent" "$http_x_forwarded_for"';
14 include extra/01_www.conf;
15 include extra/02_bbs.conf;
16 include extra/03_blog.conf;
17 include extra/04_status.conf;
18 }
然后配置在每个虚拟主机里使用上述格式记录用户访问日志,以www.etiantian.org站点为例:
[root@web01 conf]# cat extra/01_www.conf
server {
listen 80;
server_name www.etiantian.org etiantian.org;
location / {
root html/www;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
access_log logs/access_www.log main;
}
如果不指定日志格式就会用默认的combined格式记录日志。
接下来,要检查语法,重新加载配置:
[root@web01 conf]# nginx -t
nginx: the configuration file /application/nginx-1.16.0//conf/nginx.conf syntax is ok
nginx: configuration file /application/nginx-1.16.0//conf/nginx.conf test is successful
[root@web01 conf]# nginx -s reload
下面用浏览器模拟用户访问生成日志,在服务器上查看日志结果:
[root@web01 conf]# curl www.etiantian.org ---测试访问
http://www.etiantian.org
[root@web01 conf]# cat /application/nginx/logs/access_www.log ---查看日志
192.168.9.7 - - [23/Mar/2020:02:20:36 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
[root@web01 conf]# curl 192.168.9.7 ---测试IP访问
http://www.etiantian.org
[root@web01 conf]# cat /application/nginx/logs/access_www.log
192.168.9.7 - - [23/Mar/2020:02:20:36 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
192.168.9.7 - - [23/Mar/2020:02:21:20 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
[root@web01 conf]# nginx -s stop
[root@web01 conf]# nginx
[root@web01 conf]# curl 192.168.9.7
http://www.etiantian.org
[root@web01 conf]# curl 192.168.9.7
http://www.etiantian.org
[root@web01 conf]# curl www.etiantian.org
http://www.etiantian.org
[root@web01 conf]# cat /application/nginx/logs/access_www.log ---一切正常
192.168.9.7 - - [23/Mar/2020:02:20:36 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
192.168.9.7 - - [23/Mar/2020:02:21:20 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
192.168.9.7 - - [23/Mar/2020:02:21:44 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
192.168.9.7 - - [23/Mar/2020:02:21:48 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
192.168.9.7 - - [23/Mar/2020:02:21:58 +0800] "GET / HTTP/1.1" 200 25 "-" "curl/7.29.0" "-"
使用谷歌浏览器访问的日志结果如下:
[root@web01 conf]# cat /application/nginx/logs/access_www.log
192.168.9.1 - - [23/Mar/2020:02:24:28 +0800] "GET / HTTP/1.1" 200 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "-"
192.168.9.1 - - [23/Mar/2020:02:24:28 +0800] "GET /favicon.ico HTTP/1.1" 404 555 "http://192.168.9.7/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "-"
可以根据生成的日志对比下上述log_format的日志格式,看是否对应。
定义的日志格式为:
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
真实的日志内容为:
192.168.9.1 - - [23/Mar/2020:02:24:28 +0800] "GET / HTTP/1.1" 200 25 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" "-"
对应说明:
- $remote_addr 对应的真实日志里的192.168.9.1,即客户端IP。
- $remote_user 对应的是第二个中杠“-”,没有远程用户,所以用“-”填充。
- [$time_local] 对应的是[23/Mar/2020:02:24:28 +0800]。
- "$request" 对应的是"GET / HTTP/1.1"。
- $status 对应的是200状态码,200是正常访问。
- $body_bytes_sent 对应的是25字节,相应body的大小。
- $http_referer" 对应的是“-”,直接打开的域名浏览,因此,referer没有值。
- "$http_user_agent" 对应的是"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"。
- "$http_x_forwarded_for" 对应的是“-”,因为Web服务没有使用代理,因此此处为“-”。
下面针对日志配置进行深入说明。
可以在记录日志参数中加上buffer和flush选项,这样做会在高并发场景下提升网站访问性能。加该选项的命令如下:
access_log path [format [buffer=size [flush=time]] [if=condition]];
access_log path format gzip[=level] [buffer=size] [flush=time] [if=condition];
access_log syslog:server=address[,parameter=value] [format [if=condition]];
access_log off;
具体配置如下:
[root@web01 conf]# cat extra/01_www.conf
server {
listen 80;
server_name www.etiantian.org etiantian.org;
location / {
root html/www;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
access_log logs/access_www.log main gzip buffer=12k flush=5s;
}
5. Nginx访问日志轮询切割
默认情况Nginx会把所有的访问日志生成到一个指定的访问日志文件access.log里,但这样一来,时间长了就会导致日志内容很多,不利于分析日志和处理,因此,有必要对Nginx按天或按小时切割成不同的文件进行保留,Nginx日志轮询有很多方法,如利用系统默认的logrotate工具,这里使用Shell脚本实现按天切割的方法。
[root@web01 conf]# cat /server/scripts/cut_nginx_log.sh
#!/bin/bash
Dateformat='date +%Y%m%d -d -1day'
Basedir="/application/nginx"
Nginxlogdir="$Basedir/logs"
Logname="access_www"
[ -d $Nginxlogdir ] && cd $Nginxlogdir||exit 1
[ -f ${Logname}.log ]||exit 1
/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log
$Basedir/sbin/nginx -s reload
注意:脚本实现切割Nginx日志的思路为将正在写入的Nginx日志(access_www.log)改名为带日期的格式文件(20200324_access_www.log),然后平滑重新加载Nginx,生成新的Nginx日志(access_www.log)。
下面通过定时任务实现每天00:00点整定时执行/server/scripts/cut_nginx_log.sh切割日志。
[root@web01 conf]# cat >>/var/spool/cron/root << EOF
> #cut nginx access log by zheng
> 00 00 * * * /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2>&1
> EOF
[root@web01 conf]# crontab -l|tail -2
#cut nginx access log by zheng
00 00 * * * /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2>&1
Nginx常用日志收集及分析工具有rsyslog、awstats、flume、ELK(Elasticsearch logstash Kibana)、storm等。