nginx配置系列-日志切割
背景
nginx日志中我们希望日志能够每天或者每小时自动切割,nginx本身没有提供自动切割的机制,但是我们可以通过脚本或者稍加改造让其具备这种能力。下面让我们看看怎么操作吧。
日志切割
常见做法有四种,在我们做之前我们来学习一下nginx日志中常用的内置变量字段都是什么意思
nginx内置变量
变量名称 | 变量描述 |
---|---|
$arg_PARAMETER | 客户端GET请求中PARAMETER 字段的值 |
$args | 客户端请求中的参数 |
$binary_remote_addr | 远程地址的二进制表示 |
$body_bytes_sent | 已发送的消息体字节数 |
$content_length | HTTP请求信息中content-length的字段 |
$content_type | 请求信息中content-type字段 |
$cookie_COOKIE | 客户端请求中COOKIE头域的值 |
$document_root | 针对当前请求的根路径设置值 |
$document_uri | 与$uri相同 |
$host | 请求信息中的host头域,如果请求中没有Host行,则等于设置的服务器名 |
$http_HEADER | HTTP请求信息里的HEADER地段 |
$http_host | 与$host相同,但是如果请求信息中没有host行,则可能不同客户端cookie信息 |
$http_cookie | 客户端cookie信息 |
$http_referer | 客户端是从哪一个地址跳转过来的 |
$http_user_agent | 客户端代理信息,也就是你客户端浏览器 |
$http_via | 最后一个访问服务器的IP |
$http_x_forwarded_for | X-Forwarded-For 是一个扩展头, 用来表示HTTP 请求端真实IP |
$is_args | 如果有args的值,则等于”?”,否则为空 |
$limit_rate | 对连接速率的限制 |
$nginx_version | 当前Nginx的版本 |
$pid | 当前Nginx服务器的进程的进程ID |
$query_string | 与$args相同 |
$remote_addr | 客户端IP地址 |
$remote_port | 客户端的端口 |
$remote_user | 客户端的用户名,用于 auth basic module验证 |
$request | 客户端请求 |
$request_body | 客户端发送的报文体 |
$request_body_file | 发送后端服务器的本地临时缓存文件的名称 |
$request_filename | 当前请求的文件路径名,由root或alias指令与URI请求生成 |
$request_method | 请求后端数据的方法,例如”GET”,”POST” |
$request_uri | 请求的URI,带参数,不包含主机名 |
$scheme | 所用的协议,如http或者HTTPS,比如rewrite^(.+)$$scheme://mysite.name$redirect |
$sent_http_cache_control | 对应http请求头中的Cache-Control,需要打开chrome浏览器,右键检查,选中network,点中其中一个请求的资源 |
$sent_http_connection | 对应http请求中的Connection |
$sent_http_content_type | 对应http请求中的Content-Type |
$sent_last_modified | 对应请求中的Last-Modified |
$server_addr | 服务端的地址 |
$server_name | 请求到达的服务器名 |
$server_port | 请求到达服务器端口号 |
$server_protocol | 请求协议的版本号,HTTP1.0/HTTP1.1 |
$uri | 请求的不带请求参数的URI,可能和最初的值有不同,比如经过重定向之类的 |
$request_time | nginx接收到请求到发送给client端数据包耗时 |
$upstream_response_time | nginx后端服务器的响应时间 |
$http_user_agent | 用户客户端UA标识 |
nginx4中日志切割法
1. 全局通用配置,http模块里设置,这样所有域名的访问日志都会被记录下来
http {
#.....
#设置变量 year month day hour minutes seconds
map $time_iso8601 $year {
default '0000';
"~^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" $1;
}
map $time_iso8601 $month {
default '00';
"~^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" $2;
}
map $time_iso8601 $day {
default '00';
"~^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" $3;
}
map $time_iso8601 $hour {
default '00';
"~^^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" $4;
}
map $time_iso8601 $minutes {
default '00';
"~^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" $5;
}
map $time_iso8601 $seconds {
default '00';
"~^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" $6;
}
# 日志格式
log_format commonlog 'v1{|]$remote_addr:$remote_port{|]$http_x_forwarded_for{|]$upstream_addr{|]$time_iso8601{|]$request_method{|]$h
ost{|]$uri{|]$args{|]$status{|]$http_referer{|]$body_bytes_sent{|]$request_time{|]$upstream_response_time{|]$http_user_agent{|]$sent_
http_location{|]$http_cookie{|]$sent_http_content_type{|]$request_body{|]';
#记录日志,按天切割,也可以根据需要按小时切割
access_log logs/access_$year$month$day.log commonlog;
#.....
}
2. 在每个域名配置里设置日志按日期切割
年月日这些时间变量均为自定义,需要在每一个server下面添加这个代码
server {
#....
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
set $hour $4;
set $minutes $5;
set $seconds $6;
}
#记录日志,按天切割,也可以根据需要按小时切割
access_log logs/access_$host_$year$month$day.log commonlog;
#....
}
3. 自定义脚本切割
cat cut_nginx_log.sh
#!/bin/bash
# Description: rotate nginx access logs
#增加定时任务
crontab -l|grep cut_nginx_log.sh|grep -v grep || echo '0 0 * * * /somepath/cut_nginx_log.sh > /dev/null 2>&1' >> /var/spool/cron/root
LOGS_DIR="/path/nginx/logs"
NGX_PID=`cat $LOGS_DIR/nginx.pid`
WWW_LOG_NAME="access.log"
cd $LOGS_DIR
/usr/bin/mv $WWW_LOG_NAME $WWW_LOG_NAME.$(date +%F -d 'yesterday')
/bin/kill -USR1 $NGX_PID
4. logrotate 切割nginx日志
#安装logrotate
yum install logrotate
安装完成后,自动在/etc/cron.daily/下生成个logrotate脚本文件。
cd /etc/logrotate.d/
vim nginx 内容如下:
/path/nginx/logs/*log {
su root www
create 600 www www
daily
dateext
rotate 10
missingok
notifempty
compress
sharedscripts
olddir /path/nginx/logs/oldlogs # 这个目录要事先创建好,并给相关权限
postrotate
kill -USR1 `cat /path/nginx/logs/nginx.pid`
endscript
}
#设置定时任务
crontab -e
59 23 * * * /usr/sbin/logrotate -f /etc/logrotate.d/nginx