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

使用TinyLog转发Liquibase的JUL日志触发StackOverflowError求助

解决JUL转TinyLog时的StackOverflowError问题

问题原因

从堆栈信息能看出,出现了循环日志调用:TinyLog的桥接器转发JUL日志时,触发了Tomcat类加载器(org.apache.catalina.loader.WebappClassLoaderBase)的DEBUG级日志,而Tomcat的日志依赖JUL的DirectJDKLog,这条日志又被TinyLog的桥接器捕获,反复循环导致栈溢出。

解决方案

核心思路是让Tomcat类加载相关的日志不经过TinyLog桥接器,避免循环调用。可以通过代码或JUL配置文件实现:

方案1:代码中过滤特定Logger

在激活桥接器后,手动调整Tomcat类加载器对应的Logger,移除桥接器Handler并设置独立的日志处理:

// 激活TinyLog与JUL的桥接
org.tinylog.jul.JulTinylogBridge.activate();

// 获取Tomcat类加载器的Logger实例
Logger catalinaLoaderLogger = Logger.getLogger("org.apache.catalina.loader");

// 移除桥接器Handler,避免循环捕获
for (Handler handler : catalinaLoaderLogger.getHandlers()) {
    if (handler instanceof org.tinylog.jul.BridgeHandler) {
        catalinaLoaderLogger.removeHandler(handler);
    }
}

// 添加默认ConsoleHandler(可根据需求替换为其他Handler)
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.INFO); // 限制日志级别,减少不必要的日志输出
catalinaLoaderLogger.addHandler(consoleHandler);

// 禁止继承父Handler,确保日志只走我们设置的Handler
catalinaLoaderLogger.setUseParentHandlers(false);
// 设置日志级别为INFO,避免DEBUG级类加载日志触发循环
catalinaLoaderLogger.setLevel(Level.INFO);

方案2:通过JUL配置文件(logging.properties)配置

在项目的logging.properties中添加规则,排除Tomcat类加载日志走TinyLog桥接器:

# 全局默认Handler,包含TinyLog桥接器
handlers = org.tinylog.jul.BridgeHandler

# 单独配置Tomcat类加载器的Logger,使用独立Handler
org.apache.catalina.loader.handlers = java.util.logging.ConsoleHandler
org.apache.catalina.loader.useParentHandlers = false
org.apache.catalina.loader.level = INFO

额外注意事项

  • 如果还有其他类似的循环日志源(比如TinyLog自身的日志),可以用同样的方式排除对应的Logger(如org.tinylog)。
  • 调整日志级别时,根据实际需求设置,确保既避免循环,又不丢失关键日志信息。

内容的提问来源于stack exchange,提问作者bitcanvas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:35:22