Nginx access.log等 日志归档的正确姿势
续上次配置nginx缓存之后,顺道检查了nginx的配置,发现日志归档用的是crontab定时任务,每周执行一次
> /app/nginx/logs/access.log #直接清空日志,有点简单粗暴,想查周期长一点的日志的话都木的查。
所以写了这篇手册,供人使用。
Logging配置
Nginx的日志配置文档只是描述了记录哪些内容,过滤哪些内容。
并没有提供日志归档的工具和方法。
不推荐:利用管道进行归档
这个想法很天才,但是很危险。
第一步:建一个命名管道,将nginx日志指向这个管道(管道也是文件)
第二步:使用apache的log工具读取管道内容,并进行灵活的分片
危险之处,如果管道的Reader不工作了,则Writer会hang住,想想就很酸爽。
正确的姿势
使用操作系统自带的logrotate工具进行归档,这也是官方推荐的方案。
可以自行apt-get一个nginx,然后看看/etc/logrotate.d/nginx文件的内容就了然了。
/etc/logrotate.d$ cat nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
如果运行在非root用户下,使用免安装或者编译安装的nginx的情况,该如何是好呢?
logrotate提供了命令参数,可以指定配置文件进行日志文件归档。
> /usr/sbin/logrotate -vf -s nginx/logs/logrotate.status nginx/conf/logrotate.nginx.conf
参数解释:
-v, --verbose
Turns on verbose mode, for example to display messages during rotation.
-f, --force
Tells logrotate to force the rotation, even if it doesn't think this is necessary. Sometimes this is useful after adding new entries to a logrotate config file, or if old log files have been removed by hand(自行移走文件是经常的事情,所以加个force参数吧), as the new files will be created, and logging will continue correctly.
-s, --state statefile
Tells logrotate to use an alternate state file. This is useful if logrotate is being run as a different user for various sets of log files. The default state file is /var/lib/logrotate/status.这个文件我们没有权限,所以必须执行一个
那么nginx/config/logrotate.nginx.conf里面应该写什么呢?我把我们的配置贴在这里,抛砖引玉一下
/app/nginx/logs/*.log {
daily
rotate 7
missingok
compress
delaycompress
notifempty
dateext
dateyesterday
sharedscripts
postrotate
/app/nginx/sbin/nginx -s reopen
endscript
}
参数解释一下
daily
每天归档,还有其他选择(hourly、weekly、monthly等)
rotate 7
保留多少个备份,我们是保留7个,结合daily,即7天的数据
missingok
如果文件不存在,不报错
compress
压缩,使用gzip算法
delaycompress
下次滚动的时候进行日志压缩,这样做的意义:比如我们的配置就可以保证昨天和今天的日志处于未压缩的状态,不需要每天查日志先解压缩了。
notifempty
如果日志为空,不进行归档
dateext
归档文件添加时间戳,默认YYYYMMDD,可以通过dateformat
指令进行设置
dateyesterday
因为我们是凌晨0点进行归档操作,所以日志的内容都是前一天的数据,所以,使用昨天的日期作为归档文件的后缀。
sharedscripts
设置中日志文件指定的是*.log,所以有多个log文件,这个指定通知logrotate程序,接下来的脚本只运行一次,而不是每个文件执行一次。
postrotate
/app/nginx/sbin/nginx -s reopen
endscript
归档文件执行完毕后,执行指令nginx -s reopen
通知nginx重新打开日志文件,将接下来的日志写入到新的文件中。
logrotate的操作循序是
rotate ---> postrotate script ---> compress
所以,不需要担心compress时间过长,占用文件导致日志写不进去。