Ubuntu 上 Ja va 日志管理,其实是一个“组合拳”的问题。很多开发者只关心应用内日志怎么配,却忽略了操作系统层面的轮转和清理,结果日志文件越滚越大,最终把磁盘撑爆。今天,我们一次性把这个问题讲透。

一 管理总览
在 Ubuntu 上,Ja va 日志管理通常涉及三个层面,缺一不可:
- 应用内日志框架(如 Logback、Log4j2)——负责按大小或时间滚动日志,以及控制输出格式;
- 操作系统侧 logrotate——负责按天或按周轮转、压缩与清理历史文件;
- 集中化收集与分析(如 rsyslog、ELK/Graylog)——用于检索、可视化和告警。
这里有个小建议:同时启用应用内滚动与系统级轮转。为什么?因为单点失效的风险太大了——如果应用内滚动配置有问题,至少还有系统级兜底;反过来也一样。双重保险,才能避免日志无限增长。
二 查看与定位日志
动手管理之前,先得知道日志在哪。通常路径隐藏在应用的配置文件中:logback.xml、log4j2.xml 或 application.properties,找一下 /var/log/myapp/*.log 这样的关键字就行。
日志查看命令虽然基础,但实用场景不同,熟练度差别很大:
- 实时跟踪:
tail -f /var/log/myapp/app.log - 检索关键字:
grep -i "error" /var/log/myapp/*.log - 分页查看:
less /var/log/myapp/app.log - 系统服务日志:
journalctl -u myapp.service -f
遇到磁盘空间告急时,别慌,先定位大文件:
- 分区占用:
df -hT - 目录占用:
du -sh /var/log/* | sort -h - 大文件排行:
ls -lhS /var/log/
安全清理有几个要点要记住:正在被进程写入的“实时日志”,千万不要直接 rm,否则进程可能崩溃或文件句柄泄漏。正确的做法是用 truncate 或 echo > 截断,这样能立即释放空间。已轮转的 .gz 归档文件,按保留期删除即可。
三 系统级日志轮转 logrotate
Ubuntu 通常自带 logrotate,而且是靠 cron 每日任务自动触发的(配置文件在 /etc/cron.daily/logrotate)。
为 Ja va 应用创建配置很简单。假设日志路径是 /var/log/myapp/*.log:
- 新建配置文件:
sudo nano /etc/logrotate.d/myapp - 配置示例:
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 myapp myapp
sharedscripts
postrotate
# 若应用支持信号重载;否则可省略或改为重启
kill -USR1 $(cat /var/run/myapp.pid 2>/dev/null) 2>/dev/null || true
endscript
}
- 测试与生效:
- 手动测试:
sudo logrotate -vf /etc/logrotate.d/myapp - 强制立即轮转:
sudo logrotate -f /etc/logrotate.conf
对于 Tomcat 的 catalina.out 这类持续写入的单一文件,同样可以用 logrotate 按日轮转并压缩归档,效果很稳定。
四 应用内日志框架配置
应用内部的日志策略,才是真正决定“日志长什么样”的核心。
SLF4J + Logback(推荐组合):按时间滚动、保留 30 天、自动压缩归档,一套配置搞定:
logs/app.log
logs/app.%d{yyyy-MM-dd}.log
30
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
Log4j2 同样高效,按时间触发滚动,最多保留 20 个归档:
生产环境建议将日志级别设为 INFO/WARN,按需开启 DEBUG。另外,异步日志和结构化(JSON)格式是大型系统的标配,前者能显著降低 I/O 开销,后者方便采集与分析。
五 集中化收集与系统日志清理
日志管理的最终归宿,是集中化。你可以用 rsyslog 将应用日志写入 /var/log/myapp.log 或转发至远程日志服务器;也可以用 ELK Stack(Elasticsearch、Logstash、Kibana)或 Graylog 做检索、可视化与告警。
系统日志清理方面,journald 是个容易忽略的点:
- 查看占用:
journalctl --disk-usage - 仅保留最近 1 周:
sudo journalctl --vacuum-time=1w - 限制总大小至 500MB:
sudo journalctl --vacuum-size=500M
如果需要定时清理脚本,可以这样写,但务必谨慎:
sudo find /var/log -type f -name "*.log" -mtime +30 -delete
最后,安全提示再强调一遍:清理前先备份关键日志;对正在写入的日志优先截断而非删除,否则可能影响进程写入与空间释放。这个细节,往往就是线上事故的导火索。