【问题标题】:Why the ConfigurationBuilder API does not create a Logger?为什么 ConfigurationBuilder API 不创建 Logger?
【发布时间】:2019-12-23 08:00:24
【问题描述】:

我正在尝试使用 Spring Boot 应用程序中的 ConfigurationBuilder API 以编程方式创建 log4j2 记录器。 但是代码似乎不能正常工作。

下面是我试图实现的代码sn-p:

    String loggerName = "testLogger";
    final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();

    final LoggerComponentBuilder loggerComp = builder.newLogger(loggerName, Level.ALL).addAttribute("additivity",
            false);

    builder.add(loggerComp);

    LoggerContext ctx = Configurator.initialize(builder.build());
    final Configuration config = ctx.getConfiguration();
    ctx.start();
    ctx.updateLoggers();
    System.out.println(ctx.hasLogger(loggerName));

我希望在 LoggerContext 中创建记录器并使用

进行测试

ctx.hasLogger(loggerName)

它应该返回 true。但它返回 false。

上述代码中可能存在的问题。

在一些调试中,我发现 ctx.hasLogger 进入 loggerRegistry 以查找具有作为参数提供的 NAME 的记录器是否存在并且它没有找到它,因此它返回 false。 我认为自定义记录器从未创建,这就是 ctx.hasLogger() 返回 false 的原因。

另外,我没有明确使用 log4j2 的任何配置文件。 spring boot应用程序运行时会考虑到自己的log4j2.xml,如下:

 <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
        <Properties>
            <Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
            <Property name="LOG_LEVEL_PATTERN">%5p</Property>
            <Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd         
 HH:mm:ss.SSS
            </Property>
            <Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{%pid}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
            <Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} %pid --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
            </Properties>
        <Appenders>
            <Console name="Console" target="SYSTEM_OUT" follow="true">
                <PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
            </Console>
        </Appenders>
        <Loggers>
            <Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
            <Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
            <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
            <logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
            <Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
        <Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
        <Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
        <logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
        <Root level="info">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

【问题讨论】:

  • builder.add(loggerComp); 行只为记录器添加“配置”,并没有实际创建记录器。 ctx.hasLogger(loggerName) 将在您调用 ctx.getLogger(loggerName) 后返回 true,其中记录器实际上是使用您添加的配置创建的。
  • @samabcde :是的,我同意 ctx.getLogger(loggerName) 可以工作,但有什么方法可以验证创建的记录器是否使用添加的配置。
  • 我想图书馆应该正确地完成这项工作。如果你真的要验证,可以从getLogger(loggerName)创建的logger实例中调用getLevel()isAddictive()等方法来检查这些属性是否与配置匹配。
  • @samabcde :谢谢,这些检查帮助我验证。但不幸的是,它们显示不匹配的结果,如上述代码,getLevel() - 应该返回 ALL,但我得到 INFO 和 isAddictive()也恰恰相反。
  • 我认为问题是在创建配置时,log4j2考虑到了spring boot的log4j2.xml,因为我没有自己提供。我也更新了问题的描述。

标签: java spring-boot logging log4j2


【解决方案1】:

我终于找到了我所面临问题的解决方案。问题是在配置开始时。

最初,LoggerContext 以找到的默认配置(春季启动)开始,即当我们执行 ctx.start() 时。

但是为了使我们的配置工作,我们需要从我们的配置开始上下文,即 修改代码如下:

Configuration configuration = builder.build(); ctx.start(configuration);

在此之后ctx.getLogger(loggerName) 工作得很好,可以返回具有指定配置的 Logger。 您可以通过在返回的记录器上调用getLevel()isAdditive() 来验证它以匹配您的配置。

感谢@samabcde,他的建议有助于达成最终解决方案。

【讨论】:

  • 有谁知道是否有任何方法可以配置它以便 LogManger.getLogger() 返回适当的记录器?这个解决方案对我有用,但是我必须将 LoggerContext DI 到我的所有类中。
  • 我在baeldung.com/log4j2-programmatic-config#configurationfactory 中找到了解决方案。使用自定义 ConfigurationFactory,Spring 使用您的自定义配置而不是默认配置。
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
  • 2016-01-31
相关资源
最近更新 更多