log4j-jul 配置以某种方式通过 gradle junit5 测试使所有 log4j2 日志记录静音

时间:2021-02-26 18:41:09

标签: java gradle log4j2 junit5 java.util.logging

这里是完整的源代码https://github.com/xenoterracide/iv-adh

当我在 JUnit 任务中启用系统属性时,我的所有日​​志记录都会消失。

tasks.test {
  // Use junit platform for unit tests.
  useJUnitPlatform()

  // this isn't currently enabled in the code, so you can see the logging working when you run the ./gradlew build, but if you uncomment it, you'll see the logs disappear.
  systemProperty("java.util.logging.manager","org.apache.logging.log4j.jul.LogManager")

  testLogging {
    lifecycle {
      showStandardStreams = true
      displayGranularity = 2
      events.addAll(listOf(
        TestLogEvent.STARTED,
        TestLogEvent.PASSED,
        TestLogEvent.SKIPPED,
        TestLogEvent.FAILED
      ))
    }
  }
  reports {
    html.isEnabled = false
    junitXml.isEnabled = true
  }
}

这是我的 log4j config

  static void configureLog4j() {
    var console = "console";
    var builder = ConfigurationBuilderFactory.newConfigurationBuilder();

    var defaultAppender = builder.newAppender( console, "CONSOLE" )
      .addAttribute( "target", ConsoleAppender.Target.SYSTEM_OUT );
    defaultAppender.add( builder.newLayout( "PatternLayout" )
      .addAttribute( "pattern", "%highlight{%-5level} - %msg%n      - Context %MDC%n%throwable" ) );

    builder.add( defaultAppender );
    builder.add( builder.newRootLogger( Level.ERROR )
      .add( builder.newAppenderRef( console ) ) );
    builder.add( builder.newLogger( "com.xenoterracide", Level.DEBUG ) );
    Configurator.initialize( builder.build() );
  }

这是 test 的相关部分

class RecordAssemblerTest {

  @BeforeAll
  static void configureLog4j() {
    Application.configureLog4j();
  }

  @Test
  void parsers() throws Exception {

我确实在这里看到了其他答案,但这是他们给出的答案,所以我不确定为什么它会阻止我的其他日志记录。我的最终目标是让所有日志记录工作,但使 javax.money/moneta 日志记录静音。

更新:

在使用 JavaExec 时在 ./gradlew run 任务中设置属性有效,但不确定为什么它不适用于测试。

tasks.withType<JavaExec> {
  systemProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager")
}

1 个答案:

答案 0 :(得分:1)

你可以debug logging using System.out。使用您的代码添加 vcl.h 方法并使用 @AfterAll 调用它。当我使用您的代码执行此操作并运行 printConfig 时,我得到以下输出:

 ./gradlew build

要点是:

  1. org.apache.logging.log4j.jul.LogManager 已安装。 [通过]
  2. org.slf4j.bridge.SLF4JBridgeHandler 已安装并设置为 ALL。您的代码正在使用 log4j,但似乎也设置了 SLF4J [警告]
  3. 所有记录器都根据 FileProcessorTest STANDARD_ERROR java.util.logging.config.class was null java.util.logging.config.file was null LogManager=org.apache.logging.log4j.jul.LogManager scn=CoreLogger, n=, uph=true, l=WARNING, fl=null ->org.slf4j.bridge.SLF4JBridgeHandler, h=ALL, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management.timer, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.LauncherConfigurationParameters, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.EngineDiscoveryOrchestrator, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.descriptor.JupiterTestDescriptor, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.ServiceLoaderTestExecutionListenerRegistry, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.descriptor.MethodBasedTestDescriptor, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.execution.JupiterEngineExecutionContext, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.discovery.MethodOrderingVisitor, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.InternalTestPlan, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management.monitor, uph=true, l=null, fl=null scn=CoreLogger, n=javax.management.notification, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.execution.ConditionEvaluator, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management.mbeanserver, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.ServiceLoaderPostDiscoveryFilterRegistry, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.extension.TimeoutConfiguration, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.TestExecutionListenerRegistry, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.extension.MutableExtensionRegistry, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.discovery.MethodSelectorResolver, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management.relation, uph=true, l=null, fl=null scn=CoreLogger, n=javax.management.modelmbean, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.execution.ExecutableInvoker, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.javamoney.moneta.spi.MoneyUtils, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.EngineIdValidator, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.descriptor.DisplayNameUtils, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.commons.util.ReflectionUtils, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management.misc, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.platform.engine.support.hierarchical.NodeTestTask, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.javamoney.moneta.spi.MonetaryConfig, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=javax.management.mlet, uph=true, l=null, fl=null scn=CoreLogger, n=org.junit.jupiter.engine.config.EnumConfigurationParameterConverter, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.junit.platform.commons.util.ClasspathScanner, uph=true, l=SEVERE, fl=null scn=CoreLogger, n=org.javamoney.moneta.DefaultMonetaryContextFactory, uph=true, l=SEVERE, fl=null [PASS]
  4. 发布到 SLF4JBridgeHandler
  5. 没有 uph=true 记录器。项目使用 logj。 [通过]
  6. 根记录器设置为警告。只会看到 WARN 和 ERROR。 [有问题]
  7. 子记录器是 null 和 SEVERE 的混合体。只会看到警告和错误。[QUESTIONABLE]

所以让我们再次运行它,但不要在任何地方设置 log4j.jul.LogManager,我将使用 System.out:

com.xenoterracide

现在,当我比较两次运行时,您可以看到:

  1. 当 log4j 日志管理器运行时,级别要么是从根记录器继承的警告,要么是在子记录器上设置的严重级别。
  2. 运行 JUL 日志管理器时,所有级别都继承了 INFO。

我认为您看到的问题在于 Application.java#L54

  1. 您需要将根记录器级别设置为给定级别。 FileProcessorTest STANDARD_OUT java.util.logging.config.class was null java.util.logging.config.file was null LogManager=java.util.logging.LogManager scn=RootLogger, n=, uph=true, l=INFO, fl=null ->java.util.logging.ConsoleHandler, h=INFO, fl=null scn=Logger, n=org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation, uph=true, l=null, fl=null scn=Logger, n=javax.management.timer, uph=true, l=null, fl=null scn=Logger, n=global, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.LauncherConfigurationParameters, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.EngineDiscoveryOrchestrator, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.descriptor.JupiterTestDescriptor, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.ServiceLoaderTestExecutionListenerRegistry, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.descriptor.MethodBasedTestDescriptor, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.execution.JupiterEngineExecutionContext, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.discovery.MethodOrderingVisitor, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.InternalTestPlan, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.execution.ConditionEvaluator, uph=true, l=null, fl=null scn=Logger, n=javax.management.monitor, uph=true, l=null, fl=null scn=Logger, n=javax.management.notification, uph=true, l=null, fl=null scn=Logger, n=javax.management.mbeanserver, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.ServiceLoaderPostDiscoveryFilterRegistry, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.extension.TimeoutConfiguration, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.TestExecutionListenerRegistry, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.extension.MutableExtensionRegistry, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.discovery.MethodSelectorResolver, uph=true, l=null, fl=null scn=Logger, n=javax.management.relation, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.execution.ExecutableInvoker, uph=true, l=null, fl=null scn=Logger, n=javax.management.modelmbean, uph=true, l=null, fl=null scn=Logger, n=org.javamoney.moneta.spi.MoneyUtils, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter, uph=true, l=null, fl=null scn=Logger, n=javax.management, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.EngineIdValidator, uph=true, l=null, fl=null scn=Logger, n=org.javamoney.moneta.Money, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.descriptor.DisplayNameUtils, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.commons.util.ReflectionUtils, uph=true, l=null, fl=null scn=Logger, n=javax.management.misc, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.engine.support.hierarchical.NodeTestTask, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry, uph=true, l=null, fl=null scn=Logger, n=org.javamoney.moneta.spi.MonetaryConfig, uph=true, l=null, fl=null scn=Logger, n=org.junit.jupiter.engine.config.EnumConfigurationParameterConverter, uph=true, l=null, fl=null scn=Logger, n=org.junit.platform.commons.util.ClasspathScanner, uph=true, l=null, fl=null scn=Logger, n=javax.management.mlet, uph=true, l=null, fl=null scn=Logger, n=org.javamoney.moneta.DefaultMonetaryContextFactory, uph=true, l=null, fl=null
  2. log4j 配置未正确更新 JUL 记录器级别。这指向 Application::configureLog4j 中的错误。
  3. 未安装 org.slf4j.bridge.SLF4JBridgeHandler。也许当安装了桥接处理程序时,输出将发送到 SLF4J,并且没有为 SLF4J 设置控制台附加程序。

您可以尝试的一件事是明确排除 jul-to-slf4j 包。也许这将允许 logj4 控制 jul 而不是 slf4j。还有一个相关信息Java logging: slf4j over jul and log4j2