我将尽力解释这一点,但它相当复杂。我从事的项目希望人们能够使用 java 配置文件和属性覆盖 logback.xml 设置。
例如,如果我有以下内容
logback.xml
<logger name="unit.test.l1.l2.l3" level="ERROR"/>
然后有一个像这样的属性文件
logger.unit.test.l1.l2.l3=DEBUG
这在 SLF4J v1 中使用 Logback
LoggerContextListener
code 并扩展 ContextAwareBase
类工作得很好,但我最终被迫升级到 2,当我测试失败时,说这是错误。本质上,看起来 LoggerFactory.bind()
code 函数中的一些更改改变了上下文的创建方式。现在看来 logback 函数ContextSelectorStaticBinder.getSingleton()
code在 1.x 版本之前似乎是在这里调用它所以我可以在那里清理看到它被调用,但现在它使用初始化。
有谁知道这种模式是如何改变的?有人能给我指出正确的发布文档或 PR/示例吗?我猜我在 SLF4J 中缺少一些 Logback 配置,或者可能需要添加另一个类。
更深入地观察,这可能会在 Logback 方面发生变化,看起来整段代码已被删除而没有替换(并且留下没有 TODO 或说明的注释代码似乎很糟糕)...
// private final ContextSelectorStaticBinder contextSelectorBinder =
// ContextSelectorStaticBinder.getSingleton();
// private static Object KEY = new Object();
// private volatile boolean initialized = false;
...
// if (!initialized) {
// return defaultLoggerContext;
//
//
// if (contextSelectorBinder.getContextSelector() == null) {
// throw new IllegalStateException("contextSelector cannot be null. See also " + NULL_CS_URL);
// }
// return contextSelectorBinder.getContextSelector().getLoggerContext();
为什么这个被注释掉了?还有关于这个的更多文档吗?
很难帮助您解决实际问题,因为您还没有发布任何代码 - 而且我认为找到 Logback 更改的原因并不能真正帮助您。
Spring 属性文件可用于覆盖记录器级别,但您需要在 logging.level 下设置属性。
这是一个(有效的)测试来说明:
@SpringBootApplication
class LoggerApp {
}
@SpringBootTest(
classes = LoggerApp.class,
properties = {
"logging.level.playground.LoggerTest=DEBUG"
}
)
public class LoggerTest {
@Test
public void testThatLoggingLevelIsOverriddenFromProperties() {
var logger = LoggerFactory.getLogger(LoggerTest.class);
Assertions.assertTrue(logger.isDebugEnabled());
}
}
使用以下 logback.xml 运行:
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<logger name="playground.LoggerTest" level="ERROR"/>
</configuration>