真正要解决日志膨胀需配置logrotate轮转或journald限制,检查size/daily冲突、路径权限、cron触发;nohup日志须显式配置;清空用truncate或>,禁用echo/cat;根本在应用日志控制。

logrotate 配置不生效?检查这几个关键点
很多用户配了 /etc/logrotate.d/myapp 却发现日志没切、没压缩,常见原因有:
-
size和daily不能共存:二者冲突,logrotate 只认其中一个触发条件;要用大小限制就删掉daily - 路径没写对:配置里写的日志路径必须和应用实际写入的完全一致(包括软链接目标),建议用
readlink -f /var/log/myapp.log确认真实路径 - 权限不对:logrotate 默认以 root 身份运行,但如果日志文件属主是普通用户且没设
create,轮换后新文件可能无法写入 - 没触发执行:logrotate 不是常驻进程,它靠 cron 每天调用一次
/etc/cron.daily/logrotate;可手动测试:sudo logrotate -d /etc/logrotate.conf(调试模式)或sudo logrotate -f /etc/logrotate.conf(强制执行)
systemd-journald 日志爆满?别只盯着 /var/log/journal
journald 的日志行为和传统日志完全不同,journalctl --disk-usage 显示占用 2GB 并不意味着磁盘真被占满——它可能只是缓存在 /run/log/journal(内存临时目录)里没刷到持久区。
- 先确认日志是否已持久化:检查
/var/log/journal目录是否存在且非空;不存在就说明所有日志都在内存中,重启即消失 - 限制持久化日志大小:编辑
/etc/systemd/journald.conf,重点设这三项:SystemMaxUse=500M、SystemMaxFileSize=50M、SystemKeepFree=100M - 改完必须重启服务:
sudo systemctl restart systemd-journald,否则配置不加载 - 临时清理:用
sudo journalctl --vacuum-size=200M主动收缩,比删文件安全得多
nohup.out 或自定义脚本日志怎么管?logrotate 不认它
nohup.out、./app.log 这类由用户进程直接打开写入的日志,logrotate 默认不会扫描到,除非你显式把它加进配置。
- 最稳妥的做法:在启动命令里就带时间戳重定向,比如
nohup ./myapp > app_$(date +\%Y\%m\%d).log 2>&1 &,避免单文件无限增长 - 如果必须用固定名,就在 logrotate 配置中明确列出:
/path/to/nohup.out { size 100M rotate 7 missingok notifempty } - 注意
notifempty必须加上,否则空日志也会被轮换,导致后续写入失败(因为原文件被 rename 走了) - 不要用
echo "" > nohup.out清空:它只写入一个换行符(1 字节),某些程序会因检测到非空而拒绝追加写入
紧急清空日志文件,用 truncate 还是 >?
两者都能把文件变为空,但适用场景不同:
- 小文件(sudo > /var/log/messages 最快,shell 内置操作,无进程开销
- 超大文件(>1GB):用
sudo truncate -s 0 /var/log/kern.log更高效,不会读取文件内容,也不会触发 page cache 压力 - 绝对不要用
cat /dev/null > file:语义正确但多一次 fork+exec,没必要;更糟的是echo > file,它留 1 字节,可能让 tail -F 失效或引发应用异常 - 清空前先确认服务是否还在写:比如
lsof +D /var/log看哪些进程持有着日志文件句柄,否则清空后旧句柄仍指向已被截断的 inode,磁盘空间不会立即释放










