logrotate 是解决 catalina.out 无限增长的最稳方案,必须启用 copytruncate 参数以确保截断有效,路径需绝对准确,daily 与 size 可共存,手动测试命令为 /usr/sbin/logrotate -vf /etc/logrotate.d/tomcat。

catalina.out 不会自动分割,必须靠外部工具接管或截断,否则它只会无限增长——这是 Tomcat 的设计事实,不是配置遗漏。
logrotate 是最稳的方案,但 copytruncate 必须启用
Tomcat 进程始终持有 catalina.out 的文件描述符,重命名或移动文件不会让它转向新文件。只有 copytruncate 能真正解决“旧文件还在写”的问题。
常见错误现象:日志轮转后 catalina.out 仍持续变大,甚至比切割前还快。
- 确认配置中包含
copytruncate—— 缺少它,整个轮转就失效 - 路径必须绝对准确,比如
/opt/tomcat/logs/catalina.out,不能写成相对路径或带变量的字符串 -
daily和size 100M可共存,但优先匹配先触发的条件;生产环境建议两者都设 - 手动测试命令是:
/usr/sbin/logrotate -vf /etc/logrotate.d/tomcat,观察原文件是否被清空(大小归零或极小)
用 cronolog 替换 stdout 管道时,catalina.sh 修改有两处关键点
本质是让 Tomcat 启动时不再直接重定向到固定文件,而是通过管道交给 cronolog 按时间生成新文件。
容易踩的坑:改错位置、漏注释 touch "$CATALINA_OUT"、没处理好 2>&1 的流向。
- 找到
catalina.sh中类似这样的两行(通常在启动 Bootstrap 的地方):org.apache.catalina.startup.Bootstrap "$@" start >> "$CATALINA_OUT" 2>&1 & - 把这两处全部替换为:
org.apache.catalina.startup.Bootstrap "$@" start 2>&1 | /usr/local/sbin/cronolog "$CATALINA_BASE"/logs/catalina.%Y-%m-%d.out >> /dev/null & - 务必注释掉前面的
touch "$CATALINA_OUT",否则cronolog启动前会创建空catalina.out,干扰管道行为 - 验证安装路径:
which cronolog,不同系统可能装在/usr/bin/cronolog或/usr/sbin/cronolog
别碰 logging.properties 降级来“省日志”
catalina.out 不是 Java 日志框架输出的,它是 Tomcat 启动脚本把 stdout 和 stderr 全部重定向的结果。改 java.util.logging.ConsoleHandler.level 对它基本无效。
真正有效的控制点只有两个:
- 应用代码里删掉所有
System.out.println()、e.printStackTrace()这类直连 stdout 的调用 - 检查是否有第三方库(比如某些老 SDK)默认向
System.err打印调试信息,这类输出也会进catalina.out
紧急情况下安全清空已膨胀的 catalina.out
几十 GB 的 catalina.out 占满磁盘时,不能 rm,也不能用 vi 打开编辑——前者会让 Tomcat 继续往已删除的 inode 写,磁盘空间不释放;后者可能卡死或损坏文件系统。
唯一安全操作是原地截断:
-
> /path/to/tomcat/logs/catalina.out(注意是单个>,不是>>) - 执行后文件大小变为 0,但 inode 不变,Tomcat 仍正常写入
- 该操作可随时执行,无需停服务,但只是临时缓解,必须紧接着配好
logrotate或cronolog
copytruncate 是否生效、cronolog 管道是否接对、以及有没有隐藏的 System.out 输出源——这三点漏掉任一个,catalina.out 就还会悄悄长大。

















