Search code examples
javaoracle-adflog4j2threadcontext

Unable to create multiple log files based on the ThreadContext map values using routing appender in log4j2


I'm using the log4j2 jars in the oracle adf application build on 12c.

Requirement: Create multiple log files based on the session and ability to change the logging properties dynamically.

Log4j2.xml file

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" packages="apps.adfAppUI.ui.bean">
    <Appenders>
        <File name="file" fileName="./adfAppCustomLogs/TestLog4j2.log">
            <PatternLayout>
                <Pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %class %L %M - %msg%xEx%n</Pattern>
            </PatternLayout>
        </File>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%m%n"/>
        </Console>
        <Routing name="AppRouting">
            <Routes pattern="$${ctx:ROUTINGKEY}">
                <!-- This route is chosen if ThreadContext has value 'user' for key ROUTINGKEY. -->
                <Route key="USER">
                    <RollingFile name="Rolling-USER-${ctx:ROUTINGKEY}-${ctx:LOGGEDSESSIONID}" append="true" fileName="./adfAppCustomLogs/${ctx:ROUTINGKEY}-${ctx:LOGINID}-${ctx:LOGGEDSESSIONID}.log"
                                 filePattern="./adfAppCustomLogs/archive/${date:yyyy-MM}/${ctx:LOGINID}-%d{MM-dd-yyyy}-%i.txt.gz">
                        <PatternLayout>
                            <Pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %class %L %M - %msg%xEx%n</Pattern>
                        </PatternLayout>
                        <Policies>
                            <TimeBasedTriggeringPolicy interval="6" modulate="true" />
                            <SizeBasedTriggeringPolicy size="50 MB"/>
                        </Policies>
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>
        <Async name="async" bufferSize="1000" includeLocation="true">
        <AppenderRef ref="AppRouting" />
    </Async>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <!--<AppenderRef ref="file" level="DEBUG"/> -->
            <AppenderRef ref="async"/>
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

I'm calling an utility class where the threadcontext values are set and clearled after logging.

Issue: Even though I change the threadcontext values for every session,I dont see multiple files being created. All the logs are appended to one file. But when I restart the server then a new file is generated and again all the session logs are being appended to it.

Thanks.


Solution

  • The below configuration will do the usecase.

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="trace">
        <MapFilter onMatch="ACCEPT" operator="or">
            <KeyValuePair key="$${ctx:LOGLEVELYN}" value="Y"/>
        </MapFilter>
        <Appenders>
            <File name="file" fileName="./adfAppCustomLogs/TestLog4j2.log">
                <PatternLayout>
                    <Pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %class %L %M - %msg%xEx%n</Pattern>
                </PatternLayout>
            </File>
            <Console name="STDOUT" target="SYSTEM_OUT">
                <PatternLayout pattern="%m%n"/>
            </Console>
            <Routing name="AppRouting">
                <Routes pattern="$${ctx:LOGGEDSESSIONID}">
                    <!-- This route is chosen if ThreadContext has no value for key ROUTINGKEY. -->
                    <Route key="$${ctx:LOGGEDSESSIONID}">
                        <RollingFile name="Rolling-ALL" fileName="./adfAppCustomLogs/DefaultAll.log"
                                     filePattern="./adfAppCustomLogs/archive/${date:yyyy-MM}/DefaultAll-%d{MM-dd-yyyy}-%i.txt.gz">
                            <PatternLayout>
                                <Pattern>%X %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %t %msg%xEx%n</Pattern>
                            </PatternLayout>
                            <Policies>
                                <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
                                <SizeBasedTriggeringPolicy size="10 MB"/>
                            </Policies>
                        </RollingFile>
                    </Route>
                    <!-- This route is chosen if ThreadContext has value other than null for key ROUTINGKEY. -->
                    <Route>
                        <RollingFile name="Rolling-OTHER-${ctx:LOGGEDSESSIONID}"
                                     fileName="./adfAppCustomLogs/${ctx:LOGINID}-${ctx:LOGGEDSESSIONID}.log"
                                     filePattern="./adfAppCustomLogs/archive/${date:yyyy-MM}/${ctx:LOGINID}-%d{MM-dd-yyyy}-%i.txt.gz">
                            <PatternLayout>
                                <Pattern>%X %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level %t %msg%xEx%n</Pattern>
                            </PatternLayout>
                            <Policies>
                                <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
                                <SizeBasedTriggeringPolicy size="10 MB"/>
                            </Policies>
                            <!-- <DefaultRolloverStrategy max="100"/> -->
                        </RollingFile>
                    </Route>
                </Routes>
            </Routing>
            <Async name="async" bufferSize="1000" includeLocation="true">
                <AppenderRef ref="AppRouting"/>
            </Async>
        </Appenders>
        <Loggers>
            <Root level="trace">
                <!--<AppenderRef ref="file" level="DEBUG"/> -->
                <AppenderRef ref="async"/>
                <AppenderRef ref="STDOUT"/>
            </Root>
        </Loggers>
    </Configuration>