如何 运行 每个 JVM 桥接一次 jul-to-slf4j?
How to run jul-to-slf4j bridge once per JVM?
我想 运行 Surefire 并行模式(多个 JVM),其中每个 JVM 必须 运行:
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
恰好在第一次测试前一次。如何做到这一点?
有多种方法可以在测试套件的开头制作一些代码 运行。
这里有 4 个(我相信还有更多):
JUnit 通过 RunWith
Suite
with Suite.SuiteClasses
and BeforeClass
(adapted from examples in SuiteTest
):
@RunWith(Suite.class)
@SuiteClasses({FirstTest.class, SecondTest.class/*, ...*/, LastTest.class})
public static class AllWithSLF4JBridgeHandler {
@BeforeClass
public static void registerRootLoggerHandlers() {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
TestNG 与 BeforeSuite:
/**
* Base class for each test class (i.e. every test class should extend this class).
*/
public abstract class BaseTest {
@BeforeSuite
public void registerRootLoggerHandlers() {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
TestNG 与 Guice:
/**
* Test module. Each test class should be annotated with `@Guice(TestModule.class)`.
*/
public class TestModule implements Module {
@Override
public void configure(Binder binder) {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
Static initialization blocks(独立于测试框架):
/**
* Base class for each test class (i.e. every test class should extend this class).
*/
public abstract class BaseTest {
static {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}
}
我不确定所有这些方法如何与 Surefire 的并行模式一起工作。方法 1 和 2 可能在那里行不通,但我相信方法 3 和 4 应该。
另一种选择是不使用 SLF4JBridgeHandler
的编程安装,而是使用 java.util.logging.config 文件或 class(参见 LogManager
):
"java.util.logging.config.file":
logging.properties 文件:
// register SLF4JBridgeHandler as handler for the j.u.l. root logger
handlers = org.slf4j.bridge.SLF4JBridgeHandler
系统属性分配:
java -Djava.util.logging.config.file=/path/to/logging.properties ...
如果您事先知道日志文件的路径,这会很有效。
"java.util.logging.config.class":
如果您要部署一个 WAR 并且不知道该文件在哪里等等,那么使用文件可能不是一个好的选择,因此您也可以创建一个日志配置 class:
public class SLF4JBridgeHandlerInitializer {
public SLF4JBridgeHandlerInitializer() throws IOException {
String loggingConfigurationString = "handlers = " + SLF4JBridgeHandler.class.getName();
InputStream inputStream = new ByteArrayInputStream(loggingConfigurationString.getBytes());
LogManager.getLogManager().readConfiguration(inputStream);
}
}
系统属性分配:
java -Djava.util.logging.config.class=package.SLF4JBridgeHandlerInitializer ...
我以前做过这个,对我来说效果很好 (SLF4JBridgeHandler.Initializer by mfulton26 · Pull Request #57 · qos-ch/slf4j)。
只要设置了适当的系统 属性,这最后两个选项应该初始化每个 JVM 实例。
我想 运行 Surefire 并行模式(多个 JVM),其中每个 JVM 必须 运行:
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
恰好在第一次测试前一次。如何做到这一点?
有多种方法可以在测试套件的开头制作一些代码 运行。
这里有 4 个(我相信还有更多):
JUnit 通过
RunWith
Suite
withSuite.SuiteClasses
andBeforeClass
(adapted from examples inSuiteTest
):@RunWith(Suite.class) @SuiteClasses({FirstTest.class, SecondTest.class/*, ...*/, LastTest.class}) public static class AllWithSLF4JBridgeHandler { @BeforeClass public static void registerRootLoggerHandlers() { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); } }
TestNG 与 BeforeSuite:
/** * Base class for each test class (i.e. every test class should extend this class). */ public abstract class BaseTest { @BeforeSuite public void registerRootLoggerHandlers() { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); } }
TestNG 与 Guice:
/** * Test module. Each test class should be annotated with `@Guice(TestModule.class)`. */ public class TestModule implements Module { @Override public void configure(Binder binder) { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); } }
Static initialization blocks(独立于测试框架):
/** * Base class for each test class (i.e. every test class should extend this class). */ public abstract class BaseTest { static { SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); } }
我不确定所有这些方法如何与 Surefire 的并行模式一起工作。方法 1 和 2 可能在那里行不通,但我相信方法 3 和 4 应该。
另一种选择是不使用 SLF4JBridgeHandler
的编程安装,而是使用 java.util.logging.config 文件或 class(参见 LogManager
):
"java.util.logging.config.file":
logging.properties 文件:
// register SLF4JBridgeHandler as handler for the j.u.l. root logger handlers = org.slf4j.bridge.SLF4JBridgeHandler
系统属性分配:
java -Djava.util.logging.config.file=/path/to/logging.properties ...
如果您事先知道日志文件的路径,这会很有效。
"java.util.logging.config.class":
如果您要部署一个 WAR 并且不知道该文件在哪里等等,那么使用文件可能不是一个好的选择,因此您也可以创建一个日志配置 class:
public class SLF4JBridgeHandlerInitializer { public SLF4JBridgeHandlerInitializer() throws IOException { String loggingConfigurationString = "handlers = " + SLF4JBridgeHandler.class.getName(); InputStream inputStream = new ByteArrayInputStream(loggingConfigurationString.getBytes()); LogManager.getLogManager().readConfiguration(inputStream); } }
系统属性分配:
java -Djava.util.logging.config.class=package.SLF4JBridgeHandlerInitializer ...
我以前做过这个,对我来说效果很好 (SLF4JBridgeHandler.Initializer by mfulton26 · Pull Request #57 · qos-ch/slf4j)。
只要设置了适当的系统 属性,这最后两个选项应该初始化每个 JVM 实例。