You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tomcat 9中捕获后台运行的专有产品的System.out.println输出并实现日志轮转与过滤

如何在Tomcat 9中捕获后台运行的专有产品的System.out.println输出并实现日志轮转与过滤

首先得说,你遇到的这个场景挺常见的——专有程序硬写System.out又不让改代码,还得把这些输出管起来。别担心,咱们可以利用Tomcat自带的日志工具或者Log4j2来解决,完全不需要碰业务代码。

方案一:用Tomcat自带的Juli日志系统(零额外依赖)

Tomcat默认会把System.out/System.err的输出接管到它的Juli日志框架里,咱们只要配置一下就能实现轮转和基本过滤。

步骤1:修改Tomcat的logging.properties

打开Tomcat安装目录下的conf/logging.properties,按下面的步骤改:

  1. 添加自定义的System.out文件处理器:
    在文件末尾加一段配置,定义专门存System.out输出的日志文件,同时开启轮转:

    # 自定义System.out专属日志处理器
    systemout.org.apache.juli.FileHandler.level = INFO
    systemout.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
    systemout.org.apache.juli.FileHandler.prefix = systemout.
    # 开启日志轮转
    systemout.org.apache.juli.FileHandler.rotatable = true
    # 日志保留90天,过期自动删除
    systemout.org.apache.juli.FileHandler.maxDays = 90
    # 单个日志文件最大100MB,超过就轮转
    systemout.org.apache.juli.FileHandler.maxFileSize = 100MB
    # 缓冲区大小,优化写入性能
    systemout.org.apache.juli.FileHandler.bufferSize = 16384
    # 日志格式,加上调用类信息方便过滤
    systemout.org.apache.juli.FileHandler.formatter = org.apache.juli.OneLineFormatter
    systemout.org.apache.juli.FileHandler.formatter.format = %d{yyyy-MM-dd HH:mm:ss} %level [%thread] %logger - %msg (%caller{1})%n
    
  2. 把System.out绑定到这个处理器:
    找到文件里的logger配置部分,添加:

    # 让System.out的输出只走咱们定义的处理器
    java.lang.System.level = INFO
    java.lang.System.handlers = systemout.org.apache.juli.FileHandler
    # 禁止输出到父处理器(避免重复打日志)
    java.lang.System.useParentHandlers = false
    

步骤2:实现类/包过滤

因为System.out本身不带类名信息,咱们刚才在日志格式里加了%caller{1},它会显示调用println()的类和方法(比如com.foo.MyClass.main(MyClass.java:123))。之后你可以用Windows的findstr或者第三方日志工具(比如LogParser)来筛选特定类的日志:

# 筛选com.foo包下的类的System.out输出
findstr /i "com.foo" logs\systemout.2024-05-20.log

方案二:用Log4j2实现更灵活的过滤和轮转(推荐)

如果需要更精细的过滤规则(比如直接在配置里过滤特定类),可以用Log4j2来桥接System.out,它的功能更强大。

步骤1:准备Log4j2依赖

确保Tomcat的lib目录下有这些jar包:

  • log4j-api.jar
  • log4j-core.jar
  • log4j-jul.jar(用来把JUL的日志桥接到Log4j2,Tomcat的System.out会通过JUL流转过来)

步骤2:配置webapp里的log4j2.properties

打开webapp的WEB-INF/classes/log4j2.properties,添加以下配置:

# 全局配置
status = warn
name = PropertiesConfig

# 定义System.out的滚动文件Appender
appender.systemout.type = RollingFile
appender.systemout.name = SystemOutAppender
appender.systemout.fileName = ${sys:catalina.base}/logs/systemout.log
# 轮转后的文件名格式(按天+序号压缩)
appender.systemout.filePattern = ${sys:catalina.base}/logs/systemout-%d{yyyy-MM-dd}-%i.log.gz
# 日志格式,包含调用类信息
appender.systemout.layout.type = PatternLayout
appender.systemout.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg (%C{1}.%M:%L)%n

# 轮转规则:每天转一次,单个文件超过100MB也转
appender.systemout.policies.type = Policies
appender.systemout.policies.time.type = TimeBasedTriggeringPolicy
appender.systemout.policies.time.interval = 1
appender.systemout.policies.time.modulate = true
appender.systemout.policies.size.type = SizeBasedTriggeringPolicy
appender.systemout.policies.size.size = 100MB

# 保留最近30天的日志
appender.systemout.strategy.type = DefaultRolloverStrategy
appender.systemout.strategy.max = 30

# 添加类过滤规则:只保留com.foo包下的类的输出
appender.systemout.filter.type = RegexFilter
appender.systemout.filter.regex = com\\.foo\\.
appender.systemout.filter.onMatch = ACCEPT
appender.systemout.filter.onMismatch = DENY

# 把System.out绑定到这个Appender
logger.systemout.name = System.out
logger.systemout.level = INFO
logger.systemout.additivity = false
logger.systemout.appenderRef.systemout.ref = SystemOutAppender

# 可选:处理System.err的输出
appender.systemerr.type = RollingFile
appender.systemerr.name = SystemErrAppender
appender.systemerr.fileName = ${sys:catalina.base}/logs/systemerr.log
appender.systemerr.filePattern = ${sys:catalina.base}/logs/systemerr-%d{yyyy-MM-dd}-%i.log.gz
appender.systemerr.layout.type = PatternLayout
appender.systemerr.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg (%C{1}.%M:%L)%n
appender.systemerr.policies.type = Policies
appender.systemerr.policies.time.type = TimeBasedTriggeringPolicy
appender.systemerr.policies.time.interval = 1
appender.systemerr.policies.time.modulate = true
appender.systemerr.policies.size.type = SizeBasedTriggeringPolicy
appender.systemerr.policies.size.size = 100MB
appender.systemerr.strategy.type = DefaultRolloverStrategy
appender.systemerr.strategy.max = 30

logger.systemerr.name = System.err
logger.systemerr.level = ERROR
logger.systemerr.additivity = false
logger.systemerr.appenderRef.systemerr.ref = SystemErrAppender

步骤3:验证配置

重启Tomcat后,你会看到logs/systemout.log生成,里面只有com.foo包下的类的System.out输出,并且会自动按天/大小轮转,超过30天的日志会被清理。

注意事项

  • 如果你用方案一,记得重启Tomcat让配置生效;
  • 方案二里的Log4j2版本要和Tomcat兼容(Tomcat 9推荐用Log4j2 2.x系列);
  • 如果你没法往Tomcat的lib目录加jar包,可以把Log4j2的jar包放到webapp的WEB-INF/lib下,同样生效。

备注:内容来源于stack exchange,提问作者Zlelik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 08:09:33