程序在运行的时候为了了解运行状态,会输出日志文件,时间久了日志文件会变得非常大,甚至达到GB级别。我在golang应用里使用logrus包来打日志,配置和使用都很方便,就是没有日志分割的功能,应用在线上运行一个月后日志文件都已经达到上百兆。后来发现了logrotate,这是centos自带的日志分割工具,都不用安装额外组件就能实现定时分割日志。
1.运行原理
logrotate默认情况下是通过anacron调用的,它每天只会被调用一次,也就是说一个日志文件默认不会多次被处理(除非-f强制调用或者文件大小超过指定值)。大致调用流程如下:
1).anacron每天去调用/etc/cron.daily中的任务(包含logrotate);
2).anacron调用logrotate后进行日志的处理工作;
3).如果logrotate被手工调用,或者配置文件中有引用,后面的配置记录会覆盖前面相同选项的内容;
1
2
3
4
5
6
7
8
|
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
|
可以看到入口配置文件是/etc/logrotate.conf,依次运行/etc/logrotate.conf.d里的配置文件 如果发现配置的logrotate没有执行,可以看下系统的crond服务有没有开启
logrotate命令详解:
1
2
3
4
5
6
7
8
9
10
|
logrotate --help
用法:logrotate [-dv] [-f|--force] [-s|--state file] config_file+
什么都不跟则显示版本信息和简单的帮助信息,如果处理过程中出现异常则返回非0的$?;
--?,--help: 显示帮助信息;
-v, --verbose:显示详细信息;
-d, --debug:开启调试模式并隐含开启-v,不会对日志和logrotate的state文件产生操作;
-f, --force:忽略调用周期强制调用logrotate,方便测试;
-m, --mail <
command
>:告知logrotate发送邮件的命令;
-s, --state <
statefile
>:多个logrotate运行时告知logrotate自己使用的state文件(/var/lib/logrotate.status)
config_file+:表示可以使用多个配置文件(默认为/etc/logrotate.conf)在后面,最好是在一个配置文件中进行引用(测试某条新的规则时可以单独创建一个配置文件并用-f参数进行强行调用);
|
2.配置
如果有安装nginx,可以参考nginx里的配置例子
1
2
3
4
5
6
7
8
9
10
11
12
|
/var/log/nginx/*log {
create 0644 nginx nginx
daily
rotate 10
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}
|
第一行定义的是日志文件的路径,可以用*通配,一般可以定义成*.log来匹配所有日志文件。也可以指定多个文件,用空格隔开,比如
1
2
3
|
/var/log/nginx/access.log /var/log/nginx/error.log {
}
|
花括号里面是日志切割相关的参数,下面是常用的切割参数
-
compress 是否开启压缩,压缩格式gzip
-
不开启压缩
-
compresscmd 自定义压缩命令
-
compressexty 压缩文件名后缀
-
compressoptions 压缩选项
-
copy 复制一份文件
-
create 后面跟mode owner group,设置新日志文件的权限
-
daily 按天分割
-
weekly 按周分割
-
monthly 按月分割
-
rotate 后面跟数字,表示需要保留的文件历史记录,超过数量就会删除,或者通过邮件发送
-
size 后面跟文件大小,比如100k、100M,超过这个大小后分割
-
missingok 忽略不存在的文件,不报错
-
notifempty 不分割空文件
-
sharedscripts 配合postrotate、prerotate,让他们只执行一次
-
postrotate/endscript 文件分割完后,执行postrotate、endscript之间的命令
-
prerotate/endscript 文件分割完前,执行prerotate、endscript之间的命令
下面看几个例子
1
2
3
4
5
6
7
8
9
|
/var/log/httpd/error.log {
rotate 5
mail i@wuyuans.com
size=100k
sharedscripts
postrotate
/sbin/killall -HUP httpd
endscript
}
|
切割/var/log/httpd/error.log日志文件,超过100k后切割,保留最新的5个历史记录,超过5个的邮件发送到fss@qq.com,postrotate里的的命令是为了让httpd重新打开日志文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/var/lib/mysql/mysqld.log {
# create 600 mysql mysql
notifempty
daily
rotate 3
missingok
compress
postrotate
# just if mysqld is really running
if test -x /usr/bin/mysqladmin && \
/usr/bin/mysqladmin ping &>/dev/null
then
/usr/bin/mysqladmin --local flush-error-log \
flush-engine-log flush-general-log flush-slow-log
fi
endscript
}
|
这是对mysql日志的切割,每天一份,忽略空文件,保留最新3份,使用gzip压缩
1
2
3
4
5
6
7
8
9
10
11
|
/home/wuyuan/log/*.log {
su wuyuan wuyuan
create 0777 wuyuan wuyuan
daily
rotate 10
olddir /home/wuyuan/log/old
missingok
postrotate
endscript
nocompress
}
|
这是我在用的配置项,对log目录所有.log文件切割,每天一份,保留10份,新文件设定权限777,历史文件保留在old目录里,这样可以方便查看。因为应用程序用的logrus使用append的方式写日志,所以不需要重新打开日志文件,这点logrus做得很不错。
3.测试
写完配置文件后可以手动执行下,来验证是否可用。
1
|
logrotate -f /etc/logrotate.d/wuyuan
|
其中-f 表示强制执行
没问题的话日志就会被移到old目录下,并带上日期,之前的log文件会被清空
本文转自奔跑在路上博客51CTO博客,原文链接http://blog.51cto.com/qiangsh/1983415如需转载请自行联系原作者
qianghong000