nginx日志切分
Nginx Log Rotation日志正确切分与定期删除
一般场景:Nginx Log Rotation日志需要定期进行切分,操作,再定期删除。
1. 为啥不用 cp
而用 mv
?
Section titled “1. 为啥不用 cp 而用 mv?”简单的说就是:
mv
没有改变源文件的任何内容以及 inode 属性,也没有创建新文件,这样也就没有中断 nginx 进程对日志文件的读写,自然就不会有丢数据的风险了。而cp
的话,是新建了一个目标空文件,然后去往里拷贝数据,这是需要时间的,而且无法保证对一个正在读写的文件拷贝数据的完整性。当你重定向清空源文件的时候,数据就会不同程度的丢失了。所以这里用mv
而不是cp
,至此我想你也应当明白cp
与mv
的区别了。
2. 正确的切分方法
Section titled “2. 正确的切分方法”mv access.log access.log.0kill -USR1 `cat master.nginx.pid`sleep 1gzip access.log.0 # do something with access.log.0
-
首先我们不是
cp
,而是mv
当前日志成为一个归档文件(最好加上时间后缀),此时文件access.log
的 inode 并未改变,对于 Linux 进程来说,mv
并没有使文件发生变化,而进程是按 inode 追踪文件的,而不是文件名。所以直到mv
完成以及mv
完成后, nginx 进程会一直继续读写access.log.0
文件(其实是access.log
,不是吗?)。 -
Nginx 内部定义了
USR1
信号,这个信号和我们所用的kill -9
信号类似的地方在于,他们都属于 linux 信号的一种,你可以kill -l
查看全部信号的定义,各个发行版的定义会有些许差异;不同的地方在于,-9
属于系统级别的,而USR1
属于应用软件级别的,开发者自定义的,至于程序收到-USR1
信号后会干什么事,开发者自己说了算,这点和-9
这种系统级别的信号不同。所以在这里,kill -USR1
不会杀死 Nginx 进程,而 Nginx Master 进程收到-USR1
信号后,会重新打开名为access.log
的日志文件,由于access.log
已经不存在了,那么access.log
会重新建立一个这样的文件,并开始往里读写数据,也就是说读写从access.log.0
又切回到access.log
了,这样新的请求日志会被重新开始记录了,而这个过程是没有任何读写中断,数据丢失的。 -
这句的意思是给一定的时间让上一步的读写切换顺利完成,以便可以进行后续的操作,对归档日志进行处理。比如有可能数据还在 nginx 的 buffer 中,没有及时写入
access.log.0
或是系统负载、IO 很高,没有及时响应切换,此时若强行对归档日志access.log.0
进行处理,则会有数据丢失的风险。 -
这句代码就是用户后续对归档日志
access.log.0
进行处理了,你可以gzip
、rsync
等等,随你怎么玩吧。这里算是有了一个简单、完美的解决方案,其实你也可以用一些三方的工具来做 log rotation,比如logrotate
。
示例:定时切分日志并定期删除
Section titled “示例:定时切分日志并定期删除”1. 创建Nginx日志切割脚本
Section titled “1. 创建Nginx日志切割脚本”编辑 /home/crontab/cut_nginx_log.sh
文件:
#!/bin/shlogs_path="/usr/local/nginx/logs/"DAYS=30mv ${logs_path}bbs_access.log ${logs_path}nginx_logs/bbs_logs/bbs_access_$(date -d "yesterday" +"%Y%m%d").logmv ${logs_path}sns_access.log ${logs_path}nginx_logs/sns_logs/sns_access_$(date -d "yesterday" +"%Y%m%d").logkill -USR1 `cat /usr/local/nginx/logs/nginx.pid`find ${logs_path}nginx_logs/bbs_logs/ -name "bbs_access_*" -type f -mtime +$DAYS -exec rm {} \;find ${logs_path}nginx_logs/sns_logs/ -name "sns_access_*" -type f -mtime +$DAYS -exec rm {} \;
保存并退出:
:wq! #保存退出chmod +x /home/crontab/cut_nginx_log.sh #添加脚本执行权限
2. 添加任务计划
Section titled “2. 添加任务计划”修改 /etc/crontab
文件,在最后一行添加:
0 0 * * * root /home/crontab/cut_nginx_log.sh #表示每天凌晨执行:wq! #保存退出
至此,Linux下定时切割Nginx访问日志并删除指定天数前的日志记录完成。
如果脚本在执行过程中出现下面错误:
nginx: open() "/usr/local/nginx/logs/nginx.pid" failed
解决办法:
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
使用
nginx -c
的参数指定nginx.conf
文件的位置