RollingFile appender with file name to be determined at each logger invocation

343 Views Asked by At

I have a function which executes HTTP request/response and I would like to log the content of them.

Such code can be invoked multiple times within the same execution (classified by an "executionId") and each time can have a different "activityId".

What I would like to get is:

  • A new log file each time the executionId changes (so having execution1.log, execution2.log, execution3.log etc.)
  • To append into the potentially already existing file all logs for the same execution id (so if file execution1.log has already been created and I'm asked to log again something when executionId == execution1, then appending to that file).

With this purpose in mind, I have configured the following log4j2.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <properties>
        <property name="logDir">logs/</property>
    </properties>
    <appenders>
        <RollingFile name="HttpActivityTracingAppender" filePattern="${logDir}/http-logs/${ctx:executionId}.log" append="true">
            <PatternLayout pattern="%d{ISO8601} [%t] %c [execution:%X{executionId},activity:%X{activityId}] : %p - %m%n"/>
            <Policies>
                <OnStartupTriggeringPolicy />
            </Policies>
        </RollingFile>
    </appenders>
    <loggers>
        <logger name="HttpActivityTracing" level="trace">
            <appender-ref ref="HttpActivityTracingAppender"/>
        </logger>
    </loggers>
</configuration>

... and then I'm invoking the logger as follows:

    ThreadContext.put("id", UUID.randomUUID().toString());
    ThreadContext.putAll(Map.of("executionId", ..., "activityId", ...);
    ThreadContext.pop();
    myLogger.trace("bla bla bla");
    ThreadContext.clearAll();

The result is that the first time executionId is defined (let's say execution1), then a log file named execution1.log is created under logs/ as expected.

However, on consecutive executions with new values of executionId, I see the new executionId inside the log file but the name of the file used is still execution1.log.

So for example, inside execution1.log I will find stuff like:

2022-09-20T22:52:02,639 [main] HttpActivityTracing [execution:execution1,activity:activity1] : TRACE - ... (ok)
2022-09-20T22:52:02,639 [main] HttpActivityTracing [execution:execution1,activity:activity2] : TRACE - ... (ok)
2022-09-20T22:52:02,639 [main] HttpActivityTracing [execution:execution1,activity:activity3] : TRACE - ... (ok)
2022-09-20T22:52:02,639 [main] HttpActivityTracing [execution:execution2,activity:activity1] : TRACE - ... (NO, I WANT THIS INTO ANOTHER FILE "execution2.log")
2022-09-20T22:52:02,639 [main] HttpActivityTracing [execution:execution2,activity:activity2] : TRACE - ... (NO, I WANT THIS INTO ANOTHER FILE "execution2.log")

I have found several examples all over the web but I couldn't make this one work, I feel I'm not far but I can't make it work.

Can anyone please help?

P.s. I've tried to use fileName instead of filePattern in the RollingFile appender configuration, but it tries to create a file with the name ${ctx:executionId} in it which ends up being rejected by Windows because it contains an illegal character :.

1

There are 1 best solutions below

0
Matteo NNZ On BEST ANSWER

I ended up solving the issue with the exact same configuration than illustrated in the question, plus the following two lines of code after the ThreadContext.pop():

    LoggerContext context = (LoggerContext) LogManager.getContext(false);
    context.reconfigure();