log4j 按设定迭代日期删除过期日志文件,同一天内按设定大小分文件

项目需要使用log4j来记录日志,要求是【按设定迭代日期删除过期日志文件,同一天内按设定大小分文件】。废话不说上代码

 

package org.apache.log4j;

/**
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.APL file.
 */

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.helpers.CountingQuietWriter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;

/***
 * <p>
 * CompositeRollingAppender combines RollingFileAppender and DailyRollingFileAppender<br>
 * It can function as either or do both at the same time (making size based rolling files like RollingFileAppender until
 * a data/time boundary is crossed at which time it rolls all of those files as per the DailyRollingFileAppender) based
 * on the setting for <code>rollingStyle</code>.<br>
 * <br>
 * To use CompositeRollingAppender to roll log files as they reach a certain size (like RollingFileAppender), set
 * rollingStyle=1 (@see config.size)<br>
 * To use CompositeRollingAppender to roll log files at certain time intervals (daily for example), set rollingStyle=2
 * and a datePattern (@see config.time)<br>
 * To have CompositeRollingAppender roll log files at a certain size AND rename those according to time intervals, set
 * rollingStyle=3 (@see config.composite)<br>
 *
 * <p>
 * A of few additional optional features have been added:<br>
 * -- Attach date pattern for current log file (@see staticLogFileName)<br>
 * -- Backup number increments for newer files (@see countDirection)<br>
 * -- Infinite number of backups by file size (@see maxSizeRollBackups)<br>
 * <br>
 * <p>
 * A few notes and warnings: For large or infinite number of backups countDirection > 0 is highly recommended, with
 * staticLogFileName = false if time based rolling is also used -- this will reduce the number of file renamings to few
 * or none. Changing staticLogFileName or countDirection without clearing the directory could have nasty side effects.
 * If Date/Time based rolling is enabled, CompositeRollingAppender will attempt to roll existing files in the directory
 * without a date/time tag based on the last modified date of the base log files last modification.<br>
 * <br>
 * <p>
 * A maximum number of backups based on date/time boundries would be nice but is not yet implemented.<br>
 *
 * @author Kevin Steppe
 * @author Heinz Richter
 * @author Eirik Lygre
 * @author Ceki Gülcü
 */
/**
 * 实现 按天 删除日志
 * 按指定大小分文件记录
 *
 * @author zhangjianying
 *
 */
public class CompositeRollingAppender extends org.apache.log4j.FileAppender
{
    // The code assumes that the following 'time' constants are in a increasing
    // sequence.
    static final int TOP_OF_TROUBLE = -1;

    static final int TOP_OF_MINUTE = 0;

    static final int TOP_OF_HOUR = 1;

    static final int HALF_DAY = 2;

    static final int TOP_OF_DAY = 3;

    static final int TOP_OF_WEEK = 4;

    static final int TOP_OF_MONTH = 5;

    /*** Style of rolling to use */
    static final int BY_SIZE = 1;

    static final int BY_DATE = 2;

    static final int BY_COMPOSITE = 3;

    // Not currently used
    static final String S_BY_SIZE = "Size";

    static final String S_BY_DATE = "Date";

    static final String S_BY_COMPOSITE = "Composite";

    /***
     * The date pattern. By default, the pattern is set to "'.'yyyy-MM-dd" meaning daily rollover.
     */
    private String datePattern = "'.'yyyy-MM-dd";

    /***
     * The actual formatted filename that is currently being written to or will be the file transferred to on roll over
     * (based on staticLogFileName).
     */
    private String scheduledFilename = null;

    /*** The timestamp when we shall next recompute the filename. */
    private long nextCheck = System.currentTimeMillis() - 1;

    /*** Holds date of last roll over */
    Date now = new Date();

    SimpleDateFormat sdf;

    /*** Helper class to determine next rollover time */
    RollingCalendar rc = new RollingCalendar();

    /*** Current period for roll overs */
    int checkPeriod = TOP_OF_TROUBLE;

    /*** The default maximum file size is 10MB. */
    protected long maxFileSize = 10 * 1024 * 1024;

    /*** There is zero backup files by default. */
    protected int maxSizeRollBackups = 0;

    /*** How many sized based backups have been made so far */
    protected int curSizeRollBackups = 0;

    /*** not yet implemented */
    protected int maxTimeRollBackups = -1;

    protected int curTimeRollBackups = 0;

    /***
     * By default newer files have lower numbers. (countDirection < 0) ie. log.1 is most recent, log.5 is the 5th
     * backup, etc... countDirection > 0 does the opposite ie. log.1 is the first backup made, log.5 is the 5th backup
     * made, etc. For infinite backups use countDirection > 0 to reduce rollOver costs.
     */
    protected int countDirection = -1;

    /*** Style of rolling to Use. BY_SIZE (1), BY_DATE(2), BY COMPOSITE(3) */
    protected int rollingStyle = BY_COMPOSITE;

    protected boolean rollDate = true;

    protected boolean rollSize = true;

    /***
     * By default file.log is always the current file. Optionally file.log.yyyy-mm-dd for current formated datePattern
     * can by the currently logging file (or file.log.curSizeRollBackup or even file.log.yyyy-mm-dd.curSizeRollBackup)
     * This will make time based roll overs with a large number of backups much faster -- it won't have to rename all
     * the backups!
     */
    protected boolean staticLogFileName = true;

    /*** FileName provided in configuration. Used for rolling properly */
    protected String baseFileName;

    /*** The default constructor does nothing. */
    public CompositeRollingAppender()
    {
    }

    /***
     * Instantiate a <code>CompositeRollingAppender</code> and open the file designated by <code>filename</code>. The
     * opened filename will become the ouput destination for this appender.
     */
    public CompositeRollingAppender(Layout layout, String filename, String datePattern)
        throws IOException
    {
        this(layout, filename, datePattern, true);
    }

    /***
     * Instantiate a CompositeRollingAppender and open the file designated by <code>filename</code>. The opened filename
     * will become the ouput destination for this appender.
     *
     * <p>
     * If the <code>append</code> parameter is true, the file will be appended to. Otherwise, the file desginated by
     * <code>filename</code> will be truncated before being opened.
     */
    public CompositeRollingAppender(Layout layout, String filename, boolean append)
        throws IOException
    {
        super(layout, filename, append);
    }

    /***
     * Instantiate a CompositeRollingAppender and open the file designated by <code>filename</code>. The opened filename
     * will become the ouput destination for this appender.
     */
    public CompositeRollingAppender(Layout layout, String filename, String datePattern, boolean append)
        throws IOException
    {
        super(layout, filename, append);
        this.datePattern = datePattern;
        activateOptions();
    }

    /***
     * Instantiate a CompositeRollingAppender and open the file designated by <code>filename</code>. The opened filename
     * will become the output destination for this appender.
     *
     * <p>
     * The file will be appended to. DatePattern is default.
     */
    public CompositeRollingAppender(Layout layout, String filename)
        throws IOException
    {
        super(layout, filename);
    }

    /***
     * The <b>DatePattern</b> takes a string in the same format as expected by {@link SimpleDateFormat}. This options
     * determines the rollover schedule.
     */
    public void setDatePattern(String pattern)
    {
        datePattern = pattern;
    }

    /*** Returns the value of the <b>DatePattern</b> option. */
    public String getDatePattern()
    {
        return datePattern;
    }

    /***
     * Returns the value of the <b>maxSizeRollBackups</b> option.
     */
    public int getMaxSizeRollBackups()
    {
        return maxSizeRollBackups;
    }

    /***
     * Get the maximum size that the output file is allowed to reach before being rolled over to backup files.
     *
     * @since 1.1
     */
    public long getMaximumFileSize()
    {
        return maxFileSize;
    }

    /***
     * <p>
     * Set the maximum number of backup files to keep around based on file size.
     *
     * <p>
     * The <b>MaxSizeRollBackups</b> option determines how many backup files are kept before the oldest is erased. This
     * option takes an integer value. If set to zero, then there will be no backup files and the log file will be
     * truncated when it reaches <code>MaxFileSize</code>. If a negative number is supplied then no deletions will be
     * made. Note that this could result in very slow performance as a large number of files are rolled over unless
     * {@link #setCountDirection} up is used.
     *
     * <p>
     * The maximum applys to -each- time based group of files and -not- the total. Using a daily roll the maximum total
     * files would be (#days run) * (maxSizeRollBackups)
     */
    public void setMaxSizeRollBackups(int maxBackups)
    {
        maxSizeRollBackups = maxBackups;
    }

    /***
     * Set the maximum size that the output file is allowed to reach before being rolled over to backup files.
     *
     * <p>
     * This method is equivalent to {@link #setMaxFileSize} except that it is required for differentiating the setter
     * taking a <code>long</code> argument from the setter taking a <code>String</code> argument by the JavaBeans
     * {@link java.beans.Introspector Introspector}.
     *
     * @see #setMaxFileSize(String)
     */
    public void setMaxFileSize(String maxFileSize)
    {
        //默认 10M
        Long size =  1024 * 1024 * 10L ;

        maxFileSize = maxFileSize.toLowerCase();

        if(maxFileSize.endsWith("kb")){
            size = Long.valueOf(maxFileSize.replaceAll("kb", ""))*1024;
        }else if (maxFileSize.endsWith("m")){
            size = Long.valueOf(maxFileSize.replaceAll("m", ""))*1024*1024;
        }else {
            size =  1024 * 1024 * 10L ;
        }

        this.maxFileSize = size;
    }

    /***
     * Set the maximum size that the output file is allowed to reach before being rolled over to backup files.
     *
     * <p>
     * This method is equivalent to {@link #setMaxFileSize} except that it is required for differentiating the setter
     * taking a <code>long</code> argument from the setter taking a <code>String</code> argument by the JavaBeans
     * {@link java.beans.Introspector Introspector}.
     *
     * @see #setMaxFileSize(String)
     */
    public void setMaximumFileSize(long maxFileSize)
    {
        this.maxFileSize = maxFileSize;
    }

    protected void setQWForFiles(Writer writer)
    {
        qw = new CountingQuietWriter(writer, errorHandler);
    }

    // Taken verbatum from DailyRollingFileAppender
    int computeCheckPeriod()
    {
        RollingCalendar c = new RollingCalendar();
        // set sate to 1970-01-01 00:00:00 GMT
        Date epoch = new Date(0);
        if (datePattern != null)
        {
            for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++)
            {
                String r0 = sdf.format(epoch);
                c.setType(i);
                Date next = new Date(c.getNextCheckMillis(epoch));
                String r1 = sdf.format(next);
                // LogLog.debug("Type = "+i+", r0 = "+r0+", r1 = "+r1);
                if (r0 != null && r1 != null && !r0.equals(r1))
                {
                    return i;
                }
            }
        }
        return TOP_OF_TROUBLE; // Deliberately head for trouble...
    }

    // Now for the new stuff
    /***
     * Handles append time behavior for CompositeRollingAppender. This checks if a roll over either by date (checked
     * first) or time (checked second) is need and then appends to the file last.
     */
    protected void subAppend(LoggingEvent event)
    {

        if (rollDate)
        {
            long n = System.currentTimeMillis();
            if (n >= nextCheck)
            {

                now.setTime(n);
                nextCheck = rc.getNextCheckMillis(now);
                System.out.println("下次检查:" + nextCheck);
                rollOverTime();

                /*
                 * 这里我故意让程序 根据  curTimeRollBackups 来删除文件
                 * 也就是说 程序必须是连续的 正常的(无人为重启) 的运行到 curTimeRollBackups > maxTimeRollBackups
                 * 的时间 才会根据 maxTimeRollBackups 去删除日志
                 * 如果中途重启过,那么就会留下 从上次启动至 maxTimeRollBackups 这段时间的日志,这段时间的日志
                 * 只能人为删除
                 */

                // 如果开启过期日期删除
                if (maxTimeRollBackups != -1)
                {
                    if (countDirection < 0)
                    {
                        // Delete the oldest file, to keep Windows happy.
                        if (curTimeRollBackups > maxTimeRollBackups)
                        {
                            String pathDir =fileName.substring(0, getEndStart(fileName,'/'));                         

                            String filterName =getDateString(new Date(), -1* (maxTimeRollBackups+1));

                            File srcFolder = new File(pathDir);
                            CompositeFilenameFilter compositeFilenameFilter = new CompositeFilenameFilter(filterName);
                            if(srcFolder.isDirectory()){
                                File[] files = srcFolder.listFiles(compositeFilenameFilter);

                                for (File file : files)
                                {
                                    file.delete();
                                }
                            } 

                            curTimeRollBackups--;
                        }

                    }

                }
            }
        }

        if (rollSize)
        {

            if ((fileName != null) && ((CountingQuietWriter)qw).getCount() >= maxFileSize)
            {
                rollOverSize();
            }
        }

        super.subAppend(event);
    }

    public void setFile(String file)
    {
        baseFileName = file.trim();
        fileName = file.trim();
    }

    /***
     * Creates and opens the file for logging. If <code>staticLogFileName</code> is false then the fully qualified name
     * is determined and used.
     */
    public synchronized void setFile(String fileName, boolean append)
        throws IOException
    {
        if (!staticLogFileName)
        {
            scheduledFilename = fileName = fileName.trim() + sdf.format(now);
            if (countDirection > 0)
            {
                scheduledFilename = fileName = fileName + '.' + (++curSizeRollBackups);
            }
        }
        super.setFile(fileName, append, append, 1);

        // super.setFile(fileName, append);
        if (append)
        {
            File f = new File(fileName);
            ((CountingQuietWriter)qw).setCount(f.length());
        }
    }

    public int getCountDirection()
    {
        return countDirection;
    }

    public void setCountDirection(int direction)
    {
        countDirection = direction;
    }

    public int getRollingStyle()
    {
        return rollingStyle;
    }

    public void setRollingStyle(int style)
    {
        rollingStyle = style;
        switch (rollingStyle)
        {
            case BY_SIZE:
                rollDate = false;
                rollSize = true;
                break;
            case BY_DATE:
                rollDate = true;
                rollSize = false;
                break;
            case BY_COMPOSITE:
                rollDate = true;
                rollSize = true;
                break;
            default:
                errorHandler.error("Invalid rolling Style, use 1 (by size only), 2 (by date only) or 3 (both)");
        }
    }

    /**
     * public void setRollingStyle(String style) { if (style == S_BY_SIZE) { rollingStyle = BY_SIZE; } else if (style ==
     * S_BY_DATE) { rollingStyle = BY_DATE; } else if (style == S_BY_COMPOSITE) { rollingStyle = BY_COMPOSITE; } }
     */
    public boolean getStaticLogFileName()
    {
        return staticLogFileName;
    }

    public void setStaticLogFileName(boolean s)
    {
        staticLogFileName = s;
    }

    public void setStaticLogFileName(String value)
    {
        setStaticLogFileName(OptionConverter.toBoolean(value, true));
    }

    /***
     * Initializes based on exisiting conditions at time of <code>
     *  activateOptions</code>. The following is done:<br>
     * <br>
     * A) determine curSizeRollBackups<br>
     * B) determine curTimeRollBackups (not implemented)<br>
     * C) initiates a roll over if needed for crossing a date boundary since the last run.
     */
    protected void existingInit()
    {

        curSizeRollBackups = 0;
        curTimeRollBackups = 0;

        // part A starts here
        String filter;
        if (staticLogFileName || !rollDate)
        {
            filter = baseFileName + ".*";
        }
        else
        {
            filter = scheduledFilename + ".*";
        }

        File f = new File(baseFileName);
        f = f.getParentFile();
        if (f == null)
            f = new File(".");

        LogLog.debug("Searching for existing files in: " + f);
        String[] files = f.list();

        if (files != null)
        {
            for (int i = 0; i < files.length; i++)
            {
                if (!files[i].startsWith(baseFileName))
                    continue;

                int index = files[i].lastIndexOf(".");

                if (staticLogFileName)
                {
                    int endLength = files[i].length() - index;
                    if (baseFileName.length() + endLength != files[i].length())
                    {
                        // file is probably scheduledFilename + .x so I don't care
                        continue;
                    }
                }

                try
                {
                    int backup = Integer.parseInt(files[i].substring(index + 1, files[i].length()));
                    LogLog.debug("From file: " + files[i] + " -> " + backup);
                    if (backup > curSizeRollBackups)
                        curSizeRollBackups = backup;
                }
                catch (Exception e)
                {
                    // this happens when file.log -> file.log.yyyy-mm-dd which is normal
                    // when staticLogFileName == false
                    LogLog.debug("Encountered a backup file not ending in .x " + files[i]);
                }
            }
        }
        LogLog.debug("curSizeRollBackups starts at: " + curSizeRollBackups);
        // part A ends here

        // part B not yet implemented

        // part C
        if (staticLogFileName && rollDate)
        {
            File old = new File(baseFileName);
            if (old.exists())
            {
                Date last = new Date(old.lastModified());
                if (!(sdf.format(last).equals(sdf.format(now))))
                {
                    scheduledFilename = baseFileName + sdf.format(last);
                    LogLog.debug("Initial roll over to: " + scheduledFilename);
                    rollOverTime();
                }
            }
        }
        LogLog.debug("curSizeRollBackups after rollOver at: " + curSizeRollBackups);
        // part C ends here

    }

    /***
     * Sets initial conditions including date/time roll over information, first check, scheduledFilename, and calls
     * <code>existingInit</code> to initialize the current # of backups.
     */
    public void activateOptions()
    {

        // REMOVE removed rollDate from boolean to enable Alex's change
        if (datePattern != null)
        {
            now.setTime(System.currentTimeMillis());
            sdf = new SimpleDateFormat(datePattern);
            int type = computeCheckPeriod();
            // printPeriodicity(type);
            rc.setType(type);
            // next line added as this removes the name check in rollOver
            nextCheck = rc.getNextCheckMillis(now);
        }
        else
        {
            if (rollDate)
                LogLog.error("Either DatePattern or rollingStyle options are not set for [" + name + "].");
        }

        existingInit();

        super.activateOptions();

        if (rollDate && fileName != null && scheduledFilename == null)
            scheduledFilename = fileName + sdf.format(now);
    }

    /***
     * Rollover the file(s) to date/time tagged file(s). Opens the new file (through setFile) and resets
     * curSizeRollBackups.
     */
    protected void rollOverTime()
    {
        System.out.println("rollOverTime()");
        curTimeRollBackups++;

        // delete the old stuff here

        if (staticLogFileName)
        {
            /** Compute filename, but only if datePattern is specified */
            if (datePattern == null)
            {
                errorHandler.error("Missing DatePattern option in rollOver().");
                return;
            }

            // is the new file name equivalent to the 'current' one
            // something has gone wrong if we hit this -- we should only
            // roll over if the new file will be different from the old
            String dateFormat = sdf.format(now);
            if (scheduledFilename.equals(fileName + dateFormat))
            {
                errorHandler.error("Compare " + scheduledFilename + " : " + fileName + dateFormat);
                return;
            }

            // close current file, and rename it to datedFilename
            this.closeFile();

            // we may have to roll over a large number of backups here
            String from, to;
            for (int i = 1; i <= curSizeRollBackups; i++)
            {
                from = fileName + '.' + i;
                to = scheduledFilename + '.' + i;
                rollFile(from, to);
            }

            rollFile(fileName, scheduledFilename);

        }

        try
        {
            // This will also close the file. This is OK since multiple
            // close operations are safe.
            curSizeRollBackups = 0; // We're cleared out the old date and are ready for the new

            // new scheduled name
            scheduledFilename = fileName + sdf.format(now);
            this.setFile(baseFileName, false);
        }
        catch (IOException e)
        {
            errorHandler.error("setFile(" + fileName + ", false) call failed.");
        }

    }

    /***
     * Renames file <code>from</code> to file <code>to</code>. It also checks for existence of target file and deletes
     * if it does.
     */
    protected static void rollFile(String from, String to)
    {
        File target = new File(to);
        if (target.exists())
        {
            LogLog.debug("deleting existing target file: " + target);
            target.delete();
        }

        File file = new File(from);
        file.renameTo(target);
        LogLog.debug(from + " -> " + to);
    }

    /*** Delete's the specified file if it exists */
    protected static void deleteFile(String fileName)
    {
        File file = new File(fileName);
        if (file.exists())
        {
            file.delete();
        }
    }

    /***
     * Implements roll overs base on file size.
     *
     * <p>
     * If the maximum number of size based backups is reached (<code>curSizeRollBackups == maxSizeRollBackups</code)
     * then the oldest file is deleted -- it's index determined by the sign of countDirection.<br>
     * If <code>countDirection</code> < 0, then files {<code>File.1</code>, ..., <code>File.curSizeRollBackups -1</code>
     * are renamed to {<code>File.2</code>, ..., <code>File.curSizeRollBackups</code> . Moreover, <code>File</code> is
     * renamed <code>File.1</code> and closed.<br>
     *
     * A new file is created to receive further log output.
     *
     * <p>
     * If <code>maxSizeRollBackups</code> is equal to zero, then the <code>File</code> is truncated with no backup files
     * created.
     *
     * <p>
     * If <code>maxSizeRollBackups</code> < 0, then <code>File</code> is renamed if needed and no files are deleted.
     */

    // synchronization not necessary since doAppend is alreasy synched
    protected void rollOverSize()
    {
        File file;

        this.closeFile(); // keep windows happy.

        LogLog.debug("rolling over count=" + ((CountingQuietWriter)qw).getCount());
        LogLog.debug("maxSizeRollBackups = " + maxSizeRollBackups);
        LogLog.debug("curSizeRollBackups = " + curSizeRollBackups);
        LogLog.debug("countDirection = " + countDirection);

        // If maxBackups <= 0, then there is no file renaming to be done.
        if (maxSizeRollBackups != 0)
        {

            if (countDirection < 0)
            {
                // Delete the oldest file, to keep Windows happy.
                if (curSizeRollBackups == maxSizeRollBackups)
                {
                    deleteFile(fileName + '.' + maxSizeRollBackups);
                    curSizeRollBackups--;
                }

                // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2}
                for (int i = curSizeRollBackups; i >= 1; i--)
                {
                    rollFile((fileName + "." + i), (fileName + '.' + (i + 1)));
                }

                curSizeRollBackups++;
                // Rename fileName to fileName.1
                rollFile(fileName, fileName + ".1");

            } // REMOVE This code branching for Alexander Cerna's request
            else if (countDirection == 0)
            {
                // rollFile based on date pattern
                curSizeRollBackups++;
                now.setTime(System.currentTimeMillis());
                scheduledFilename = fileName + sdf.format(now);
                rollFile(fileName, scheduledFilename);
            }
            else
            { // countDirection > 0
                if (curSizeRollBackups >= maxSizeRollBackups && maxSizeRollBackups > 0)
                {
                    // delete the first and keep counting up.
                    int oldestFileIndex = curSizeRollBackups - maxSizeRollBackups + 1;
                    deleteFile(fileName + '.' + oldestFileIndex);
                }

                if (staticLogFileName)
                {
                    curSizeRollBackups++;
                    rollFile(fileName, fileName + '.' + curSizeRollBackups);
                }
            }
        }

        try
        {
            // This will also close the file. This is OK since multiple
            // close operations are safe.
            this.setFile(baseFileName, false);
        }
        catch (IOException e)
        {
            LogLog.error("setFile(" + fileName + ", false) call failed.", e);
        }
    }

    public int getMaxTimeRollBackups()
    {
        return maxTimeRollBackups;
    }

    public void setMaxTimeRollBackups(int maxTimeRollBackups)
    {
        this.maxTimeRollBackups = maxTimeRollBackups;
    }

    public static void main(String[] args)
    {

        CompositeFilenameFilter compositeFilenameFilter = new CompositeFilenameFilter(getDateString(new Date(), -1));
        File srcFolder = new File("E:/eclipse-jee-indigo-SR2-win32/logs");
        File[] files = srcFolder.listFiles(compositeFilenameFilter);

        for (File file : files)
        {
            System.out.println(file.getName());
        }
    }

    private static String getDateString(Date date, int pos)
    {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(DateUtils.addDays(date, pos));
    }

    public static int getEndStart(String source, char tarChar)
    {
        int length = source.length();

        for (int i = 0; i < length; i++)
        {
            if (source.indexOf(tarChar, length - i) > -1)
            {
                return length - i;
            }
        }
        return -1;
    }

}

 

package org.apache.log4j;

import java.io.File;
import java.io.FilenameFilter;

/**
 * 用于通过指定preix 过滤文件的 过滤器 只要文件名中包含preix字符串就算匹配成功
 *
 * @author zhangjianying
 *
 */
public class CompositeFilenameFilter implements FilenameFilter
{
    // 需要查找文件中必须包含的文字
    private String preix = "";

    public CompositeFilenameFilter(String preix)
    {
        this.preix = preix;
    }

    @Override
    public boolean accept(File dir, String name)
    {

        return name.indexOf(preix) > -1 ? true : false;
    }

}

 

OK,记得包名不能改

 

然后配置log4j.properties

log4j.appender.logfile=org.apache.log4j.CompositeRollingAppender
log4j.appender.logfile.RollingStyle=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.staticLogFileName=true
log4j.appender.logfile.File=../logs/XXXXXXXXX.log
# Keep three backup files.
log4j.appender.logfile.MaxSizeRollBackups=9999
log4j.appender.logfile.CountDirection=-1
log4j.appender.logfile.maxTimeRollBackups=7

log4j.appender.logfile.MaxFileSize=10M
log4j.appender.logfile.datePattern='.'yyyy-MM-dd

# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout.ConversionPattern=[工程名] %d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

 

最后生成的文件同一天内就会按照 10M来分文件,最多分9999个,如果超过9999就会迭代覆盖。

maxTimeRollBackups 是指超期日期是7天,会自动删除7天前的日志(当然应该是打压缩包转移,不过目前项目的SE没做这个要求)
这里我处理有点特殊:我要求应用再超期日期这段时间内没有重启过才会删除超期后的日志,如果重启过,超期时间内的日志都不会自动删除可供分析问题。

 

 

 

时间: 2024-09-16 00:10:06

log4j 按设定迭代日期删除过期日志文件,同一天内按设定大小分文件的相关文章

基于Log4j完成定时创建和删除日志的方法

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 Log4j作为常用的日志生成工具,其清除日志的策略却十分有限.只有在RollingFileAppender中可以通过设置MaxFileSize和maxBackupIndex属性来指定要保留的日志文件大小以及个数,从而实现自动清除.   但是实际生产中,我们的真实的需求常常是定时生成日志,然后保留最近几天的日志,历史日志需要及时清理.可是Log4j中的Daily

怎么样在log4j中用日期来命名日志文件

问题描述 怎么样在log4j中用日期来命名日志文件? 解决方案 解决方案二:不需要制定,直接用楼上说的appender,以前的日志自动被加上日期

关于SQL Server自动备份无法删除过期的备份文件奇怪现象

server|备份 关于SQL Server自动备份无法删除过期的备份文件 数据库服务器每天凌晨两点进行数据库备份,同时对5天前的数据库备份文件进行删除,不然的话就会把硬盘给撑爆的 windows的日志里给出信息:SQL Server Scheduled Job 'DB 维护计划"数据库维护计划1"的 DB 备份作业.' (0x2DA54A5BBEFC2B4A874428B91602C52A) - Status: 失败 - Invoked on: 2005-09-09 01:00:00

Linux下定时删除过期文件的方法

在管理Linux下的文件时,我们通常会有定时删除过期文件的这个需求.比如定时删除超过指定时间的日志文件,不然时长越久,你的日志文件占用的空间就越大,那离爆磁盘不远了,还有也解决网站方便的需求,比如我们建立的淘宝客api的程序,为了提高商品页的访问速度,我们需要进行关键数据的缓存,也需要定时删除过期的缓存文件,如果是使用PHP程序扫描删除,那将得不偿失.那么如何在Linux下定时删除过期文件?这里小编简单介绍下,方便需要的朋友. 在linux下删除过期文件,很简单,用如下命令: 复制代码代码如下:

Linux下两种删除过期文件的方法详述

一.概述 在实际的C软件开发项目中,不同的软件会在不同的目录中生成文件,由于磁盘的存储空间有限,开发人员不得不考虑对目录下的过期文件进行删除.一般说来,有两种删除过期文件的方法,一种是在C程序中实现,一种是利用crontab实现.本文对这两种方法的具体实现进行详细的介绍. 为了便于说明,本文中的过期文件的后缀为.c,存放在/home/zhou/zhouzx/Test目录下,过期时间为1天. 二.在C程序中实现过期文件删除 在该方法中,我们要考虑的主要问题为: (1)要删除过期多久的文件?文件存放

Linux下的删除过期文件操作

        在实际的软件开发项目中,经常会有实现删除过期文件的需求.即要求程序能够自动删除多长时间之前生成的文件.本文提供了一个示例代码,为相关的开发工作提供了参考.         程序如下(本程序用makefile进行编译): /*********************************************************************** 版权所有 (C)2014, Zhou Zhaoxiong.* * 文件名称: TestFileDelete.c* 内容

DELETE OBSOLETE不删除归档日志以及归档的备份集

今天遇到一个奇怪的事情,使用OBSOLETE不删除归档日志,而且也不删除过期的归档的BACKUP SET 从delete obsolete的概念来看如下: The REPORT OBSOLETE and DELETE OBSOLETE commands work in two steps:                                                                                                         

Windows 下 MySQL 简单定时自动备份、删除过期备份

问题 MySQL Workbench 客户端虽然好用,但并不提供自动备份功能.手工备份,确实繁琐. 环境 Windows Server 2012 MySQL 5.6.24 思考 MySQL 提供了 mysqldump 来进行备份.那么我们可否使用该工具,结合Windows 的定时任务功能,来实现 MySQL 定时自动备份呢? 解决 新建一个 数据库备份文件存放目录,本例为D:\db_backup.新建一个批处理文件,可以起任意名,本例为mysql_backup_tool.bat ,文件内容如下:

python删除过期文件的方法

  本文实例讲述了python删除过期文件的方法.分享给大家供大家参考.具体实现方法如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # remove all jpeg image files of an expired modification date = mtime # you could also use creation date (ctime) or last access