自定义log4j生成的log文件名

来源:互联网 发布:php基础教程 第5版 pdf 编辑:程序博客网 时间:2024/06/05 00:16



很多时候,log4j的RollingFileAppender配置如下: 

log4j.logger.cn.lettoo.Test=INFO, filelog4j.appender.file=org.apache.log4j.RollingFileAppenderlog4j.appender.file.MaxFileSize=100KBlog4j.appender.file.MaxBackupIndex=10log4j.appender.file.File=test.loglog4j.appender.file.layout=org.apache.log4j.PatternLayout  log4j.appender.file.layout.ConversionPattern=[%d{MM/dd/yyyy HH:mm:ss.SSS} %m%n

RollingFileAppender会自动在一个文件满了之后,生成一个如text.log.1的文件,一直生成到text.log.x(x值可配置log4j.appender.file.MaxBackupIndex=10)为止,再回写text.log。 

    当我们有需要在产生一些自定义的log文件名的时候,比如: 

引用

test_[process_name]_0_20111031.log 
test_[process_name]_1_20111031.log 
test_[process_name]_2_20111031.log 
...... 

    要在文件名显示是哪一个进程名,第一个文件为0,后面是1,2,3......,并且要加上日期,再使用RollingFileAppender做简单的配置是无论如何也实现不了了。 

    打开RollingFileAppender.java的源码,我看到它主要是用setFile(),subAppend()和rollOver()这几个方法来实现具体的功能的:


  public // synchronization not necessary since doAppend is alreasy synched  void rollOver() {    File target;    File file;    if (qw != null) {        long size = ((CountingQuietWriter) qw).getCount();        LogLog.debug("rolling over count=" + size);        //   if operation fails, do not roll again until        //      maxFileSize more bytes are written        nextRollover = size + maxFileSize;    }    LogLog.debug("maxBackupIndex="+maxBackupIndex);    boolean renameSucceeded = true;    // If maxBackups <= 0, then there is no file renaming to be done.    if(maxBackupIndex > 0) {      // Delete the oldest file, to keep Windows happy.      file = new File(fileName + '.' + maxBackupIndex);      if (file.exists())       renameSucceeded = file.delete();      // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2}      for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) {file = new File(fileName + "." + i);if (file.exists()) {  target = new File(fileName + '.' + (i + 1));  LogLog.debug("Renaming file " + file + " to " + target);  renameSucceeded = file.renameTo(target);}      }    if(renameSucceeded) {      // Rename fileName to fileName.1      target = new File(fileName + "." + 1);      this.closeFile(); // keep windows happy.      file = new File(fileName);      LogLog.debug("Renaming file " + file + " to " + target);      renameSucceeded = file.renameTo(target);      //      //   if file rename failed, reopen file with append = true      //      if (!renameSucceeded) {          try {            this.setFile(fileName, true, bufferedIO, bufferSize);          }          catch(IOException e) {              if (e instanceof InterruptedIOException) {                  Thread.currentThread().interrupt();              }              LogLog.error("setFile("+fileName+", true) call failed.", e);          }      }    }    }    //    //   if all renames were successful, then    //    if (renameSucceeded) {    try {      // This will also close the file. This is OK since multiple      // close operations are safe.      this.setFile(fileName, false, bufferedIO, bufferSize);      nextRollover = 0;    }    catch(IOException e) {        if (e instanceof InterruptedIOException) {            Thread.currentThread().interrupt();        }        LogLog.error("setFile("+fileName+", false) call failed.", e);    }    }  }  public  synchronized  void setFile(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);      ((CountingQuietWriter) qw).setCount(f.length());    }  }  /**     This method differentiates RollingFileAppender from its super     class.     @since 0.9.0  */  protected  void subAppend(LoggingEvent event) {    super.subAppend(event);    if(fileName != null && qw != null) {        long size = ((CountingQuietWriter) qw).getCount();        if (size >= maxFileSize && size >= nextRollover) {            rollOver();        }    }   }

如果我继承这个类,然后在子类里实现它的这三个方法,不就可以实现我要的功能了吗? 
代码如下: 

public class MWLogFileAppender extends RollingFileAppender {    private long nextRollover = 0;    public void rollOver() {        File target;        File file;        if (qw != null) {            long size = ((CountingQuietWriter) qw).getCount();            LogLog.debug("rolling over count=" + size);            // if operation fails, do not roll again until            // maxFileSize more bytes are written            nextRollover = size + maxFileSize;        }        LogLog.debug("maxBackupIndex=" + maxBackupIndex);        boolean renameSucceeded = true;        // If maxBackups <= 0, then there is no file renaming to be done.        if (maxBackupIndex > 0) {            // Delete the oldest file, to keep Windows happy.            //file = new File(fileName + '.' + maxBackupIndex);            file = new File(getRollingFileName(fileName, maxBackupIndex));            if (file.exists())                renameSucceeded = file.delete();            // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3,            // 2}            for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) {                //file = new File(fileName + "." + i);                file = new File(getRollingFileName(fileName, i));                if (file.exists()) {                    //target = new File(fileName + '.' + (i + 1));                    target = new File(getRollingFileName(fileName, i+1));                    LogLog.debug("Renaming file " + file + " to " + target);                    renameSucceeded = file.renameTo(target);                }            }            if (renameSucceeded) {                // Rename fileName to fileName.1                //target = new File(fileName + "." + 1);                target = new File(this.getRollingFileName(fileName, 1));                this.closeFile(); // keep windows happy.                file = new File(fileName);                LogLog.debug("Renaming file " + file + " to " + target);                renameSucceeded = file.renameTo(target);                //                // if file rename failed, reopen file with append = true                //                if (!renameSucceeded) {                    try {                        this.setFile(fileName, true, bufferedIO, bufferSize);                    } catch (IOException e) {                        if (e instanceof InterruptedIOException) {                            Thread.currentThread().interrupt();                        }                        LogLog.error("setFile(" + fileName                                + ", true) call failed.", e);                    }                }            }        }        //        // if all renames were successful, then        //        if (renameSucceeded) {            try {                // This will also close the file. This is OK since multiple                // close operations are safe.                this.setFile(fileName, false, bufferedIO, bufferSize);                nextRollover = 0;            } catch (IOException e) {                if (e instanceof InterruptedIOException) {                    Thread.currentThread().interrupt();                }                LogLog.error("setFile(" + fileName + ", false) call failed.", e);            }        }    }    private String getRollingFileName(String fileName, int index) {        Pattern p = Pattern.compile("_\\d+\\.");         Matcher m=p.matcher(fileName);                return m.replaceFirst(String.format("_%d.", index));    }    public synchronized void setFile(String fileName, boolean append,            boolean bufferedIO, int bufferSize) throws IOException {        String processName = "01";        SimpleDateFormat format = new SimpleDateFormat("MMddyyyy");        String dateString = format.format(new Date(System.currentTimeMillis()));        String processId = String.valueOf(Thread.currentThread().getId());        String temp = String.format(fileName, processName, dateString,                processId);        //System.out.println(temp);        super.setFile(temp, append, bufferedIO, bufferSize);    }    protected void subAppend(LoggingEvent event) {        super.subAppend(event);        if (fileName != null && qw != null) {            long size = ((CountingQuietWriter) qw).getCount();            if (size >= maxFileSize && size >= nextRollover) {                rollOver();            }        }    }}

在setFile方法里,通过String的替换来实现我要的自定义字符串的功能,当然,这里只是一个示例。 
    文件满了之后生成新的文件编号,不再在log后面加数据,而是在文件名体现,我这里加了一个getRollingFileName()来根据正则表达式来替换。 

    当然,配置文件可以修改如下了: 

log4j.logger.cn.lettoo.Test=INFO, filelog4j.appender.file=org.apache.log4j.RollingFileAppenderlog4j.appender.file.MaxFileSize=100KBlog4j.appender.file.MaxBackupIndex=10log4j.appender.file.File=test-%s_%s_0.%s.loglog4j.appender.file.layout=org.apache.log4j.PatternLayout  log4j.appender.file.layout.ConversionPattern=[%d{MM/dd/yyyy HH:mm:ss.SSS} %m%n

虽然以上的做法满足了我的要求,但是我感觉也有缺点,主要是: 

  • 配置文件必须要按我自定义的格式来写,即log4j.appender.file.File=test-%s_%s_0.%s.log不能搞错了
  • RollingFileAppender的几个方法扩展的都不好,还把原来的代码copy过来修改的。


转载地址:http://lettoo.iteye.com/blog/1226671

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝买的衣服味道很大怎么办 三国杀账号忘了怎么办 宽带连接被删了 怎么办 手机被偷了qq怎么办 手机丢了微信怎么办啊 手机店把手机修坏了怎么办 在手机店买到山寨机手机怎么办 有人在qq群上骂我怎么办 qq群一直有人骚扰怎么办 苹果手机QQ图标不在桌面上怎么办 苹果手机长按不能删除怎么办 qq发的图片过期怎么办 九黎八卦在仓库怎么办 飞猪f2领了万豪银卡没住怎么办 机械键盘摁键冲突怎么办 玩游戏键盘没反应怎么办 玩枪战游戏头晕恶心怎么办 手机看视频不能横屏怎么办 苹果手机安全码忘记了怎么办 信用卡安全码忘记了怎么办 联想电脑管家阻止我安装软件怎么办 word恢复后打开乱码怎么办 苹果手机局域网也登陆不了怎么办 剑三账号冻结7天怎么办 荒野行动无缘无故被限制时间怎么办 电脑打游戏闪屏怎么办 微信下载出现数据包出错怎么办 安卓平板闪退怎么办 剑侠世界2出了1怎么办 苹果手机有木马病毒删除不了怎么办 苹果手机病毒了怎么办【解决方法】 苹果手机点击病毒链接怎么办 苹果手机有病毒啦怎么办 苹果7p反复重启怎么办 苹果手机屏幕触屏不灵怎么办 苹果手机屏翘起来了怎么办 苹果x手机触屏失灵怎么办 苹果7手机变成黑白屏怎么办 苹果手机屏不动了怎么办 苹果6老是卡屏怎么办 苹果x卡屏死机怎么办