背景
在编写脚本或者运行项目的时候,一般都需要在适当的地方做日志输出,方便在出问题或者有需要的时候可以快速定位代码位置。
因此,只要系统正常运行,就会一直有日志不断输出,日志文件也会越来越大。长时间累计下来,一个日志文件可能有数百G大小,想打开文件查看都很难。如果对于大部分久远的日志信息我们并不需要,那么这样保存如此多的日志信息,对磁盘空间既是浪费,也是很大的额外负担。
所以,很多时候我们需要日志记录关键信息,但是只需要保留近期的日志信息,比如三十天内的日志。这样能在保证我们可以在项目出现问题的时候能找到近期的相关信息,又不至于保存了太多的无用信息。
最近,我做的项目中就遇到了需要处理日志的问题。因为在以前没有做日志的轮转,导致日志可能累计了半年甚至更久的。不仅占了大量磁盘空间,查看日志也非常的麻烦。
一开始我试图通过将所有输出日志的格式统一,然后通过另外的脚本读取所有的日志文件,再对日志文件进行切分。逻辑上这样做确实没有问题,但是实际操作的话,却并没有足够的可行性。主要有两个原因:
1.项目中有日志输出的地方非常多,如果要统一日志的输出格式的话,需要在所有输出日志的地方都做代码修改。这样做不仅需要做的改动非常多,而且可能会有遗漏。
2.在使用另外的脚本读取日志文件进行切分的时候,可能会在当时有脚本正在向文件写日志,多方操作可能会有冲突。如果要加文件锁,也会是非常麻烦的事情,要加很多异常处理情况。
为了解决上述问题,以及让日志轮转变得更加简单方便,我们可以使用logrotate进行日志的自动轮转与切分。
Logrotate
简介
上图所示为logrotate的介绍,logrotate就是专门用来自动切分日志文件的,可以对文件进行轮转、压缩、移除等。Linux系统默认是安装了logrotate的。
配置
logrotate的基础配置文件为/etc/logrotate.conf,在/etc目录下还有个文件夹/etc/logrotate.d,用户可以将自己的配置文件放在这个文件夹中。这个文件夹中所有的文件都会被读取,然后在运行logrotate的时候被执行。
logrotate基于cron执行,默认每天执行一次。cron的配置文件为/etc/cron.daily/logrotate。如果不进行额外的配置,默认会在每天凌晨运行一次,不同系统可能在时间上略有差异。
如果确实需要一天多次运行logrotate,可以自行配置crontab任务。在配置任务之前,可以手动执行确保配置的正确性。在执行的时候,可以增加参数,显示一些我们需要的信息:
-d, --debug :debug模式,测试配置文件是否有错误。
-f, --force :强制转储文件。
-m, --mail=command :压缩日志后,发送日志到指定邮箱。
-s, --state=statefile :使用指定的状态文件。
-v, --verbose :显示转储过程
在正式运行前,可以先使用-d参数,查看输出是否正常。然后可以使用-f强制执行。-vf会在强制执行的同时输出操作过程的详细信息。
使用
有新的日志轮转的需求,可以直接向相关配置加载logrotate.conf中,但是这样管理起来很不方便。建议是在logrotate.d文件夹中添加新的配置文件。
新的配置的格式一般如下所示:
文件开始是需要加入轮转的日志的路径,如图中的/var/log/apt/term.log。然后是用{}包起来的执行参数,一行一个。上图中的样例的执行效果是:每个月进行一次轮转;最多会存在12个文件;日志轮转后自动压缩;如果文件不存在,忽略报错信息继续执行后面的;当日志文件为空时,不进行轮转。
具体执行的时候流程如下:
1.第一次执行完之后,原本的term.log会变成term.log.1,然后系统会新建一个term.log给之后的日志写入。
2.第二次执行后,term.log.1变成term.log.2,term.log变成term.log.1,然后再生成一个新的term.log。
3.同以上操作,每次执行后,都会生成一个新的文件,然后所有文件后缀做一次轮转。
4.当生成了第13个文件时,这个文件会被删除,只保留12个文件。
其它参数说明
用户可以根据自己的需求,选择合适的配置参数。比如轮转的周期(daily,weekly,monthly),是否压缩,是否创建新文件等等。
对于需要自定义轮转周期的,也可以自行配置cron任务。