You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Gonzalo Herreros-Gonzalez <GO...@Amdocs.com> on 2010/02/05 11:39:48 UTC

New rolling appender proposal

Hi,

I came across an issue with the RollingFileAppender and I would like to contribute back my solution.

The problem is that we have a RollingFileAppender to log customer usage. So you have, let's say a file with the user activity for each minute.
This logs are exported into other systems that do monitoring and business intelligence based on that feedback.

The problem is that the rolling is tied to log events, so if events stop happening (the customers end their working hours) the log is not rolled until the next morning when the system is used again. So the external systems don't receive that log until the next day since the export script cannot do the rolling by itself.

Therefore I developed and extension of the appender, that schedules itself to rollover the file at the expected time if it hasn't been rolled by events.
I have tested it and I haven't seen any impact in performance. Only one thread is used, which is enough for a reasonable number of appenders of this type.

See below the source code of the new appender.
Let me know what you think.

Regards, Gonzalo


/*
 * Copyright 1999-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */



package org.apache.log4j;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.helpers.LogLog;

/**
 * Extends the default time based rolling file appender to roll the files in a synchronous manner.
 * That means when the time is due the file will be rolled, instead of rolling the file when
 *  a new event is logged and the timeout is detected.
 *
 * @author Gonzalo Herreros
 */
public class SynchronousDailyRollingFileAppender extends DailyRollingFileAppender
{
    //One thread should be enough for a reasonable amount of rolling appenders
    //Anyway there should be no harm if there is a small delay
    private static ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1);

    /* (non-Javadoc)
     * @see org.apache.log4j.DailyRollingFileAppender#activateOptions()
     */
    public void activateOptions() {
        super.activateOptions();
        scheduleNextRollover();
    }

    /**
     * Schedule the next call so we try to rollover
     */
    protected void scheduleNextRollover() {
        long nextTime = rc.getNextCheckMillis(now);
        long lapse = nextTime - now.getTime();
        if (lapse > 0){
            synchronized(scheduler) {
                scheduler.schedule(new Runnable() {
                    public void run() {
                        try {
                            //Prevent conflicts with other threads writing the log
                            synchronized(this){
                                now.setTime(System.currentTimeMillis());
                                rollOver();
                            }
                        } catch(Throwable t) {
                            LogLog.error("rollOver() failed.", t);
                        }
                        scheduleNextRollover();
                    }
                }, lapse + 1, TimeUnit.MILLISECONDS);
            }
        }
    }
}

This message and the information contained herein is proprietary and confidential and subject to the Amdocs policy statement,
you may review at http://www.amdocs.com/email_disclaimer.asp