I don't think there's any lingering threads, Carter. I changed my test to follow the pattern of AsyncLoggerConfigErrorOnFormat.java. Same story -- works locally; in CI, it works if it's the only test that's run; and intermittently if run with the whole suite. The test is very simple and should look familiar as it's inspiration is from doNotProcessPlaceholdersTwice in AsyncLoggerConfigErrorOnFormat.java.
class Scratch { private static BufferedReader _reader; @BeforeClass public static void beforeClass() throws IOException { System.setProperty("log4j2.logEventFactory", MyGoodLogEventFactory.class.getName()); File tmpFile = File.createTempFile(Scratch.class.getName(), ".log"); tmpFile.deleteOnExit(); System.setProperty("log-file", tmpFile.getAbsolutePath()); System.setProperty(CONFIGURATION_FILE_PROPERTY, "fileAppender.xml"); _reader = new BufferedReader(new FileReader(tmpFile)); } @AfterClass public static void afterClass() { IOUtils.closeQuietly(_reader); } @Test public void Test_that_slf4j_log_messages_with_marker_get_handled_correctly() throws IOException { // GIVEN: An SLF4J logger Logger slf4jLogger = LoggerFactory.getLogger("FileLogger"); // WHEN: The SLF4J logger is used with the "MASK" marker slf4jLogger.debug(MyGoodMaskMarker.MY_GOOD_SLF4J_MARKER, "Hello, {}", "test"); // THEN: The resulting message is as expected Assert.assertEquals("Hello, XYZ", _reader.readLine()); } } The fileAppender.xml contains this: <Configuration status="WARN"> <Appenders> <File name="File1" fileName="${sys:log-file}" bufferedIO="false" immediateFlush="true" append="false"> <PatternLayout> <Pattern>%m%n</Pattern> </PatternLayout> </File> </Appenders> <Loggers> <Root level="DEBUG"> <AppenderRef ref="File1"/> </Root> </Loggers> </Configuration> Two questions: 1. Do you see any issues with this test code? 2. Is there some other way to set the LogEventFactory besides a system property? I don't have to use the system property. That can be manually tested. On Wed, Sep 29, 2021 at 8:42 PM Carter Kozak <cko...@ckozak.net> wrote: > > I think the LoggerContextRule can fail to apply the provided configuration if > another thread happens to access a logger (re-initializing the default > config) after the rule has stopped the old context, but before it has > initialized the new one. We may be able to update it with a loop so it tries > harder, ideally throwing an exception if it fails to set the expected context. > Is there any chance another test may be leaking threads beyond the scope of > the test? > > -ck > > On Wed, Sep 29, 2021, at 14:33, Gary Gregory wrote: > > Another reason to stick to Maven ;-) > > > > On Wed, Sep 29, 2021, 14:32 Travis Spencer <tra...@curity.io> wrote: > > > > > Thanks, Gary, for the reply. Unfortunately, a -D approach means a ton > > > of Gradle voodoo. I can ask one of the witchdocers to help with that, > > > but will try to copy the technique used AsyncLoggerConfigErrorOnFormat > > > first. Will report back on how it goes either way. Happy to receive > > > additional suggestions in the meantime. > > > > > > > > > On Wed, Sep 29, 2021 at 8:08 PM Gary Gregory <garydgreg...@gmail.com> > > > wrote: > > > > > > > > I would suggest finding some baseline that works by using -D on the > > > command > > > > line definition of your CI. > > > > > > > > Gary > > > > > > > > On Wed, Sep 29, 2021, 12:12 Travis Spencer <tra...@curity.io> wrote: > > > > > > > > > Greetings, Log4j list. > > > > > > > > > > I am testing some extensions that I have made to my usage of Log4j. > > > > > This usage involves a custom log event factory. I set this in my > > > > > actual program on startup using a system property. Now, to test this > > > > > in a unit test, I'm trying to set a system property in the same sort > > > > > of way. To that end, I have a static block in the test and a JUnit > > > > > ClassRule like this: > > > > > > > > > > static > > > > > { > > > > > System.setProperty("log4j2.logEventFactory", > > > > > MyGoodLogEventFactory.class.getName()); > > > > > } > > > > > > > > > > @ClassRule > > > > > public static LoggerContextRule _context = new > > > > > LoggerContextRule("myGoodConfig.xml"); > > > > > > > > > > This works perfectly on my local machine. In our CI system, however, > > > > > this fails sometimes. If I run only this one test in the CI system, it > > > > > passes every time. If I run all unit tests, however, it usually fails, > > > > > but does occasionally succeed. The hypothesis is that it depends on > > > > > which unit test is run first and whether or not the Log4j subsystem is > > > > > initialized yet. If it's not, the system property above is set and > > > > > everything works. If the Log4j subsystem is initialized, however, by > > > > > the time this test runs, then the system property (and thus the log > > > > > event factory) is not used. > > > > > > > > > > To test this hypothesis, I updated the test to do this instead: > > > > > > > > > > static > > > > > { > > > > > System.setProperty("log4j2.logEventFactory", > > > > > MaskedLogEventFactory.class.getName()); > > > > > LoggerContextRule context = new > > > LoggerContextRule("myGoodConfig.xml"); > > > > > if (context.getLoggerContext() != null) context.reconfigure(); > > > > > _context = context; > > > > > } > > > > > > > > > > @ClassRule > > > > > public static LoggerContextRule _context; > > > > > > > > > > This had no effect though, and the test still passed locally, passed > > > > > remotely if it was the only test run, but failed intermittently if run > > > > > as a part of the entire suite. > > > > > > > > > > Looking through the Log4j source, I only found one test that was > > > > > setting a custom log event factory, > > > > > > > > > > > > > src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java. > > > > > This test, however, doesn't use the LoggerContextRule to configure the > > > > > system. I really like this API for the tests and would like to > > > > > continue to use it. > > > > > > > > > > Can anyone offer me help in: > > > > > > > > > > 1. Confirming that my hypothesis is correct that the tests likely fail > > > > > intermittently due to the initialization state of the Log4j subsystem > > > > > 2. Suggest a way to make the rest more resilient > > > > > > > > > > TIA! > > > > > > > > > > Travis Spencer > > > > > > > > > > --------------------------------------------------------------------- > > > > > To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org > > > > > For additional commands, e-mail: log4j-user-h...@logging.apache.org > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org > > > For additional commands, e-mail: log4j-user-h...@logging.apache.org > > > > > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-user-h...@logging.apache.org