摘要:本文基于 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个文件(调试日志体积大、无长期留存价值,避免占用过多磁盘空间)。

  1. Tomcat 自身日志(catalina/localhost/manager/access):通过 Tomcat 原生配置实现自动切割+过期删除,无需外部工具;

  2. catalina.out 日志:Tomcat 无法原生管控,采用 Linux logrotate 工具切割+清理,不重启服务即可生效;

  3. 应用 Log4j2 日志:按时间/大小滚动,精准删除过期日志,解决小文件爆炸问题;

  4. 子目录日志:精准匹配一级子目录日志,不影响当前目录,避免误删;

  5. crontab 补充方案:提供手动编写定时任务的方式,灵活实现日志自动删除,适配特殊场景。

一、Tomcat 原生日志自动删除(conf 配置,无需外部工具)

适用文件:catalina.xxxx-xx-xx.loglocalhost.*.logmanager.*.loghost-manager.*.loglocalhost_access_log.*.txt,通过修改 Tomcat 配置文件实现原生自动管理,无需依赖任何外部工具。

修改文件:conf/logging.propertiesconf/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配置中,age参数必须与filePattern的时间精度协调——若filePattern精确到小时(如 logs/gateway-%d{yyyy-MM-dd-HH}.log),则age需写成xH(x为小时数),若仍写xd(天)则无法生效;另外,age对应的数字建议大于2,否则可能因最近的日志文件仍被服务进程占用,导致删除操作失败。

四、子目录日志专属清理规则(精准匹配,避免误删)

场景:日志目录下有子目录(如 logs/sub1/xxx.loglogs/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 命令参数解释(关键)

参数

作用

参数

作用

find 路径

指定要搜索的日志目录(如 /usr/local/tomcat/logs)

-type f

仅匹配文件,不匹配目录,避免误删子目录本身(推荐添加)

-name "xxx"

匹配要删除的日志文件名(支持通配符 *)

-o

逻辑“或”,用于匹配多种类型的日志文件

-mtime +7

匹配7天前的文件(+7 代表超过7天,-7 代表7天内)

-delete

删除匹配到的文件(谨慎使用,确保路径和匹配规则正确)

指定要搜索的日志目录(如 /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. 问题1:catalina.out 不切割、不清理 原因:未使用 logrotate,或 logrotate 配置路径错误; 解决:确认 logrotate 配置中的 catalina.out 路径正确(如 /usr/local/tomcat/logs/catalina.out),执行 logrotate -f /etc/logrotate.d/tomcat 手动测试。

  2. 问题2:Log4j2 生成大量小文件(如 gateway-2026-04-22-2.log) 原因:filePattern 中包含 %i(序号),且 SizeBasedTriggeringPolicy 大小设置过小; 解决:删除 filePattern 中的 %i,将 size 改为 128MB 及以上(如 size="128MB")。

  3. 问题3:自动删除不生效 原因:maxDays/age 天数设置错误、日志路径不匹配、未重启 Tomcat; 解决:确认所有配置中的保留天数一致(如均为7天),检查日志路径是否正确,重启 Tomcat 或触发 logrotate/crontab 命令。

  4. 问题4:子目录日志清理误删当前目录日志 原因:glob 匹配规则错误(使用了**.log 而非 */*.log); 解决:将 glob 值改为 */*.log,仅匹配一级子目录日志。

  5. 问题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黄金法则」,生产环境实测稳定;所有代码块可直接复制使用,搭配立即生效测试方法,新手也能快速落地,既满足问题排查、合规需求,又能避免日志堆积占用过多磁盘空间,彻底解决日志管理痛点。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐