DailyRollingFileAppender-设置文件大小和备份天数

感谢:http://byx5185.iteye.com/blog/1616034

1、重写FileAppender :

package com.bankht.cis.tps.apps.tps.util;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TreeMap;

/** 
 * 名称: TraceLogFileAppender.java<br>
 * 描述: 该appender是仿照log4j中RollingFileAppender写的
 * 可配置备份天数,包含当天
 * filesize为字节数<br>
 * 批次:name<br> 
 * 创建时间: 2018年7月23日<br>
 * 修改时间:<br> 
 * 编写人员:xxx <br>
 * 版本号:1.0 
 */

public class CustomTraceLogFileAppender extends FileAppender {
    
    protected long maxFileSize = 10485760L;//file.length,字节数
    protected int maxDaysIndex = 1;//备份天数,包含当天

    private long nextRollover = 0;  
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    private static String separator = ".";

    public CustomTraceLogFileAppender() {}
    
    public CustomTraceLogFileAppender(Layout layout, String filename, boolean append)
    throws IOException
    {
        super(layout, filename, append);
    }
    
    public CustomTraceLogFileAppender(Layout layout, String filename)
    throws IOException
    {
        super(layout, filename);
    }
    public int getMaxDaysIndex(){return maxDaysIndex;}

    public long getMaximumFileSize()
    {
        return maxFileSize;
    }

    public void setMaxDaysIndex(int maxDays)
    {
        maxDaysIndex = maxDays;
    }

    public void setMaximumFileSize(long maxFileSize)
    {
        this.maxFileSize = maxFileSize;
    }

    public void setMaxFileSize(String value)
    {
        maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1L);
    }

    protected void setQWForFiles(Writer writer)
    {
        qw = new CustomCountingQuietWriter(writer, errorHandler,this.encoding);
    }

    //启动时专用
    public synchronized void setFile(String fileName, boolean append,  
            boolean bufferedIO, int bufferSize) throws IOException {
        String temp = getStartupFileName(fileName);
        super.setFile(temp, append, this.bufferedIO, this.bufferSize);  
        if (append) {
            File f = new File(temp);
            ((CustomCountingQuietWriter)qw).setCount(f.length());
        }
        //每次启动时,检验是否超出备份数量,超出则删除最旧日期
        countFile(temp,maxDaysIndex);
    }

    private String getStartupFileName(String name) {
        String filePath = name.substring(0,name.lastIndexOf("/")+1);
        String[] strs = name.split("\.");
        File[] files = new File(filePath).listFiles(new CustomLogStartupFileFilter(strs[1]));

        //treemap默认是升序,取最后一个即为最新文件.
        TreeMap<Long, String> treeMap = new TreeMap<Long, String>();
        if(files==null || files.length == 0){
            if(strs.length==3){
                StringBuffer sb = new StringBuffer();
                String now = sdf.format(new Date());
                return sb.append(strs[0]).append(separator)
                .append(strs[1]).append(separator)
                .append(now).append(separator)
                .append("1").append(separator).append("log").toString();
            }
            return name;
        }else{
            for(File temp : files){
                treeMap.put(temp.lastModified(),temp.getPath());
            }
            name = treeMap.lastEntry().getValue();
            String now = sdf.format(new Date());
            String[] strs1 = name.split("\.");
            if(strs1.length == 5){//符合日志文件名格式
                StringBuffer sb = new StringBuffer();
                if(now.equals(strs1[2])){
                    return sb.append(strs[0]).append(separator)
                    .append(strs1[1]).append(separator)
                    .append(strs1[2]).append(separator)
                    .append(strs1[3]).append(separator).append("log").toString();
                }else{
                    return sb.append(strs[0]).append(separator)
                    .append(strs1[1]).append(separator)
                    .append(now).append(separator)
                    .append("1").append(separator).append("log").toString();
                }
            }
        }
        return name;
    }

    public synchronized void setCustomFile(String fileName, boolean append,
            boolean bufferedIO, int bufferSize) throws IOException {
        super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
        if (append) {
            File f = new File(fileName);
            ((CustomCountingQuietWriter)qw).setCount(f.length());
        }
    }

    protected void subAppend(LoggingEvent event) {
        String nowDate = sdf.format(new Date());
        String[] strs = fileName.split("\.");
        String fileDate  = strs[2];
        if(!nowDate.equals(fileDate)){
            try {
                //新建文件,当切换日期时,文件名中的序号都是从1开始
                String newFileName = getFileName(fileName,1);
                this.setCustomFile(newFileName, true, bufferedIO, bufferSize);
                //计算备份天数,多出删掉
                countFile(newFileName,maxDaysIndex);
            } catch (IOException e) {
                if (e instanceof InterruptedIOException) {
                    Thread.currentThread().interrupt();
                }
            }
        }
        super.subAppend(event);//先写入数据
        if ((fileName != null) && (qw != null)) {
            long size = ((CustomCountingQuietWriter)qw).getCount();
            if ((size >= maxFileSize) && (size >= nextRollover)) {
                this.closeFile();
                fileName = getFileName(fileName,1);
                try {
                    this.setCustomFile(fileName, true, bufferedIO, bufferSize);
                    nextRollover = 0;
                } catch (IOException e) {
                    if (e instanceof InterruptedIOException) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }
    }

    /**
     * 系统名称.实例名称.日期.文件编号.log
     * @param name
     * @param i
     * @return
     */
    private static String getFileName(String name,int i) {
        String date = sdf.format(new Date());
        String filePath = name.substring(0, name.lastIndexOf("/")+1);
        String currentName = name.substring(name.lastIndexOf("/")+1);
        String[] str = currentName.split("\.");
        if(str.length>=3){//启动时,文件名:系统名.实例名.log,长度为3
            String fileName = "";
            fileName = str[0]+separator+str[1]+separator+date+separator;
            int nums = 0;
            if(str.length==5){
                String num = str[3];
                String fileDate = str[2];
                if(!"".equals(num) && num != null && date.equals(fileDate)){
                    nums = Integer.parseInt(num);
                }
            }
            nums= nums + i;

            fileName = filePath + fileName + nums + ".log";
            name = fileName;
        }
        return name;
    }
    /**
     * 获取几天前的日期,格式yyyyMMdd
     * @param days 天数
     * @return
     */
    public static String getBeforeDate(int days){
        Calendar cal = Calendar.getInstance();
        cal.add(cal.DATE, -days);
        Date resultDate = cal.getTime();
        return sdf.format(resultDate);
    }

    /**
     *
     * @param fileName 文件名称(包括路径)
     * @param MaxDaysIndex 计算日志文件个数,当达到最大保留数时,将最早生成的日志文件删除
     */
    public static void countFile(String fileName,int MaxDaysIndex){
        String delDate = getBeforeDate(MaxDaysIndex);
        String filePath = fileName.substring(0, fileName.lastIndexOf("/"));
        File file = new File(filePath);
        if(file.isDirectory()){
            File[] files = file.listFiles(new CustomLogFileFilter(delDate));
            if(files != null && files.length>0){
                for(File temp:files){
                    temp.delete();
                }
            }
        }
    }

}

/**
 * 文件过滤器
 * 删除文件时专用
 */
class CustomLogFileFilter implements FileFilter {
    private String delDate;


    public CustomLogFileFilter(String delDate) {
        this.delDate = delDate;
    }


    /**
     *
     * @param file 路径+文件名
     * @return
     */
    @Override
    public boolean accept(File file) {
        if (delDate == null || file.isDirectory()) {
            return false;
        } else {
            String[] strs = file.getName().split("\.");
            if(strs!=null && strs.length>=3){
                if(strs[2].compareTo(delDate)<=0){//删除备份天数之前的文件
                    return true;
                }
            }
            return false;
        }
    }
}
class CustomLogStartupFileFilter implements FileFilter {
    private String serverName;


    public CustomLogStartupFileFilter(String serverName) {
        this.serverName = serverName;
    }


    /**
     *
     * @param file 路径+文件名
     * @return
     */
    @Override
    public boolean accept(File file) {
        //过滤文件夹中符合系统名称.实例名称.日期.文件编号.log格式的文件,实例名与当前实例名一致.
        if(file.getName().split("\.").length == 5 && serverName.equals(file.getName().split("\.")[1])){
            return true;
        }
        return false;
    }
}

2、

package com.bankht.cis.tps.apps.tps.util;

import org.apache.log4j.helpers.QuietWriter;
import org.apache.log4j.spi.ErrorHandler;

import java.io.IOException;
import java.io.Writer;

/**
 * 重写CustomCountingQuietWriter
 * 计算长度时,设置字符级
 * Created by xxx on 2018/7/24.
 */
public class CustomCountingQuietWriter extends QuietWriter {
    protected long count;
    protected String encoding;


    public CustomCountingQuietWriter(Writer writer, ErrorHandler eh, String encoding) {
        super(writer, eh);
        this.encoding = encoding;
    }

    public void write(String string) {
        try {
            this.out.write(string);
            this.count += (long)string.getBytes(this.encoding).length;
        } catch (IOException var3) {
            this.errorHandler.error("Write failure.", var3, 1);
        }

    }

    public long getCount() {
        return this.count;
    }

    public void setCount(long count) {
        this.count = count;
    }
}

2、 log4j.properties文件中配置

其中CustomTraceLogFileAppender为重写的FileAppender。
MaxFileSize 文件大小
MaxDaysIndex 备份天数
# Set root logger level to DEBUG and its only appender to CONSOLE.
log4j.rootLogger=INFO,log

#CONSOLE
#log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
#log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
#log4j.appender.CONSOLE.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%t] %-5p %C{1} : %m%n

#route trace log
log4j.appender.log=org.apache.log4j.RollingFileAppender
log4j.appender.log.File=/route/route-trace-${log.name}.log
log4j.appender.log.MaxFileSize=200000KB
log4j.appender.log.MaxBackupIndex=200
log4j.appender.log.layout=org.apache.log4j.PatternLayout
log4j.appender.log.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS}[%t][%c][%p]-%m%n

#SQL
log4j.logger.java.sql.Connection=INFO
log4j.logger.java.sql.Statement=INFO
log4j.logger.java.sql.PreparedStatement=INFO 
log4j.logger.java.sql.ResultSet=INFO

#trace log
log4j.logger.traceLog=INFO,traceLog
log4j.additivity.traceLog=false
log4j.appender.traceLog=com.bankht.cis.tps.apps.tps.util.CustomTraceLogFileAppender
log4j.appender.traceLog.Append=true
log4j.appender.traceLog.MaxFileSize=20480KB
log4j.appender.traceLog.MaxDaysIndex=7
log4j.appender.traceLog.encoding=UTF-8
log4j.appender.traceLog.File=/route/tracelog/GCSC-D.${log.name}.log
log4j.appender.traceLog.layout=org.apache.log4j.PatternLayout
log4j.appender.traceLog.layout.ConversionPattern=%m%n
原文地址:https://www.cnblogs.com/amunamuna/p/8664072.html