为 logrotate 自定义 cron

Author Avatar
Equim 2017年5月7日
  • 在其它设备中阅读本文章
Read: 2 minWords: 669Last Updated: 17-12-25Written in: MarkdownLicense: CC-BY-NC-4.0

在之前,考虑到我是用 pm2 作为守护进程,所以在日志管理这方面我直接用了 pm2-logrotate 这个插件。然而最近我发现 pm2-logrotate 的内存占用居然达到了 80 MB,而且持续了很久(应该是有内存泄漏)。对于一个一天只进行一次作业的进程来说,长期占用如此大的内存让我很难接受。于是我决定改用 linux 自带的 logrotate 来进行日志管理。

之前我也用过 logrotate,主要是用来处理不是由 pm2 管理的,又没有自带日志轮转功能的应用产生的日志,所以上手不难。但这次的情况不太一样。我有一个应用为了减小日志体积,时间戳的格式是HH:mm:ss.SSSSS,即只记录时间而不记录日期,这也就意味着,日志必须正好在每天 23 时 59 分准时轮转,这样才能根据轮转后的归档的文件名来区分日志。

那么,问题就来了。logrotate 本身是由 cron 调度的,你可以在/etc/cron.daily下找到一个 logrotate 的执行脚本。然而,cron 的 daily 是以从运行 crond 的那一刻开始计算的时间间隔,也就是说,如果 crond 在 17:40 启动,那么下一次进行 daily 调度的时间会是第二天的 17:40,以此类推。而 logrotate 依赖于 cron,那么 logrotate 的 daily 设置也依赖于 cron 的 daily。但是我之前说过,我的应用要求在每天 23 时 59 分轮转日志。这样看来,直接用 logrotate 的 daily 是行不通的。

这个问题解决起来也不算难,因为我发现无论是 cron 还是 logrotate,都是可以纯净地定制的(不需要 root)。首先我建立了一个~/logrotate文件夹,然后把 pm2 的日志轮转设置写入文件中,命名为pm2,放在这个目录下。然后打开crontab -e,加上一行59 23 * * * cd ~/logrotate/ && logrotate ./pm2 -s ./logrotate.status(注意:-s必须要指定,否则默认会去找/var/lib/logrotate.status,而这个目录是需要 root 权限的),这样自定义的 logrotate 配置就能在每天 23 时 59 分被调用了,最重要的是这样不会影响到其他配置,也不需要 root。

原解决方案:
我直接把/etc/cron.daily/logrotate移动到了/root/logrotate.midnight,然后在/etc/crontab下加上一行59 23 * * * root /root/logrotate.midnight,这样 logrotate 就能在每天 23 时 59 分被调用了。注意如果这么设置的话,所有设置为 daily 的 logrotate 作业都会在每天 23 时 59 分执行。

知识共享许可协议
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

本文链接:https://ekyu.moe/article/custom-cron-with-logrotate/