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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM