zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    SOAP协议调研
    android 支付宝 沙箱环境配置
    点击两次物理键退出APP
    Android LitePal的简单使用
    多线程
    【Android】15.0 UI开发(六)——列表控件RecyclerView的网格布局排列实现
    【Android】14.0 UI开发(五)——列表控件RecyclerView的瀑布布局排列实现
    【Android】利用回收机制创建ListView列表实现
    BaseActivity
    【MySQL数据库】一些bug的解决
  • 原文地址:https://www.cnblogs.com/amunamuna/p/8664072.html
Copyright © 2011-2022 走看看