LOG4J实现日切或者时切

来源:互联网 发布:电脑安装软件出现乱码 编辑:程序博客网 时间:2024/04/29 16:35

LOG4J 存在一个问题,一段时间内没有打印日志,LOG4J日志归档会空缺一些日志文件。

如果有监控系统对日志文件进行监控,可能就会导致误判。

如果在程序中定时向LOG4J中打印日志或者空格(打一个空格也会存在一个换行)也可以,但是会破坏日志的完整性,监控程序可能会解析出错等。

经过研究,提供一种方法,修改LOG4J的源码,保证无日志打印,日志文件也会定时归档。

1、重写 DailyRollingFileAppende 类。


package com.pouyang.log4j;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;import java.util.TimeZone;import java.util.Timer;import java.util.TimerTask;import org.apache.log4j.FileAppender;import org.apache.log4j.Layout;import org.apache.log4j.helpers.LogLog;import org.apache.log4j.spi.LoggingEvent;public class UmpDailyRollingFileAppender extends FileAppender{  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;  private String datePattern = "'.'yyyy-MM-dd";  private String scheduledFilename;  private long nextCheck = System.currentTimeMillis() - 1L;    private String categoryName = "MPSP";  Date now = new Date();  SimpleDateFormat sdf;  RollingCalendar rc = new RollingCalendar();  Timer timer;  org.slf4j.Logger _log ;    int checkPeriod = -1;  static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");  public UmpDailyRollingFileAppender()  {  System.out.println("UmpDailyRollingFileAppender()"+this);  }  public UmpDailyRollingFileAppender(Layout layout, String filename, String datePattern)    throws IOException  {    super(layout, filename, true);    this.datePattern = datePattern;    activateOptions();    System.out.println("UmpDailyRollingFileAppender()"+this);  }  public void setDatePattern(String pattern)  {    this.datePattern = pattern;  }  public String getDatePattern()  {    return this.datePattern;  }  public void activateOptions() {    super.activateOptions();    if ((this.datePattern != null) && (this.fileName != null)) {      this.now.setTime(System.currentTimeMillis());      this.sdf = new SimpleDateFormat(this.datePattern);      int type = computeCheckPeriod();      printPeriodicity(type);      this.rc.setType(type);      File file = new File(this.fileName);      this.scheduledFilename =         (this.fileName +         this.sdf.format(new Date(file.lastModified())));      this.timer = new Timer();      Date next = this.rc.getNextCheckDate(this.now);      long perid = this.rc.getNextCheckMillis(next) - next.getTime();            Debug.log("timer.schedule(next,perid): "+next +","+perid+"ms");      _log = org.slf4j.LoggerFactory.getLogger(categoryName);      this.timer.schedule(new RolloverFileTask(), next, perid);    }    else {      LogLog.error("Either File or DatePattern options are not set for appender [" +         this.name + "].");    }  }  void printPeriodicity(int type) {    switch (type) {    case 0:      LogLog.debug("Appender [" + this.name + "] to be rolled every minute.");      break;    case 1:      LogLog.debug("Appender [" + this.name +         "] to be rolled on top of every hour.");      break;    case 2:      LogLog.debug("Appender [" + this.name +         "] to be rolled at midday and midnight.");      break;    case 3:      LogLog.debug("Appender [" + this.name + "] to be rolled at midnight.");      break;    case 4:      LogLog.debug("Appender [" + this.name +         "] to be rolled at start of week.");      break;    case 5:      LogLog.debug("Appender [" + this.name +         "] to be rolled at start of every month.");      break;    default:      LogLog.warn("Unknown periodicity for appender [" + this.name + "].");    }  }  int computeCheckPeriod()  {    RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone,       Locale.getDefault());    Date epoch = new Date(0L);    if (this.datePattern != null) {      for (int i = 0; i <= 5; i++) {        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(          this.datePattern);        simpleDateFormat.setTimeZone(gmtTimeZone);        String r0 = simpleDateFormat.format(epoch);        rollingCalendar.setType(i);        Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));        String r1 = simpleDateFormat.format(next);        if ((r0 != null) && (r1 != null) && (!r0.equals(r1))) {          return i;        }      }    }    return -1;  }  /**   * old log LOGARCHIVE   * log4j  locked http://blog.163.com/qiongling007@126/blog/static/214242962011102344916998/   * log4j  time gen log file: http://www.iteye.com/topic/1006379   * @throws IOException   */  void rollOver()    throws IOException  {    if (this.datePattern == null) {      this.errorHandler.error("Missing DatePattern option in rollOver().");      return;    }    String datedFilename = this.fileName + this.sdf.format(this.now);        //Debug.log("rollOver()  datedFilename: "+datedFilename);    //Debug.log("rollOver()  scheduledFilename: "+scheduledFilename);    if (this.scheduledFilename.equals(datedFilename)) {      return;    }    closeFile();    File target = new File(this.scheduledFilename);    if (target.exists()) {      System.out.println("scheduledFilename- exists- ");      target.delete();    }    File file = new File(this.fileName);    boolean result = file.renameTo(target);    if (result)      LogLog.debug(this.fileName + " -> " + this.scheduledFilename);    else {      LogLog.error("Failed to rename [" + this.fileName + "] to [" +         this.scheduledFilename + "].");    }    try    {      //setFile(this.fileName, true, this.bufferedIO, this.bufferSize);      setFile(this.fileName, false, this.bufferedIO, this.bufferSize);    } catch (IOException e) {      this.errorHandler.error("setFile(" + this.fileName + ", false) call failed.");    }    this.scheduledFilename = datedFilename;  }  protected void subAppend(LoggingEvent event)  {    long n = System.currentTimeMillis();    if (n >= this.nextCheck) {      this.now.setTime(n);      this.nextCheck = this.rc.getNextCheckMillis(this.now);      try {        rollOver();      } catch (IOException ioe) {//        if ((ioe instanceof InterruptedIOException)) {//          Thread.currentThread().interrupt();//        }        LogLog.error("rollOver() failed.", ioe);      }    }    super.subAppend(event);          }          class RolloverFileTask extends TimerTask {      RolloverFileTask() {        }    public void run() {    /**     * 通过定时打印日志,触发 subAppend(LoggingEvent event) 方法,进行日切日志文件归档。     * mod by oyp 2014-12-04 18:22:30     * @@@Time log cutting@@@     */    try {     //Debug.log("-"+categoryName+"@@@-LOGARCHIVE-@@@ timing output log to generate a log file");    /**     * log in system.log ,not in mpsp.log, because not the same layout     */    _log.info(Debug.LOGARCHIVE+" timing output log to generate a log file");    } catch (Exception e) {    e.printStackTrace();    }//    System.out.println(System.currentTimeMillis()+"---------------------run---------------------");//      long n = System.currentTimeMillis();//      if (n >= UmpDailyRollingFileAppender.this.nextCheck) {//        UmpDailyRollingFileAppender.this.now.setTime(n);//        UmpDailyRollingFileAppender.this.nextCheck = UmpDailyRollingFileAppender.this.rc.getNextCheckMillis(UmpDailyRollingFileAppender.this.now);//        try {//          UmpDailyRollingFileAppender.this.rollOver();//        } catch (IOException ioe) {//          if ((ioe instanceof InterruptedIOException)) {//            Thread.currentThread().interrupt();//          }//          LogLog.error("rollOver() failed.", ioe);//          System.out.println(ioe);//        }//      }    }  }public String getCategoryName() {return categoryName;}public void setCategoryName(String categoryName) {this.categoryName = categoryName;}}


2、重写 PatternLayout。

package com.pouyang.log4j;/**  * @author ouyangping * @date Dec 4, 2014 */import org.apache.log4j.Layout;import org.apache.log4j.helpers.PatternConverter;import org.apache.log4j.helpers.PatternParser;import org.apache.log4j.spi.LoggingEvent;public class UmpPatternLayout extends Layout{  public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";  public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %x - %m%n";  protected final int BUF_SIZE = 256;  protected final int MAX_CAPACITY = 1024;  private StringBuffer sbuf = new StringBuffer(256);  private String pattern;  private PatternConverter head;  private String timezone;  public UmpPatternLayout()  {    this("%m%n");  }  public UmpPatternLayout(String pattern)  {    this.pattern = pattern;    this.head = createPatternParser(pattern == null ? "%m%n" : pattern).parse();  }  public void setConversionPattern(String conversionPattern)  {    this.pattern = conversionPattern;    this.head = createPatternParser(conversionPattern).parse();  }  public String getConversionPattern()  {    return this.pattern;  }  public void activateOptions()  {  }  public boolean ignoresThrowable()  {    return true;  }  protected PatternParser createPatternParser(String pattern)  {    return new PatternParser(pattern);  }  public String format(LoggingEvent event)  {    if (this.sbuf.capacity() > 1024)      this.sbuf = new StringBuffer(256);    else {      this.sbuf.setLength(0);    }    PatternConverter c = this.head;        while (c != null) {      c.format(this.sbuf, event);      c = c.next;    }    //System.out.println("layout2:"+this.sbuf.toString());    //System.out.println("layout2:"+ MyUtil.bcd(this.sbuf.toString().getBytes()));    /**     * 过滤掉定时任务执行生成对账文件的日志,只打一个空串且不包含换行操作     * add by oyp 2014-12-04 18:22:44     *///    String mesg = this.sbuf.toString();//    Debug.log(mesg);//    String[] temp = mesg.split("-");//    if ( temp.length >= 2 && ( temp[1] == null || "".equals(temp[1].trim())) ) {//    return "";//    } else {//    return mesg;//    }        String mesg = this.sbuf.toString();    if (mesg.contains(Debug.LOGARCHIVE)) {    //Debug.log(mesg);    return "";    } else {    return mesg;    }    //return this.sbuf.toString();  }}







0 0
原创粉丝点击