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

Reply via email to