一、脚本思路

第一步就是重命名日志文件,不用担心重命名后nginx找不到日志文件而丢失日志。在你未重新打开原名字的日志文件前,nginx还是会向你重命名的文件写日志,linux是靠文件描述符而不是文件名定位文件。
第二步向nginx主进程发送usr1信号。
nginx主进程接到信号后会从配置文件中读取日志文件名称,重新打开日志文件(以配置文件中的日志名称命名),并以工作进程的用户作为日志文件的所有者。
重新打开日志文件后,nginx主进程会关闭重名的日志文件并通知工作进程使用新打开的日志文件。
工作进程立刻打开新的日志文件并关闭重名名的日志文件。
然后你就可以处理旧的日志文件了。

二、脚本实现

nginx日志按日期自动切割脚本如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
#nginx日志切割脚本
 
#!/bin/bash
#设置日志文件存放目录
logs_path= "/usr/local/nginx/logs/"
#设置pid文件
pid_path= "/usr/local/nginx/nginx.pid"
 
#重命名日志文件
mv ${logs_path}access.log ${logs_path}access_$( date -d  "yesterday" + "%y%m%d" ).log
 
#向nginx主进程发信号重新打开日志
kill -usr1 ` cat ${pid_path}`


试验环境:

?

1
2
3
4
5
# cat /etc/redhat-release
red hat enterprise linux server release 5.3 (tikanga)
 
# /opt/nginx/nginx -v
nginx version: nginx /1 .6.2

代码:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# ==============================================================================
# chmod u+x /opt/nginx/cut_nginx_log.sh
# crontab -e
# 0 0 * * * /opt/nginx/cut_nginx_log.sh > /opt/nginx/logs/cut_nginx_log.log 2>&1
# ==============================================================================
 
logs_path= "/opt/nginx/logs"
archive_year=$( date -d  "yesterday" "+%y" )
archive_month=$( date -d  "yesterday" "+%m" )
archive_date=$( date -d  "yesterday" "+%y%m%d_%h%m%s" )
if [ -r  /opt/nginx/nginx .pid ];  then
   mkdir -p  "${logs_path}/${archive_year}/${archive_month}"
   mv "${logs_path}/access.log" "${logs_path}/${archive_year}/${archive_month}/access_${archive_date}.log"
   kill -usr1 $( cat "/opt/nginx/nginx.pid" )
   sleep 1
   gzip "${logs_path}/${archive_year}/${archive_month}/access_${archive_date}.log"
else
   echo "nginx might be down"
fi
 
# ==============================================================================
# clean up log files older than 100 days
# ==============================================================================
 
# change housekeeping=1 to enable clean up
housekeeping=0
keep_days=100
if [ $housekeeping == 1 ];  then
   if [ -d  "${logs_path}" ];  then
     find "${logs_path}" - type f -name  "access_*.log.gz" -mtime +${keep_days} - exec rm -f {} \;
   fi
fi

参考:
http://wiki.nginx.org/logrotation

保存以上脚本nginx_log.sh,并设置定时切割任务

三、定时工作
在crontab中设置作业

复制代码 代码如下:

0 0 * * * bash /usr/local/nginx/nginx_log.sh


这样就每天的0点0分把nginx日志重命名为日期格式,并重新生成今天的新日志文件