0
votes

I am logging to file "file.log" with 2 loggers(logger1 and logger2). One has time-based rollover policy set to daily while the other is set to hourly. Once I make the switch to logger2, I do not go back to logger1. But, the rollovers stop after the switch to logger2 since file.log has logs from both loggers. I don't want to log to separate files corresponding to each logger and then rollover each independently.

Rollingfile appender associated with logger1:

<FileName>file.log</FileName>
<FilePattern>../archive/log-%d{yyyy-MM-dd}.log</FilePattern>

Rollingfile appender associated with logger2:

<FileName>file.log</FileName>
<FilePattern>../archive/log-%d{yyyy-MM-dd-HH}.log</FilePattern>

How do I change the rollover policy from daily to hourly for a log file while the server is running based on a toggle in code? (It can be 1 logger/2 loggers, but rollover should change from daily to hourly)

1
Have you tried RoutingAppender?D.B.
@D.B. hey, yes. But that just makes it easy to switch between loggers. I am able to do that. I just want the log file to roll-over in an hourly fashion when I switch to the appender with hourly rolling (despite the log file having logs from both loggers).Jeremy

1 Answers

0
votes

I'm not quite sure exactly what your desired output is, but I think this may be pretty close. Note that I'm going to provide an example that switches between rolling over the log every millisecond and every second, but you can modify to your needs.

Here's an example class that generates some logs. It sets a context key to "millis" so that log4j2 will select an appender that rolls the log every millisecond, generates some logs, waits a few seconds, then sets the context key to "sec" to select an appender that rolls the log every second, and then generates some more logs.

package example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;


public class SomeClass {
    private static final Logger log = LogManager.getLogger();

    public static void main(String[] args){
        ThreadContext.put("rollTime", "millis");

        log.debug("This is some debug!");
        log.info("Here's some info!");
        log.error("Some error happened!");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        ThreadContext.put("rollTime", "sec");
        log.debug("This is some debug!");
        log.info("Here's some info!");
        log.error("Some error happened!");
    }
}

Here is the log4j2 config file (in XML format):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <Routing name="MyRoutingAppender">
            <Routes pattern="$${ctx:rollTime}">
                <Route key="millis">
                    <RollingFile name="fileAppender1" fileName="logs/file.log"
                        filePattern="logs/file.%d{yyyy-MM-dd HH_mm_ss_SSS}.log">
                        <PatternLayout
                            pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger:%L - %msg%n" />
                        <Policies>
                            <TimeBasedTriggeringPolicy />
                        </Policies>
                        <DefaultRolloverStrategy max="2" />
                    </RollingFile>
                </Route>
                <Route key="sec">
                    <RollingFile name="fileAppender2" fileName="logs/file.log"
                        filePattern="logs/file.%d{yyyy-MM-dd HH_mm_ss}.log">
                        <PatternLayout
                            pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger:%L - %msg%n" />
                        <Policies>
                            <TimeBasedTriggeringPolicy />
                        </Policies>
                        <DefaultRolloverStrategy max="2" />
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console" />
            <AppenderRef ref="MyRoutingAppender" />
        </Root>
    </Loggers>
</Configuration>

Hopefully this example gets close to what you want to achieve and can help guide you to a solution.