FROM : http://www.2cto.com/os/201503/381812.html
在很多实际项目中,应用程序会持续写日志,如果程序代码中没有调用支持自动切分(如按filesize或date切割)的日志库,则日志文件会很快增长到G级别。单机操作大文件对后续跟进日志来说非常不方便。
本文介绍如何利用logrotate这个工具来在应用程序外部切分日志。
1. logrotate是什么
logrotate是大多数linux系统自带的日志切割工具,在shell终端输入"man 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.
更完整的简介可以在shell终端查看其man文档,这里不赘述。
总之,我们知道它可以用来切割仍在滚动的日志文件即可,这里的“仍在滚动”是指当前日志文件仍在被应用程序持续进行追加写操作。
2. logrotate的适用场景
如果文件是静态的(即当前没有应用程序对齐进行写操作),则split是更常用的静态文件切割工具,其用法简介见这里,此处略过。
logrotate常用来切割仍在被写的“动态”文件,它支持按时间间隔或文件大小来触发文件的自动切分(automatic rotation)。具体用法下面说明。
3. 如何使用logrotate
根据man logrotate的说明,logrotate用法很简单:
1 |
|
其中[]中出现的option(s)均是可选项,我们只需提供一份配置文件即可,下面用示例对配置文件格式做说明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
上述配置文件中,"#"表示后面是注释,它可以独占一行,也可以与配置项在同一行。
配置项"rotate 5"表明切分后的历史文件最多保存最近的5份,若触发本次切分时已有5份历史文件(默认为messages.1/messages.2/messages.3/messages.4/messages.5),则文件messages.5会被物理删除,剩余文件后缀序号依次加1。
切分的具体执行过程可以参考《鸟哥的Linux私房菜》在这里的说明。
上面的示例配置文件只是展示了logrotate配置文件的基本格式,该工具还支持其它众多配置项,具体可以参考man logrotate的说明。
下面的配置文件说明了在实际项目中如何按文件大小对不允许restart的应用程序进行日志自动切分。
1 2 3 4 5 6 7 8 9 |
|
特别注意copytruncate这个配置项,根据其文档说明(见下面的摘录),它可能会导致部分数据丢失,在不允许日志数据丢失的应用场景下,不应该使用该配置(若日志不允许丢失,则最好在应用程序代码中支持HUP信号来实现优雅重启,这样就可以避免使用copytruncate;当然,也可以用logrotate支持的create配置来达到目的)。
copytruncate
Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one, It can be used when some program can not be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.=