一、自定义日志格式
1.1、日志格式定义
Nginx提供了很多变量用来记录请求中的各种信息,可以根据这些变量来自定义日志格式。将日志格式的定义放在主配置文件“nginx.conf”的http {}
配置段中,方便将其应用到所有虚拟主机的日志中:
# vim /usr/local/nginx/conf/nginx.conf
http {
……
log_format main '$remote_addr - $remote_user [$time_local] "$scheme://$host$request_uri $server_protocol" '
'$status $body_bytes_sent $request_length "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time" "$upstream_response_time"';
……
include vhosts/*.conf;
}
说明:
- log_format:用来定义日志格式的字段;
- main:自定义日志格式的名称;
- include:日志的定义要放在include包含的虚拟主机之前,否则将会报错找不到日志格式:“[emerg] unknown log format “main””
1.2、使用自定义的日志
在虚拟主机中使用自定义的日志格式,只需要将自定义的日志格式的名称放在日志文件路径之后即可:
server {
listen 80;
server_name www.test.com;
access_log /usr/local/nginx/logs/www_test_com.log main;
……
重新加载Nginx配置文件后,做访问测试:
192.168.18.1 - - [30/Dec/2020:14:50:29 +0800] "http://www.test.com/ HTTP/1.1" 200 245 430 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "-" "0.000" "-"
1.3、变量说明
- $remote_addr:直接与Nginx服务器建立TCP连接的客户端IP地址。如果用户使用代理,则记录代理IP;如果没有使用代理,则记录客户端IP;
- $remote_user:当Nginx服务器开启安全认证时,记录客户端用于认证的用户名;
- $time_local:Nginx服务器时间;
- $scheme:客户端请求中的scheme,如“http://www.test.com”中的“http”;
- $host:HTTP请求报文中的Host;
- $request_uri:客户端请求的资源名称;
- $server_protocol:Nginx服务器使用的HTTP协议,如HTTP/1.1;
- $status:Nginx服务器响应状态码,如200、404;
- $body_bytes_sent:Nginx服务器响应给客户端的body大小;
- $http_referer:客户端是从哪个地址跳转到本服务器地址,可用于防盗链;
- $http_user_agent:HTTP请求报文中的请求头,用于表示客户端访问设备;
- $http_x_forwarded_for:HTTP请求携带的信息,通常用于Nginx反向代理或负载均衡服务器向后端服务器传递客户端真实IP。如果用户直接访问Nginx或反向代理服务器,则X-Forwarded-For(XFF)记录用户真实IP。如果用户到Web服务器之间有一层或多层代理,并且代理没有使用XFF,那XFF列表的第一位记录离用户最近的代理IP,最后的Nginx反向代理将其上一级代理的IP追加到XFF列表末尾,自身的IP将被记录到remoteAddress中。XFF在请求头中可以被伪造,remoteAddress则无法伪造;
- $request_time:从接受用户请求的第一个字节到发送完响应数据的时间;
- $upstream_response_time:Nginx作为反向代理或负载均衡服务器时,从与后端服务器建立连接到接收完响应数据关闭连接的时间。
二、Nginx日志切割
Nginx日志文件会随着访问量的增多而增大,达到一定量时,从日志文件中检索数据将会非常缓慢。所以需要对Nginx日志文件按一定的时间周期做拆分,避免日志文件异常大导致的问题。
这里通过shell脚本和计划任务,对Nginx日志文件按天切割。脚本内容如下:
#!/bin/bash
#Author: Ops
#Function: Nginx log file cutting.
# 声明时间变量:
Date=$(date -d yesterday +%Y-%m-%d)
# Nginx日志文件存放路径:
SourceDir="/usr/local/nginx/logs"
# 日志文件备份路径:
BackupDir="/backup/nginx/logs"
# Nginx进程ID文件
PidFile="/usr/local/nginx/logs/nginx.pid"
# 检查备份路径是否存在,不存在时自动创建:
test -d ${BackupDir} || mkdir -p ${BackupDir}
for LogFile in $(ls ${SourceDir}/*.log)
do
# 去掉日志文件绝对路径的目录,只保留文件名:
LogFileName=${LogFile#$SourceDir}
# 再去掉文件名的.log后缀:
LogName=${LogFilePrefix%.log}
# 移动日志文件:
mv ${SourceDir}${LogName}.log ${BackupDir}${LogName}-${Date}.log
done
# 平滑重启Nginx:
kill -USR1 $(cat ${PidFile})
添加定时任务,每天00:01执行脚本:
# crontab -l
1 0 * * * sh /root/cutnginxlog.sh