Search code examples
javamultithreadingjunit4log4j2maven-surefire-plugin

How to read from multithreading log4j2 buffer


I have executed automated test cases with multithreads, managed by maven-surefire-plugin. Each class has their own thread where it is executing and the log4j2 is configured with bufferIO = true and immediateFlush= true. In the output file, all the threads are mixing the information. I know that log4j2 has this buffer and I would like to know if each thread has their own buffer and if I can read from it before the information is written into the output file.

I read other question related to this topic, but it hasn't arrived at a solution. And for that reason, I'm trying to search another path to follow.


Solution

  • The first thing I found is that JUnit5 is the cause of the mixed output log file, when we execute the test cases in multithreading way. When I used JUnit4 the default output, usually the console waits for the end of the test case to write.

    In other hand the output file from log4j, when the user execute it with multithreding, always it shows mixing all the threads, regardless of the JUnit version.

    Them, I add the thread id to the log4j layout pattern: %d{yyyy-MM-dd HH:mm:ss} %-5p- **[%tid]** %m%n

    And after finish each thread I read the last lines of the output log4j file and I filter by the thread id number to obtain the relevant lines. With this point I had to solve other problem. How to obtain the absolute path of a dynamic log4j output log file? I test two solutions:

    1. By reflection (not recommended, but faster)
    2. Implement your own FileAppender to create a method to access to the fileName field

    The two steps to follow the first option are this:

    LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    Appender appender = ctx.getConfiguration().getAppenders().get("file");
    

    The appendervariable has the fileName field, but it is private.