rat
rat

Reputation: 2554

RollingFileAppender set RollingPolicy programmatically

For reasons I won't get into I'm forced to configure a log4j appender programmatically.

I want to use a RollingFileAppender so I can control the maximum number of files that are kept around.

Also I want to set this appender to use a TimeBasedRollingPolicy as that will automatically take care of compressing the rolled files.

Problem is I can't see a way to set this through code. When setting up a RollingFileAppender normally through a properties file you would have:

log4j.appender.LOGFILE.RollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy

There must be a way of setting this .... ? Can anyone shed some light, digging through the javadoc and the basic eclipse-reflection of the classes methods hasn't revealed the solution :(

Upvotes: 7

Views: 12352

Answers (5)

Kal
Kal

Reputation: 24910

You might need the log4j companions/extras to use the rolling.RollingFileAppender.

http://logging.apache.org/log4j/companions/index.html

EDIT:

Here is the api reference that lets you set the rolling policy.

http://logging.apache.org/log4j/companions/apidocs/org/apache/log4j/rolling/RollingFileAppender.html

Upvotes: 4

Glenn
Glenn

Reputation: 9150

This is based on cquezel's answer. Changing the file name on the active file name as well as the policy file name pattern did the trick for me. If you don't change the active file name, the current log was not visible until rotation occurred. In this case, I'm just changing the name of the log file from "Launcher".

private static final String LOG4J_ROLLING_FILE_NAME_TOKEN = "Launcher";

/*
 * Change the name of the the log file as configured through log4j.xml
 * by replacing the placeholder file name token ("Launcher") with the
 * a new "actionName".
 */
private static void log4jConfig(String actionName) {

    org.apache.log4j.Logger rootLogger = LogManager.getRootLogger();
    RollingFileAppender fileAppender = (RollingFileAppender)rootLogger.getAppender("fileAppender");

    // <param name="FileNamePattern" value="/var/log/Launcher.log.%d{yyyy-MM-dd}.gz"/>
    String currentLogFile = fileAppender.getFile();
    String newLogPattern = currentLogFile.replace(LOG4J_ROLLING_FILE_NAME_TOKEN, actionName);
    fileAppender.setFile(newLogPattern);

    TimeBasedRollingPolicy timeBasedRollingPolicy = (TimeBasedRollingPolicy) fileAppender.getRollingPolicy();
    String fileNamePattern = timeBasedRollingPolicy.getFileNamePattern();
    String newFileNamePattern = fileNamePattern.replace(LOG4J_ROLLING_FILE_NAME_TOKEN, actionName);;
    timeBasedRollingPolicy.setFileNamePattern(newFileNamePattern);
    timeBasedRollingPolicy.activateOptions();

    fileAppender.activateOptions();

    LOG.info("  Redirected launcher log output to log pattern: " + newFileNamePattern);
}

Upvotes: 3

codder
codder

Reputation: 21

this example will be creating logger for each minute, if u want to change for each day change the datepattern value.

<appender name="ASYNC" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="./applogs/logger.log" />           
         <param name="Append" value="true" />           
        <param name="Threshold" value="debug" />          
         <appendToFile value="true" /> 
         <param name="DatePattern" value="'.'yyyy_MM_dd_HH_mm"/> 
         <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy"> 
         <param name="fileNamePattern" value="./applogs/logger_%d{ddMMMyyyy HH:mm:ss}.log"/>
         <param name="rollOver" value="TRUE"/>   
         </rollingPolicy>            
         <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ddMMMyyyy HH:mm:ss,SSS}^[%X{l4j_mdc_key}]^[%c{1}]^ %-5p %m%n" />
         </layout>
    </appender>
    <root>
        <level value="info" />
        <appender-ref ref="ASYNC" />
    </root>

Upvotes: -2

cquezel
cquezel

Reputation: 4487

Here is how I override the log4j.xml file to set a new filename to the logger named "TheLoggerName" whose RollingFileAppender is named "TheAppenderName". You can probably base your solution on this.

import org.apache.log4j.Logger;
import org.apache.log4j.rolling.RollingFileAppender;
import org.apache.log4j.rolling.TimeBasedRollingPolicy;

...

private static void afunction(String pTheNewFileName) {

Logger logger = Logger.getLogger("TheLoggerName");
RollingFileAppender rfappender = (RollingFileAppender) logger.getAppender("TheAppenderName");
TimeBasedRollingPolicy timeBasedRollingPolicy = (TimeBasedRollingPolicy) rfappender.getRollingPolicy();
timeBasedRollingPolicy.setFileNamePattern("newfilename%d{yyyy-MM}");
timeBasedRollingPolicy.activateOptions();
rfappender.activateOptions();
}

Upvotes: 5

MJB
MJB

Reputation: 9389

I had to do this recently. This doesn't use RollingFileAppender, but I think you'll get the idea

    public synchronized static MNLogger getLogger() {
        if (logInstance != null) return logInstance;
        Layout layout = new PatternLayout("%d{ABSOLUTE} [%t] %c{1} %m%n");
        Logger logger=Logger.getLogger(MigrationLogger.class);
        Appender a=logger.getAppender("MigrationMemory");
        if (a ==null) {

            //log4j.appender.M=org.apache.log4j.MemoryAppender
            MemoryAppender m=new MemoryAppender();
            m.setLayout(layout);
            m.setName("MigrationMemory");
            logger.addAppender(m);          
        }
        a=logger.getAppender("MigrationDisk");
        if (a ==null) {


            String tomcat=null;
            try {
                tomcat=JSPLogger.getTomcatPath();
            } catch(Exception e) {
                try {
                    tomcat=JSPLogger.getTempDir();
                } catch (IOException e1) {
                    /* swallow*/
                }
            }
            String filename=tomcat+File.separator+"logs"+File.separator+"Migration.log";

            try {

                FileAppender f =new FileAppender(layout,filename,true);
                f.setName("MigrationDisk");
                logger.addAppender(f);
            } catch (IOException e) {
                /* swallow */
            }
//          ConsoleAppender c=new ConsoleAppender(layout);
    //      logger.addAppender(c);
        }
        logger.setLevel(Level.ALL);
        logInstance=new LoggerWrap(logger);
        return logInstance;

    }

Upvotes: 1

Related Questions