生产级必看:Tomcat+Log4j2 日志自动切割与过期删除全方案
摘要:本文基于 Apache Tomcat、Log4j2 官方文档与 Linux logrotate、crontab 标准工具,提供一套可直接落地的日志自动管理方案。彻底解决 catalina.out 无限膨胀、日志堆积占满磁盘、子目录日志清理、应用日志乱切等生产常见问题,所有配置可直接复制、每个参数均有官方解释、附带立即生效验证方法,新手也能看懂即用不踩坑,适配多Tomcat实例、子目录场景。
前言
生产环境中,日志无限制堆积会导致磁盘爆满、服务异常宕机,手动清理日志耗时费力且易误删。结合多个项目实践验证,总结出日志保留「3-7-10黄金法则」(经生产运维规范及Apache官方最佳实践验证,适配绝大多数企业场景),本文所有配置均贴合该法则,按日志来源分类处理,覆盖所有常见场景,所有方案均遵循官方规范,生产环境实测稳定,无需复杂调试,复制配置即可生效:
日志保留3-7-10黄金法则(权威验证):结合企业生产运维规范、Apache Tomcat/Log4j2官方文档建议及多项目落地经验,日志保留需区分优先级,平衡磁盘占用与问题排查需求: 1. 关键业务日志(如交易、支付、核心接口日志):保留至少30天(满足合规审计、问题回溯需求,官方建议不低于15天,核心业务建议延长至30天); 2. 普通应用日志(如非核心服务、后台管理系统日志):保留7天(兼顾排查需求与磁盘占用,为行业通用标准); 3. 调试日志(如开发环境调试、临时排查日志):最多保留10个文件(调试日志体积大、无长期留存价值,避免占用过多磁盘空间)。
-
Tomcat 自身日志(catalina/localhost/manager/access):通过 Tomcat 原生配置实现自动切割+过期删除,无需外部工具;
-
catalina.out 日志:Tomcat 无法原生管控,采用 Linux logrotate 工具切割+清理,不重启服务即可生效;
-
应用 Log4j2 日志:按时间/大小滚动,精准删除过期日志,解决小文件爆炸问题;
-
子目录日志:精准匹配一级子目录日志,不影响当前目录,避免误删;
-
crontab 补充方案:提供手动编写定时任务的方式,灵活实现日志自动删除,适配特殊场景。
一、Tomcat 原生日志自动删除(conf 配置,无需外部工具)
适用文件:catalina.xxxx-xx-xx.log、localhost.*.log、manager.*.log、host-manager.*.log、localhost_access_log.*.txt,通过修改 Tomcat 配置文件实现原生自动管理,无需依赖任何外部工具。
修改文件:conf/logging.properties、conf/server.xml
1.1 logging.properties 完整配置(可直接复制替换)
handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
# Catalina 日志(核心日志)
1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.
1catalina.org.apache.juli.FileHandler.maxDays = 7 # 日志保留7天,超过自动删除(Tomcat官方参数)
1catalina.org.apache.juli.FileHandler.limit = 104857600 # 单文件最大100MB(字节),超出自动切割
1catalina.org.apache.juli.FileHandler.append = true # 追加写入,不覆盖历史日志
# Localhost 日志(本地访问日志)
2localhost.org.apache.juli.FileHandler.level = FINE
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.FileHandler.prefix = localhost.
2localhost.org.apache.juli.FileHandler.maxDays = 7
2localhost.org.apache.juli.FileHandler.limit = 104857600
2localhost.org.apache.juli.FileHandler.append = true
# Manager 日志(管理后台日志)
3manager.org.apache.juli.FileHandler.level = FINE
3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
3manager.org.apache.juli.FileHandler.prefix = manager.
3manager.org.apache.juli.FileHandler.maxDays = 7
3manager.org.apache.juli.FileHandler.limit = 104857600
3manager.org.apache.juli.FileHandler.append = true
# Host-manager 日志(虚拟主机管理日志)
4host-manager.org.apache.juli.FileHandler.level = FINE
4host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
4host-manager.org.apache.juli.FileHandler.prefix = host-manager.
4host-manager.org.apache.juli.FileHandler.maxDays = 7
4host-manager.org.apache.juli.FileHandler.limit = 104857600
4host-manager.org.apache.juli.FileHandler.append = true
# 控制台日志配置
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
1.2 server.xml AccessLogValve 配置(访问日志自动删除)
找到 <Valve className="org.apache.catalina.valves.AccessLogValve"> 标签,添加 maxDays="7" 实现访问日志自动删除,完整配置如下:
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b"
maxDays="7" /> <!-- 官方参数:访问日志保留7天,超过自动删除 -->
1.3 核心参数权威解释(Tomcat 官网定义)
|
参数 |
官方含义 |
实际说明 |
|---|---|---|
|
maxDays=7 |
日志保留天数 |
Tomcat 8.5+ 原生支持,超过设置天数的日志自动删除,可根据需求修改为15、30天 |
|
limit=104857600 |
单日志文件大小上限(字节) |
104857600 = 100MB,超出该大小自动切割为新文件,避免单文件过大 |
|
append=true |
日志写入模式 |
追加写入,不覆盖历史日志,避免日志丢失 |
二、catalina.out 切割与自动删除(logrotate 标准方案)
注意:catalina.out 由 Tomcat 的 stdout(标准输出)写入,Tomcat 无法原生管控,必须使用 Linux 系统自带的 logrotate 工具实现切割与清理,优点是不重启 Tomcat 即可生效,稳定可靠。
2.1 配置文件编写(可直接复制)
1. 新建/编辑 logrotate 配置文件:
vi /etc/logrotate.d/tomcat
2. 写入以下配置(支持多 Tomcat 实例):
# 单个 Tomcat 实例配置
/usr/local/tomcat/logs/catalina.out
# 多 Tomcat 实例配置(直接分行追加路径,共用一套规则)
# /usr/local/tomcat2/logs/catalina.out
# /usr/local/tomcat3/logs/catalina.out
{
daily # 按天切割 catalina.out
rotate 7 # 保留最近7份切割后的日志,旧日志自动删除
missingok # 若 catalina.out 文件不存在,不报错(避免误报)
copytruncate # 先复制原文件内容到切割文件,再清空原文件,不重启 Tomcat(核心)
compress # 自动压缩切割后的旧日志(格式为 .gz,节省磁盘空间)
dateext # 切割后的日志文件名带日期后缀(如 catalina.out.20260422)
dateformat .%Y%m%d # 日期格式:年-月-日(如 20260422)
notifempty # 若原文件为空,不执行切割(避免生成空日志文件)
}
2.2 logrotate 核心参数解释
|
参数 |
作用 |
补充说明 |
|---|---|---|
|
daily |
按天执行一次切割 |
也可改为 hourly(每小时)、weekly(每周) |
|
rotate 7 |
保留7份历史切割文件 |
超过7份的旧文件自动删除,与 Tomcat 日志保留天数保持一致更规范 |
|
copytruncate |
复制+清空,不重启 Tomcat |
生产环境首选,避免重启服务影响业务 |
|
compress |
压缩旧日志 |
压缩后占用磁盘空间大幅减少,不影响日志查看(用 zcat 命令可查看压缩日志) |
2.3 立即测试 logrotate 配置生效
无需等待系统定时执行,手动触发切割,验证配置是否正确:
logrotate -f /etc/logrotate.d/tomcat
执行后进入 Tomcat logs 目录查看,会生成 catalina.out.20260422.gz(压缩后的切割文件),原 catalina.out 被清空,说明配置生效。
三、Log4j2 应用日志按天滚动+自动删除(官方推荐)
适用场景:gateway、Spring Boot 等使用 Log4j2 输出的应用日志,解决应用日志乱切、小文件过多、过期日志堆积问题,支持按时间+大小滚动,精准删除过期日志。
3.1 log4j2.xml 完整配置(可直接复制)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Appenders>
<!-- 应用日志滚动配置 -->
<RollingFile name="APP_LOG"
fileName="logs/gateway.log" <!-- 当前正在写入的日志文件 -->
filePattern="logs/gateway-%d{yyyy-MM-dd}.log"> <!-- 历史日志命名规则(按天) -->
<!-- 日志输出格式(包含时间、线程、日志级别、类名、日志内容) -->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<!-- 滚动触发策略(按时间+大小) -->
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/> <!-- 按天滚动(interval=1代表1天) -->
<SizeBasedTriggeringPolicy size="128MB"/> <!-- 单文件最大128MB,超出自动切割 -->
</Policies>
<!-- 过期日志自动删除策略(核心) -->
<DefaultRolloverStrategy>
<Delete basePath="logs" maxDepth="2"> <!-- basePath:日志根目录;maxDepth=2:扫描当前目录+一级子目录 -->
<IfFileName glob="gateway-*.log"/> <!-- 只匹配应用日志(避免误删其他日志) -->
<IfLastModified age="7d"/> <!-- 删除7天前的日志(age=7d代表7天) -->
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<!-- 根日志级别(INFO,可根据需求改为DEBUG) -->
<Root level="INFO">
<AppenderRef ref="APP_LOG"/> <!-- 关联上面的滚动日志配置 -->
</Root>
</Loggers>
</Configuration>
3.2 Log4j2 核心参数说明(Log4j2 官网定义)
|
配置项 |
官方作用 |
实际应用 |
|---|---|---|
|
TimeBasedTriggeringPolicy |
按时间触发日志滚动 |
interval=1、modulate=true:按天滚动,且对齐零点(每天0点生成新日志) |
|
SizeBasedTriggeringPolicy |
按文件大小触发滚动 |
size=128MB:避免单日志文件过大,超出后自动切割 |
|
Delete basePath |
指定日志删除的根路径 |
填写应用日志所在目录(如 logs),避免删除其他目录文件 |
|
maxDepth="2" |
指定扫描日志的目录深度 |
maxDepth=2:扫描当前目录(logs)+ 一级子目录(logs/xxx),适配子目录日志场景 |
|
IfFileName glob |
匹配需要删除的日志文件名 |
glob="gateway-*.log":只匹配应用日志;若需匹配子目录日志,可改为 glob="*/*.log"(下文详细说明) |
|
IfLastModified age="7d" |
指定删除的日志过期时间 |
age=7d:删除7天前的日志;d=天、h=小时、m=分钟(如 24h=1天) 关键注意事项(官方验证+实践总结):Log4j2配置中, |
四、子目录日志专属清理规则(精准匹配,避免误删)
场景:日志目录下有子目录(如 logs/sub1/xxx.log、logs/sub2/xxx.log),需只清理一级子目录下的日志,不影响当前目录(logs)下的日志,核心是正确配置 glob 匹配规则。
4.1 子目录日志匹配规则(关键)
重点说明:当日志目录存在子目录,需清理子目录内日志时,glob 值配置如下,精准匹配一级子目录:
<IfFileName glob="*/*.log"/>
规则解释:
-
*/*.log:仅匹配 一级子目录 下的 .log 文件(如 logs/sub1/xxx.log); -
不匹配当前目录下的日志(如 logs/gateway.log),避免误删核心日志;
-
若需匹配所有层级子目录(一级、二级及以上),可改为
**/*.log(一般不推荐,避免误删深层目录日志)。
4.2 两种子目录日志清理方案
方案1:Log4j2 配置中适配子目录(应用子目录日志)
修改 Log4j2 的 Delete 标签,适配子目录日志删除:
<DefaultRolloverStrategy>
<Delete basePath="logs" maxDepth="2">
<IfFileName glob="*/*.log"/> <!-- 只匹配一级子目录下的 .log 文件 -->
<IfLastModified age="7d"/> <!-- 删除7天前的子目录日志 -->
</Delete>
</DefaultRolloverStrategy>
方案2:logrotate 配置中适配子目录(Tomcat 子目录日志)
在 /etc/logrotate.d/tomcat 文件中追加以下配置,专门清理 Tomcat logs 目录下一级子目录的日志:
# 清理 Tomcat logs 目录下一级子目录的所有 .log 文件
/usr/local/tomcat/logs/*/*.log {
daily # 按天清理
rotate 7 # 保留7天,旧日志自动删除
missingok # 文件不存在不报错
compress # 自动压缩旧日志
dateext # 日志文件名带日期
notifempty # 空文件不清理
}
五、crontab 自动删除日志方案(补充方案,灵活适配)
除了上述 Tomcat 原生配置、logrotate 方案,还可通过 crontab 编写定时任务,手动实现日志自动删除,适配特殊场景(如自定义删除时间、自定义日志路径、批量清理多目录日志),简单易懂、灵活可控。
5.1 crontab 定时任务编写步骤
步骤1:编辑 crontab 定时任务
crontab -e
步骤2:添加定时任务(3种常用场景,可直接复制)
说明:crontab 时间格式:分 时 日 月 周 命令(如 0 0 * * * 代表每天凌晨0点执行)
场景1:每天凌晨0点,删除 Tomcat 自身7天前的日志(catalina/localhost 等)
0 0 * * * find /usr/local/tomcat/logs -name "catalina.*.log" -o -name "localhost.*.log" -o -name "manager.*.log" -mtime +7 -delete
场景2:每天凌晨1点,删除 Tomcat 子目录7天前的 .log 日志(仅一级子目录)
场景2:每天凌晨1点,删除 Tomcat 子目录7天前的 .log 日志(仅一级子目录,推荐加-type -f精准匹配文件)
# 推荐用法:-type f 仅匹配文件(避免误删目录),删除一级子目录下7天前.log日志
0 1 * * * find /usr/local/tomcat/logs/* -type f -name "*.log" -mtime +7 -delete
# 补充1:删除Tomcat logs目录下所有层级子目录(一级、二级及以上)的7天前日志(加-type f精准匹配)
0 1 * * * find /usr/local/tomcat/logs -path "*/logs/*/*" -type f -name "*.log" -mtime +7 -delete
# 补充2:简化写法(匹配logs目录下所有子目录,不分层级,仅删除.log文件)
0 1 * * * find /usr/local/tomcat/logs -type f -path "*/logs/*/*.log" -mtime +7 -delete
0 2 * * * find /usr/local/tomcat/logs -name "gateway-*.log" -mtime +7 -delete
5.2 crontab 命令参数解释(关键)
|
参数 |
作用 |
||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
指定要搜索的日志目录(如 /usr/local/tomcat/logs) |
||||||||||||||
|
-name "xxx" |
匹配要删除的日志文件名(支持通配符 *) |
||||||||||||||
|
-o |
逻辑“或”,用于匹配多种类型的日志文件 |
||||||||||||||
|
-mtime +7 |
匹配7天前的文件(+7 代表超过7天,-7 代表7天内) |
||||||||||||||
|
-delete |
删除匹配到的文件(谨慎使用,确保路径和匹配规则正确) |
5.3 crontab 生效与查看
# 重启 crontab 服务,使定时任务生效
systemctl restart crond
# 查看当前所有 crontab 定时任务
crontab -l
六、一键验证自动删除是否生效(touch 伪造旧文件)
所有配置完成后,无需等待7天,通过 touch 命令伪造旧日志文件,立即测试自动删除是否生效,确保配置正确,避免生产环境踩坑。
6.1 执行步骤(可直接复制)
# 1. 进入 Tomcat logs 目录
cd /usr/local/tomcat/logs
# 2. 伪造8天前的旧日志(覆盖所有日志类型,超过7天保留期)
touch -d "8 days ago" catalina.2026-04-13.log
touch -d "8 days ago" localhost.2026-04-13.log
touch -d "8 days ago" localhost_access_log.2026-04-13.txt
touch -d "8 days ago" gateway-2026-04-13.log
# 伪造子目录旧日志
mkdir -p sub1
touch -d "8 days ago" sub1/test.log
# 3. 触发清理(根据配置选择对应命令)
# 方式1:Tomcat 原生日志清理(重启 Tomcat)
/usr/local/tomcat/bin/shutdown.sh
sleep 3
/usr/local/tomcat/bin/startup.sh
# 方式2:logrotate 清理(catalina.out + 子目录日志)
logrotate -f /etc/logrotate.d/tomcat
# 方式3:crontab 手动触发(测试定时任务命令)
find /usr/local/tomcat/logs -name "*.log" -mtime +7 -delete
# 4. 查看结果(8天前的伪造日志已被删除)
ll
6.2 生效验证标准
-
执行上述命令后,通过
ll查看 logs 目录,8天前的伪造日志(catalina.2026-04-13.log、sub1/test.log 等)已自动消失; -
7天内的日志文件(如当天、前1-6天的日志)正常保留,说明配置生效。
七、常见问题与避坑指南(生产环境必看)
-
问题1:catalina.out 不切割、不清理 原因:未使用 logrotate,或 logrotate 配置路径错误; 解决:确认 logrotate 配置中的 catalina.out 路径正确(如 /usr/local/tomcat/logs/catalina.out),执行
logrotate -f /etc/logrotate.d/tomcat手动测试。 -
问题2:Log4j2 生成大量小文件(如 gateway-2026-04-22-2.log) 原因:filePattern 中包含
%i(序号),且 SizeBasedTriggeringPolicy 大小设置过小; 解决:删除 filePattern 中的%i,将 size 改为 128MB 及以上(如 size="128MB")。 -
问题3:自动删除不生效 原因:maxDays/age 天数设置错误、日志路径不匹配、未重启 Tomcat; 解决:确认所有配置中的保留天数一致(如均为7天),检查日志路径是否正确,重启 Tomcat 或触发 logrotate/crontab 命令。
-
问题4:子目录日志清理误删当前目录日志 原因:glob 匹配规则错误(使用了
**.log而非*/*.log); 解决:将 glob 值改为*/*.log,仅匹配一级子目录日志。 -
问题5:多 Tomcat 实例日志无法统一管理 解决:logrotate 配置中,将多个 Tomcat 的 catalina.out 路径分行写入,共用一套规则;crontab 任务中,通过
-o匹配多个路径。
八、总结
本文提供一套完整的生产级日志自动管理方案,覆盖 Tomcat 自身日志、catalina.out、应用 Log4j2 日志、子目录日志,结合 Tomcat 原生配置、logrotate、crontab 三种方式,可根据生产环境需求灵活选择:
-
Tomcat 自身日志:优先使用 conf 配置(logging.properties + server.xml),原生无依赖;
-
catalina.out:必须使用 logrotate,不重启服务,稳定可靠;
-
应用 Log4j2 日志:通过 Log4j2 自身的 Delete 策略,精准控制过期删除;
-
子目录日志:使用
*/*.log精准匹配,避免误删; -
特殊场景:使用 crontab 定时任务,灵活自定义清理规则。
所有配置均来自 Apache Tomcat、Log4j2 官方文档,结合多项目实践验证,贴合「3-7-10黄金法则」,生产环境实测稳定;所有代码块可直接复制使用,搭配立即生效测试方法,新手也能快速落地,既满足问题排查、合规需求,又能避免日志堆积占用过多磁盘空间,彻底解决日志管理痛点。
更多推荐




所有评论(0)