Appearance
Linux 日志切割怎么做更稳:logrotate 在 Java 与 Nginx 场景里的常用写法
日志不切,几乎早晚都会出问题。
最常见的后果就是:
- 磁盘被慢慢打满
- 排障时日志文件大得难处理
- 容器和宿主机日志都越来越乱
先说结论
对大多数 Linux 服务器来说,日志治理最实用的起点不是先上复杂平台,而是先把:
- 哪些日志需要切
- 切完保留多久
- 压缩不压缩
- 切完服务是否需要 reopen
这几件事用 logrotate 固定下来。
一、现在应该怎么理解 logrotate
它本质上是在做两件事:
- 按规则轮转日志
- 控制日志保留和压缩
所以它解决的不是“看日志”,而是“日志别把机器拖死”。
二、哪些日志最该先治理
最常见的是:
- Nginx access/error 日志
- Java 应用文件日志
- 自定义任务日志
如果服务器上既有 Docker,又有宿主机服务,排查时一定要分清:
- 哪些是容器 stdout
- 哪些是宿主机文件日志
对你现在这类站点来说,最值得先看的是:
/mydata/nginx/logs/*.log- 系统级任务日志
- 如果启用了文件日志的 Java 服务目录
三、先别把 Nginx 日志和 Docker 日志混为一谈
这点很关键。
如果你现在的 Nginx 容器把日志直接挂载到宿主机,例如:
/mydata/nginx/logs/access.log/mydata/nginx/logs/error.log
那 logrotate 管理的就是这些宿主机文件。
但如果某些容器主要把日志打到 stdout/stderr,那么你要治理的就不一定是 logrotate,而更可能是 Docker 自己的日志驱动和日志轮转配置。
简单说就是:
- 文件日志,用
logrotate - 容器标准输出日志,优先看 Docker 日志配置
不要两边一起乱切。
四、一个常见配置长什么样
ini
/var/log/myapp/*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
copytruncate
}这段配置的核心含义是:
- 每天切一次
- 保留 14 份
- 空文件不处理
- 开启压缩
如果你要放到当前 Nginx 场景,一个更贴近实际的例子可以是:
ini
/mydata/nginx/logs/*.log {
daily
rotate 14
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
docker exec nginx-mumu-wiki nginx -s reopen >/dev/null 2>&1 || true
endscript
}这类写法的重点是:
- 日志按天切分
- 保留两周
- 切完后通知 Nginx 重新打开日志文件
五、copytruncate 为什么常见
对很多没有优雅 reopen 日志能力的应用来说,copytruncate 很常见。
它适合:
- 应用还在持续写日志
- 不方便重启应用
但也要知道,它不是完美方案。
它的代价是切割瞬间可能丢少量日志。
所以:
- 能
reopen的服务,优先用postrotate + reopen - 不能
reopen的老应用,再考虑copytruncate
如果应用本身支持日志框架轮转,优先用应用层能力通常更稳。
六、Nginx 日志要注意什么
Nginx 切日志后,通常需要让它重新打开日志文件。
这也是为什么很多配置会配合:
postrotatenginx -s reopen
如果你当前 Nginx 是 Docker 方式运行,那命令可能会变成:
docker exec nginx-mumu-wiki nginx -s reopen
前提是容器名、挂载路径和权限都已经固定好。
七、Java 应用日志怎么考虑
如果你用的是 logback、log4j2 这类日志框架,很多时候应用层已经支持:
- 按天切分
- 按大小切分
这时要先判断:
- 是不是已经在应用层切了
- 还需不需要系统层再切
不要两层逻辑互相打架。
比较稳的做法通常是:
- Java 应用日志由
logback或log4j2自己管理 - Nginx、脚本、自定义文件日志由
logrotate兜底
八、怎么验证 logrotate 规则真的可用
别等磁盘打满了再验证。
至少可以做两步:
1. 先做语法和配置检查
bash
logrotate -d /etc/logrotate.d/nginx-d 是 debug 模式,不会真的执行切割,但可以先看规则有没有问题。
2. 再做一次强制演练
bash
logrotate -f /etc/logrotate.d/nginx演练后重点检查:
- 是否生成了轮转后的文件
- Nginx 是否还在继续写新日志
- 磁盘占用是否符合预期
九、最容易踩的坑
1. 日志删了,空间没回来
这通常不是 df 错了,而是:
- 进程还占着已删除文件句柄
2. 只切不清理
如果只轮转不控制保留数量,磁盘压力只是来得更晚。
3. 容器日志完全没治理
很多机器磁盘打满,根因其实不是应用文件日志,而是:
- Docker JSON 日志无限增长
4. 已经用了应用层轮转,又在系统层强切一次
这样最容易造成日志命名混乱,甚至影响排障连续性。
一句话总结
日志切割不是锦上添花,而是服务器日常治理里非常基础的一环。
对 Java 服务和 Nginx 来说,先把“谁负责切日志、切完后谁负责 reopen、日志最终落在哪”这三件事固定下来,能提前避开很多低级但代价很高的问题。