Openresty学习使用(四)日志切割
Openresty学习使用(四)日志切割说明Logrotate日志切割问题执行时间的问题如何告诉应用程序重新打开日志文件说明安装新版nginx的时候,会自动在/etc/logrotate.d目录下面生成一个nginx的文件,每天会自动进行日志切割,保留10天的文件等。但是openresty并没有这个功能,所以需要手动创建配置文件。LogrotateLinux服务器上我们可以用Logrota...
说明
安装新版nginx的时候,会自动在/etc/logrotate.d目录下面生成一个nginx的文件,每天会自动进行日志切割,保留10天的文件等。但是openresty并没有这个功能,所以需要手动创建配置文件。
Logrotate
Linux服务器上我们可以用Logrotate来分割归档日志文件,结合crond我们可以指定每天在某个时间自动整理日志等文档,避免自己去编写复杂的crontab脚本。
Logrotate的配置文件位于 /etc/logrotate.conf,
Logrotate的子配置文件位于文件夹 /etc/logrotate.d/ 下。
常用命令
常用命令 | 描述 |
---|---|
logrotate -d -v /etc/logrotate.d/nginx | 测试指定的logrotate配置 |
logrotate /etc/logrotate.conf | 重新读取配置文件,并对符合条件的文件文件进行rotate |
logrotate主要参数如下表:
配置参数 | 功能说明 |
---|---|
compress | 通过gzip 压缩日志文件的所有非当前版本 |
nocompress | 不需要压缩时,用这个参数 |
copytruncate | 用于还在打开中的日志文件,把当前日志备份并截断 |
nocopytruncate | 备份日志文件但是不截断 |
create mode owner group | 转储文件,使用指定的文件模式创建新的日志文件 |
nocreate | 不建立新的日志文件 |
delaycompress 和 compress | 一起使用时,压缩所有版本,除了当前和下一个最近的 |
nodelaycompress | delaycompress 选项,转储同时压缩。 |
errors address | 专储时的错误信息发送到指定的Email 地址 |
ifempty | 即使是空文件也转储,这个是 logrotate 的缺省选项。 |
notifempty | 如果是空文件的话,不转储 |
dateext | 定义日志文件后缀是日期格式,也就是切割后文件是:xxx.log-20160402.gz这样的格式。如果该参数被注释掉,切割出来是按数字递增,即前面说的 xxx.log-1这种格式 |
mail address | 把转储的日志文件发送到指定的E-mail 地址 |
nomail | 转储时不发送日志文件 |
olddir directory | 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统 |
noolddir | 转储后的日志文件和当前日志文件放在同一个目录下 |
prerotate/endscript | 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行 |
postrotate/endscript | 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行 |
daily | 指定转储周期为每天 |
weekly | 指定转储周期为每周 |
monthly | 指定转储周期为每月 |
rotate | 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份 |
tabootext [+] list | 让logrotate不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~ |
sharedscripts | 对于整个日志组只运行一次脚本 |
size | size当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem). |
日志切割
我们在/etc/logrotate.d下面新建openresty文件
/usr/local/openresty/nginx/logs/*log {
daily
missingok
rotate 7
notifempty
sharedscripts
compress
delaycompress
dateext
postrotate
[ ! -f /usr/local/openresty/nginx/logs/nginx.pid ] || kill -USR1 `cat /usr/local/openresty/nginx/logs/nginx.pid`
endscript
}
执行logrotate /etc/logrotate.conf
需要说明的是sharedscripts,我在前面Nginx的例子里声明日志文件的时候用了星号通配符,也就是说这里可能涉及多个日志文件,比如:access.log和error.log。sharedscripts的作用是在所有的日志文件都轮转完毕后统一执行一次脚本。如果没有配置这条指令,那么每个日志文件轮转完毕后都会执行一次脚本。
问题
执行时间的问题
Logrotate是基于CRON运行的,所以这个时间是由CRON控制的。如果使用的是新版CentOS,那么配置文件为:/etc/anacrontab。
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly
RANDOM_DELAY 指的是最大的延迟时间,这个时间被加在delay in minutes中,为最后生效的delay分钟数,也就是说每次执行日常任务是总是有一个随机5-50分钟的延时。
START_HOURS_RANGE 指定任务开始的小时数。
cron与anacron对比
所以如果你想在指定时间点,让logrotate切割日志的话,是不合适的。我们目前的场景是走了日志收集,所以啥时候切割并不是很重要。
如果想在指定时间点进行切割的话,参考如下脚本,然后配置crontab进行执行
#!/bin/bash
#初始化
LOGS_PATH=/usr/local/openresty/nginx/logs/
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
#按天切割日志
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
#向nginx主进程发送USR1信号,重新打开日志文件,否则会继续往mv后的文件写数据的。原因在于:linux系统中,内核是根据文件描述符来找文件的。如果不这样操作导致日志切割失败。
kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'`
#删除7天前的日志
cd ${LOGS_PATH}
find . -mtime +7 -name "*20[1-9][3-9]*" | xargs rm -f
exit 0
如何告诉应用程序重新打开日志文件
以Nginx为例,是通过postrotate指令发送USR1信号来通知Nginx重新打开日志文件的。但是其他的应用程序不一定遵循这样的约定,比如说MySQL是通过flush-logs来重新打开日志文件的。更有甚者,有些应用程序就压根没有提供类似的方法,此时如果想重新打开日志文件,就必须重启服务,但为了高可用性,这往往不能接受。Logrotate提供了一个名为copytruncate的指令,此方法采用的是先拷贝再清空的方式,整个过程中日志文件的操作句柄没有发生改变,所以不需要通知应用程序重新打开日志文件,但是需要注意的是,在拷贝和清空之间有一个时间差,所以可能会丢失部分日志数据。
更多推荐
所有评论(0)