搞运维和开发的朋友,十有八九都被日志坑过。不是磁盘被一堆几百MB甚至几个G的日志文件塞爆,就是排查问题的时候发现关键日志早就被覆盖了。我自己就经历过一次:一台业务服务器半夜告警,登录上去一看,/var/log 目录占了整整40多个G,连 df -h 都要卡好几秒。从那次之后,我彻底把“日志自动管理”这件事当成正经项目来做,而不是随手写个 > /tmp/app.log 就糊弄过去。
这篇内容适合所有在用 Linux 做服务器、跑应用、维护系统的朋友。不管你是刚入行的运维新手,还是自己折腾个人项目的开发者,只要服务器上会产出日志,就离不开这套东西。我会从整体思路讲起,把自动切割、压缩、按时间清理到定时任务整个链路拆开讲透,全程都有可以直接抄走的配置和脚本。
1. 日志管理的整体设计与方案选型
日志自动管理这件事,看着简单,做起来容易踩坑。核心原因在于:日志文件是动态增长的,而磁盘空间是固定有限的。如果不给它上一套“自动机制”,它迟早会把你坑一次。
1.1 要解决的核心问题
我们把日志管理的需求拆开来看,其实是四个问题的组合:
- 日志文件无限增长:一个 Java 服务如果开了 debug 级别日志,一天产出几个 G 是很正常的事。如果完全不限制,磁盘迟早被写满。
- 单文件过大导致读取困难:几个 G 的日志文件,你用
vi打开直接卡死,用tail -f倒是能跟,但想往回翻就很痛苦,grep一次也要等半天。 - 历史日志没有一个合理的清理周期:有些日志可能要留 180 天用于安全审计,有些日志留 7 天就足够。如果一刀切全删,出了问题没法追溯;如果全留着,磁盘又扛不住。
- 操作完全依赖人工:今天记得手动清理了,明天忘了怎么办?必须靠系统机制自动完成,不能靠人的自觉性。
设计这套方案的时候,我没有绕弯子,直接采用了 Linux 生态里面最成熟的两个组合:logrotate 做轮转切割,find + crontab 做定期清理。这两个工具都是系统自带的,不需要额外装任何东西,也没有性能损耗,稳定可靠。
1.2 为什么选 logrotate 而不是纯脚本
肯定有人会问:我直接写个 shell 脚本,用 mv 把日志改名,再用 kill -HUP 让进程重新打开日志文件,不也能实现吗?
可以,但没必要。logrotate 本身已经把这些事封装好了,而且处理了很多边缘情况:
- 它是通过 cron 每天定时触发的,不需要你额外维护一个定时任务。
- 支持按大小切割(size 参数)、按时间切割(daily、weekly、monthly)。
- 支持压缩(compress)、归档(olddir)、自定义日期后缀(dateext)。
- 支持在轮转完成后执行命令(postrotate),这对需要发信号给进程重新打开日志的场景特别重要。
- 它的配置文件语法清晰,字段含义明确,几行就能完成一个服务的日志轮转配置。
更重要的是,logrotate 是绝大多数 Linux 发行版预装好的,几乎所有主流软件包在安装时会自动往 /etc/logrotate.d/ 里丢一份自己的轮转配置。你只需要看懂并修改它,而不是从零造轮子。
1.3 整体方案架构
这套日志自动管理方案一共分为三层:
- 轮转切割层:用 logrotate 把正在写的日志按天或按大小切分,保留最近 N 份,再对历史文件做压缩。
- 清理回收层:用一个独立的清理脚本,对超过保留期限的日志文件做删除,或者对某些不需要进 logrotate 的目录做粗暴清理。
- 定时执行层:用 crontab 把清理脚本挂上去,每天凌晨低峰期跑一次,同时给 logrotate 也留出执行窗口。
换句话说,logrotate 负责“把大文件切成小文件”,find 脚本负责“把过期的小文件删掉”。两者分工明确,互不冲突。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 日志轮转核心配置与参数详解
logrotate 的主配置在 /etc/logrotate.conf,针对具体服务的轮转规则放在 /etc/logrotate.d/ 下面,比如 /etc/logrotate.d/nginx、/etc/logrotate.d/syslog。我实际使用中发现,直接在 /etc/logrotate.d/ 下新建独立配置文件,比改动全局配置要清晰得多,也好维护。
2.1 一份可直接落地的 logrotate 配置
下面这份配置是我在线上环境用了一年多的模板,适用范围很广,你只需要改掉路径和保留份数就能用:
bash复制cat > /etc/logrotate.d/myapp <<'EOF'
/var/log/myapp/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
dateext
dateformat -%Y%m%d
copytruncate
}
EOF
逐项参数说明一下:
daily:每天轮转一次。如果你愿意,也可以写成weekly或size 500M,按日志产出速度实际情况来。rotate 30:保留最近 30 份轮转后的日志文件。因为是按天的,所以相当于保留一个月。compress:轮转完成后对历史文件做 gzip 压缩。注意它压缩的是“轮转下来之后”的文件,正在写入的日志文件不会被压缩。delaycompress:延迟一层压缩。意思是本轮轮转出来的文件先不压缩,等下一天轮转时再压缩。这个参数配合
