如何用logrotate管理每日增长的日志

logrotate简介

logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be handled daily, weekly, monthly, or when it grows too large.

这是logrotate文档中对其自身的描述,其实logrotate功能很简单,正如其名,按一定周期自动循环分割和保存日志防止无限增长,必要的时候进行压缩、删除,还可以进行邮件通知等功能。

很多服务器上总会运行着一些会不停生成成吨日志的程序,最简单的比如nginx、httpd之类的web服务器的访问日志,为了保持这些日志的可检索以及防止无限增长把有限的硬盘都吃干净了,就会有五花八门的cron脚本来处理这些日志,事实上这些事情都可以由logrotate代劳。

安装logrotate

事实上大多数Linux发行版本都默认安装了logrotate,可以通过以下命令来判断系统是否已经预装了logrotate:

rpm包管理器:

rpm -qa|grep logrotate

dpkg包管理器:

dpkg --list|grep logrotate

更简单粗暴的方法:

which logrotate

如果能看到有字符串返回的话,你的服务器就应该预装了logrotate,并且它已经每天在默默地工作了,只不过你并没有给他分配活儿。

如果没有安装的话,用正常的包管理工具都能安装它:

yum install logrotateapt-get install logrotate

logrotate基本工作原理

作为一个定时处理的管理工具,logrotate本身是个命令行的工具,然而它需要定时处理你的日志,所以显然logrotate还是得基于cron来工作的,否则就没有人定时来唤醒它让它干活了,正常情况下logrotate已经作为cron.daily的一个任务每天被定时在执行了,这个定时脚本位于/etc/cron.daily/logrotate

#!/bin/sh
# Clean non existent log file entries from status file
cd /var/lib/logrotate
test -e status || touch status
head -1 status > status.clean
sed 's/"//g' status | while read logfile date
do
    [ -e "$logfile" ] && echo "\"$logfile\" $date"
done >> status.clean
mv status.clean status
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf

上面这段是Ubuntu中默认的logrotate脚本,各个不同版本上的logrotate脚本会有细微的不同,但是核心都是使用/etc/logrotate.conf配置脚本来启动logrotate。

然而这段脚本只是位于这个目录里,为什么会被每天调用呢,而且每天什么点调用呢?

可以查看CRON的默认配置文件/etc/crontab(新版CentOS中其默认配置文件位于/etc/anacrontab)的内容:

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

事实上CRON默认会存在这4条指令,分别是每小时、每天、每周、每个月会执行对应目录下的脚本,而不需要再通过日常常用的crontab去配置,可以看到cron.daily目录下的脚本在每天的6点25分会被执行,这也就意味着在这台机器上每天6点25分会启动logrotate进行日志的处理,各个系统的默认配置也是各不相同的。

最后来看一下默认的配置文件/etc/logrotate.conf:

# see "man logrotate" for details
# rotate log files weekly
weekly
# use the syslog group by default, since this is the owning group
# of /var/log/syslog.
su root syslog
# keep 4 weeks worth of backlogs
rotate 4
# create new (empty) log files after rotating old ones
create
# uncomment this if you want your log files compressed
#compress
# packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own wtmp, or btmp -- we'll rotate them here
/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}
/var/log/btmp {
    missingok
    monthly
    create 0660 root utmp
    rotate 1
}
# system-specific logs may be configured here

其实默认配置文件中给出的是logrotate的一些默认配置选项,并给出了一些样例的配置(如wtmp,btmp),这些配置的意义在后文中会予以阐述,而这个配置文件中还包含了include /etc/logrotate.d,这使得我们可以不用将所有的配置扎堆写入这个默认配置文件中,而是可以分散地管理在/etc/logrotate.d目录下,事实上/etc/logrotate.d也已经包含了一些样例的配置文件供参考。

logrotate的配置和使用

如同刚才所说的,logrotate会每日CRON启动并执行,我们只需要在/etc/logrotate.d目录中添加我们需要的配置,就可以利用logrotate来自动管理我们需要的日志文件。

这里先来看一个目录下已经存在的样例配置dpkg:

/var/log/dpkg.log {
    monthly
    rotate 12
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
}
/var/log/alternatives.log {
    monthly
    rotate 12
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
}

正如其名称dpkg,这个配置是用来处理包管理器dpkg的默认日志的,处理的日志文件是/var/log/dpkg.log与/var/log/alternatives.log这两个文件

其配置内容如下:

  • monthly:按月处理日志
  • rotate 12:保留12份日志
  • compress:日志分割后会进行gzip压缩
  • delaycompress:日志压缩会被延后到下次分割时进行
  • missingok:目标日志文件不存在程序也不会报错退出
  • notifempty:目标日志文件为空时不进行分割操作
  • create 644 root root:以644也就是rw-r–r–权限来建立分割出来的文件,同时该分割文件所属用户为root,用户组为root

在/var/log下列出文件列表,可以看到dpkg的日志的确被分割并压缩了:

如何用logrotate管理每日增长的日志_第1张图片

仿照这个样例文件,我们可以配置一个类似的处理任务,这里处理一下nginx的log文件,一般web serve的access log文件都是日志重灾区,建立一个/etc/logrotate.d/nginx配置文件,内容如下:

/home/wwwlogs/*.log {
    daily
    rotate 7
    dateext
    compress
    delaycompress    
    missingok
    notifempty
    create 644 root root
    sharedscripts
    postrotate
        kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
    endscript
}

与之前的样例配置类似,注意到声明日志文件位置时使用了*通配符,这意味着/home/wwwlogs/下的所有.log文件都会被logrotate处理,这里多出了几行配置

说明如下:

  • daily:每天处理日志
  • dateext:备份的日志文件的后缀不再是默认的.1 .2 .3的递增格式,而是.YYYYMMDD的日期格式
  • sharedscripts:配置该选项时,prerotate和postrotate段的脚本会在所有文件被处理结束(被处理前)统一执行,而不是每个文件前后分别执行一次
  • postrotate:处理日志后钩子,postrotate和endscript构成一个shell语句块,在日志文件被处理后这部分语句会被执行,对应的还有prerotate语句块

这样nginx的log文件的处理配置就完成了,但是我们可能还需要确认一下配置的内容到底是否正确呢,这时候可以利用logrotate命令行的debug选项来进行测试

命令如下:

logrotate -d -f /etc/logrotate.d/nginx

开启了debug选项时,logrotate会详细地给出处理日志过程中的处理信息,但是并不会真正地去处理日志文件,所以可以用来测试配置文件处理的是否正确

这行命令的输出如下:

reading config file /etc/logrotate.d/nginx
Handling 1 logs
rotating pattern: /home/wwwlogs/*.log  forced from command line (7 rotations)
empty log files are not rotated, old logs are removed
considering log /home/wwwlogs/access.log
  log needs rotating
considering log /home/wwwlogs/jp01.sanaecon.com.log
  log needs rotating
considering log /home/wwwlogs/nginx_error.log
  log needs rotating
rotating log /home/wwwlogs/access.log, log->rotateCount is 7
dateext suffix '-20151108'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
rotating log /home/wwwlogs/jp01.sanaecon.com.log, log->rotateCount is 7
dateext suffix '-20151108'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
rotating log /home/wwwlogs/nginx_error.log, log->rotateCount is 7
dateext suffix '-20151108'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
renaming /home/wwwlogs/access.log to /home/wwwlogs/access.log-20151108
creating new /home/wwwlogs/access.log mode = 0644 uid = 0 gid = 0
renaming /home/wwwlogs/jp01.sanaecon.com.log to /home/wwwlogs/jp01.sanaecon.com.log-20151108
creating new /home/wwwlogs/jp01.sanaecon.com.log mode = 0644 uid = 0 gid = 0
renaming /home/wwwlogs/nginx_error.log to /home/wwwlogs/nginx_error.log-20151108
creating new /home/wwwlogs/nginx_error.log mode = 0644 uid = 0 gid = 0
running postrotate script
running script with arg /home/wwwlogs/*.log : "
        kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
"

可以看到logrotate如我们设想的那样在正常处理日志文件,至此一个logrotate配置就完成了。

logrotate命令行除了可以用来展示配置文件配置是否正确以外,还可以用来手动执行日志分割,使用以下命令行:

logrotate -f /etc/logrotate.d/nginx

就会脱离CRON手动运行一次日志分割和处理任务,事实上通过这个方式也可以用第三方的其他程序来管理日志分割的频率。

本文中给出了一些常见的配置文件中的配置参数的含义,更多其他的配置参数的含义和功能可以参考官方的配置文档:http://linuxconfig.org/logrotate-8-manual-page

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

你可能感兴趣的:(如何用logrotate管理每日增长的日志)