利用Linux自带的logrotate管理日志(转)

日常运维中,经常要对各类日志进行管理,清理,监控,尤其是因为应用bug,在1小时内就能写几十个G日志,导致磁盘爆满,系统挂掉。

nohup.out,access.log,catalina.out

本文简单介绍利用Linux自带的logrotate来对操作系统中各类日志进行管理。

1、logrotate简介

The logrotate utility is designed to simplify the administration of log files on a system which generates a lot of log files. Logrotate allows for the automatic rotation compression, removal and mailing of log files. Logrotate can be set to handle a log file daily, weekly, monthly or when the log file gets to a certain size.

为了使用它,主要有两个地方需要修改一下:一个是/etc/logrotate.conf,另一个是/etc/logrotate.d/下面的文件。

你既可以在logrotate.conf中直接定义如何处理你的log文件,也可以在/logrotate.d/下面针对自己的log新建一个对应的文件来定义处理log的行为,推荐在目录 /logrotate.d/ 下面创建自己的文件来对个性化的日志进行处理。

logrotate定义了如何处理日志,而它本身则是被crond定时调用的。

我使用的一个生产实例:

复制代码
/usr/local/nginx/logs/*.log {
    create 0644 root root
    daily
    rotate 2
    missingok
    copytruncate
    ifempty
    compress
    noolddir
}
复制代码

上述内容保存到nginxlog文件,存放到目录:/etc/logrotate.d/nginxlog
设置权限:owner=root group=root mode=0644

测试配置是否正确:

lograte -d /etc/logrotate.d/nginxlog

2、logrotate配置参数

logrotate 全局配置文件: /etc/logrotate.conf

配置参数 功能说明
compress 通过gzip 压缩转储以后的日志
nocompress 不需要压缩时,用这个参数
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断;是先拷贝再清空的方式,拷贝和清空之间有一个时间差,可能会丢失部分日志数据。
nocopytruncate 备份日志文件但是不截断
create mode owner group  转储文件,使用指定的文件模式创建新的日志文件。轮转时指定创建新文件的属性,如create 0777 nobody nobody
nocreate 不建立新的日志文件
delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩
errors address  专储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,这个是 logrotate 的缺省选项。
notifempty 如果是空文件的话,不转储
mail address  把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下

prerotate/endscript

在logrotate转储之前需要执行的指令,例如修改文件的属性等动作;这两个关键字必须单独成行;
postrotate/endscript 在logrotate转储之后需要执行的指令,例如重新启动 (kill -HUP) 某个服务!必须独立成行;
daily 指定转储周期为每天
weekly 指定转储周期为每周
monthly 指定转储周期为每月
rotate count 指定日志文件删除之前转储的个数,0 指没有备份,5 指保留5个备份
tabootext [+] list 让logrotate  不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~ 
size size当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem).
missingok 如果日志丢失,不报错继续滚动下一个日志
notifempty 当日志文件为空时,不进行轮转
sharedscripts 运行postrotate脚本,作用是在所有日志都轮转后统一执行一次脚本。如果没有配置这个,那么每个日志轮转后都会执行一次脚本
dateext 使用当期日期作为命名格式
dateformat .%s  配合dateext使用,紧跟在下一行出现,定义文件切割后的文件名,必须配合dateext使用,只支持 %Y %m %d %s 这四个参数
size(或minsize) log-size 当日志文件到达指定的大小时才转储,log-size能指定bytes(缺省)及KB (sizek)或MB(sizem).

说明:

当日志文件 >= log-size 的时候就转储。
以下为合法格式:(其他格式的单位大小写没有试过)
size = 5 或 size 5 (>= 5 个字节就转储)
size = 100k 或 size 100k
size = 100M 或 size 100M

实例:

复制代码
/home/deploy/apps/production.log {
missingok
copytruncate
rotate 10
notifempty
sharedscripts
dateext
dateformat -%Y-%m-%d-%s
size=10M
postrotate
mv /home/deploy/apps/production.log-* /data1/log/rails
gzip /data1/log/rails/production.log-*
endscript
}
复制代码

问题:rotate和maxage的区别是什么?
它们都是用来控制保存多少日志文件的,区别在于 rotate 是以个数为单位的,而 maxage 是以天数为单位的。如果我们是以按天来轮转日志,那么二者的差别就不大了。

4、nginx日志切割实例

复制代码
vim /etc/logrotate.d/nginx   #创建nginx日志切割配置文件

/application/nginx/logs/*.log{
daily
rotate 10
create
dateext
}

logrotate -d /etc/logrotate.d/nginx 调试测试 -d debug
logrotate -d /etc/logrotate.d/nginx 手动切割日志测试

ls /application/nginx/logs/ 带日期的表示是切割好的日志
access.log bbs.log-20180228 error.log www.log
access.log-20180228 blog.log error.log-20180228 www.log-20180228
bbs.log blog.log-20180228 nginx.pid

复制代码

配置好nginx切割日志生效时间

# cat /etc/anacrontab    #此文件里有生效时间
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

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 #生效时间范围是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

复制代码

也就是说,配好的nginx切割日志,生效时间是在凌晨3点到22点之间,而且随机延迟时间是45分钟

5、其他配置示例

复制代码
/var/log/htmlaccess.log {
 errors jim
 notifempty
 nocompress
 weekly
 prerotate
 /usr/bin/chattr -a /var/log/htmlaccess.log
 endscript

postrotate
/usr/bin/chattr +a /var/log/htmlaccess.log
endscript
}

复制代码

持续集成系统日志处理配置

复制代码
/var/log/jenkins/jenkins.log /var/log/jenkins/access_log {
    compress
    dateext
    maxage 365      #保留最大365天
    rotate 99       #最大保留99个备份
    size=+4096k
    notifempty
    missingok
    create 644
    copytruncate
}
复制代码

 自定义日志处理

复制代码
/medialog/*.log {
    create 0644 root root
    daily
    rotate 30
    missingok
    copytruncate
    notifempty
    compress
    delaycompress
    olddir /medialog/backlog    # 将归档日志单独目录存储
}
复制代码

 

转:----------------------------logrotate自定义切割时间的一些坑

说起日志切割,很多人会选择用crontab脚本定时执行已编写好的日志分割脚本,殊不知在linux上内置了日志分割工具,它就是logrotate且其在centos7上默认安装了.

logrotate介绍

logrotate是基于crond服务来运行的,其crond服务的脚本是/etc/cron.daily/logrotate,日志转储是系统自动完成的。实际运行时,logrotate会调用主配置文件 /etc/logrotate.conf,可以在 /etc/logrotate.d 目录里放置自定义好的配置文件,用来覆盖logrotate的缺省值。定时执行/etc/cron.daily目录下的文件的设置,则在/etc/anacrontab里定义的,那anacrontab怎么知道上次成功执行脚本的具体时间呢?通过查看/etc/cron.daily/logrotate得知有 /var/lib/logrotate/logrotate.status这样的一个文件,此文件的作用就是记录最近一次成功运行日志分割脚本的具体时间.

所以logrotate执行脚本的命令其实是/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf

logrotate执行流程

crond服务加载/etc/cron.d/0hourly ---> 在每小时的01分执行/etc/cron.hourly/0anacron ---> 执行anacron ---> 根据/etc/cron.daily/logrotate获得上次运行logrotate的时间 ---> 根据/etc/anacrontab的配置执行/etc/cron.daily/etc/cron.weekly/etc/cron.monthly ---> 执行/etc/cron.daily/下的logrotate脚本 ---> 执行logrotate ---> 根据/etc/logrotate.conf配置执行脚本/etc/logrotate.d/nginx ---> 转储nginx日志成功

logrotate使用

/etc/logrotate.d/下面新建文件nginxLogrotate

vim /etc/logrotate.d/nginxLogrotate

添加如下:

/home/APPDeploy/nginx-1.16.0/logs/*.log {               #日志文件所在的路径
        daily                                           #每天进行日志分割
        missingok                                       #在日志转储期间,任何错误将被忽略
        rotate 30                                       #保留30个备份
        compress                                        #通过gzip压缩转储以后的日志
        delaycompress                                   #delaycompress和compress一起使用时,转储的日志文件到下一次转储时才压缩,即这次切割的日志不压缩
        dateext                                         #日志后面带时间,如:nginx.access.log-20190516
        #dateformat -%Y%m%d%s                           #日志时间格式
        #dateyesterday                                  #如果定时任务时间设置的是0点就要配置此项,不然切割的内容是昨天的但是日志名却是当天的.
        notifempty                                      #当日志文件为空时,不进行轮转
        create 644 APPDeploy APPDeploy                  #轮转时指定创建新文件的属性
        sharedscripts                                   #运行postrotate脚本,作用是在所有日志都轮转后统一执行一次脚本。如果没有配置这个,那么每个日志轮转后都会执行一次脚本
        postrotate                                      #在logrotate转储之后需要执行的指令,下面的脚本作用是让nginx将日志内容存储在新的日志文件中.
                if [ -f /home/APPDeploy/nginx-1.16.0/run/nginx.pid ]; then
                        kill -USR1 `cat /home/APPDeploy/nginx-1.16.0/run/nginx.pid`
                fi
        endscript
}
  • 测试是否生效

logrotate -vfd /etc/logrotate.d/nginxAccessLog # 以debug测试是否生效,不会真的切割日志

logrotate -fv /etc/logrotate.d/nginxAccessLog # 强制生效并显示详细的输出信息

详细信息请用man logrotate查看

logrotate生效时间

要想知道logrotate什么时候执行日志分割操作,需要关注/etc/anacrontab/var/lib/logrotate/logrotate.status这两个文件.

上文中已介绍过/var/lib/logrotate/logrotate.status这里就不在赘述了.

/etc/anacrontab是使logrotate按时执行脚本的主要配置文件,我们来仔细看下anacrontab的主要内容:

sudo cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.

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=03-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

从上面的内容可以看出:如果机器没有关机,默认的logrotate(配置文件里设置的是cron.daily)一般会在每天的3点05分到3点50分之间执行,真实的延迟时间是 RANDOM_DELAY + delay in minutes.

如果在3-22这个时间段内服务器处于关机状态,则logrotate会在机器开机5分钟后执行分割日志的操作.

注意

不建议直接修改此文件,如果想修改logrotate默认的执行时间,可通过crontab执行自定义的logrotate配置文件,但这时就不能将自定义的配置文件放置在 /etc/logrotat.d/下了,应该放置在/etc/logrotat.d/下层目录或者另外的路径,否则就会执行两遍日志分割的操作,执行时间分别是你在crontab中定义的时间以及anacrontab默认的执行时间即3:05-3:50。

更多的信息请用man anacrontab查看.

自定义logrotate执行时间

正常的日志分割都是按天进行的,即每个日志只记录0-24点之间的内容,如果是按默认的anacrontab设定的执行时间那肯定是不行的,具体实现其实有两种方法:

  • 方法1(推荐):

1: 在/etc/logrotate.d创建下层目录,mkdir -p /etc/logrotate.d/nginx ,当然也可在非/etc/logrotate.d/下创建此目录,例如我是在/etc/logrotate.daily.0下创建了nginxLogrotate文件.

2: 移除之前自定义的配置文件,sudo mv /etc/logrotate.d/nginxLogrotate ~/bak/,这样做的作用就是防止执行两次日志分割脚本的操作.

3: 添加crontab计划任务, sudo echo "59 23 * * * /usr/sbin/logrotate -f /etc/logrotate.daily.0/nginxLogrotate >/dev/null 2>&1" > /etc/crontab

当然也可直接在root用户下执行crontab -e然后添加上面的内容.

如果用非root用户则会报错error: error creating output file /var/lib/logrotate/logrotate.status.tmp: 权限不够

4: 重启crontab,service crond restart,其实可以不用重启.

注意

如果crontab中定义的执行时间是0点,则需要在/etc/logrotate.d/nginx/nginxLogrotate里添加上dateyesterday这个选项,否则日志内容记录的是昨天的,而 日志名称格式却是今天的,但crontab中定义的执行时间是23:59这样的则不用添加dateyesterday选项.

posted @ 2021-01-25 11:38  plumemoon  阅读(429)  评论(0)    收藏  举报