Log4J-重写方法,实现按照日期大小进行分割文件

1.Log4J配置

[html] view plain copy
  1. log4j.rootLogger =debug,stdout,FILE  
  2.   
  3. log4j.category.org.springframework=ERROR  
  4. log4j.category.org.apache=ERROR  
  5. log4j.appender.FILE=com.xxx.xxx.util.MyDailyRollingFileAppender  
  6. #org.apache.log4j.RollingFileAppender  
  7. log4j.appender.FILE.File=./logs/config.log  
  8. log4j.appender.FILE.DatePattern='.'yyyy-MM-dd'.log'  
  9. log4j.appender.FILE.MaxFileSize=100MB  
  10. log4j.appender.FILE.MaxBackupIndex=-1  
  11. log4j.appender.FILE.ImmediateFlush=true  
  12. log4j.appender.FILE.Threshold=debug  
  13. log4j.appender.FILE.Append=true  
  14. log4j.appender.FILE.layout=org.apache.log4j.PatternLayout  
  15. log4j.appender.FILE.layout.conversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n  
  16.   
  17. log4j.logger.org.quartz=INFO  
  18.   
  19. log4j.appender.stdout = org.apache.log4j.ConsoleAppender  
  20. log4j.appender.stdout.Target = System.out  
  21. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout  
  22. log4j.appender.stdout.layout.ConversionPattern = [%p][%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n  
  23. #%l%n  
  24.   
  25.   
  26.   
  27. log4j.logger.com.ibatis=debug  
  28. log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug  
  29. log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug  
  30. log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug  
  31. log4j.logger.druid.sql.DataSource=debug  
  32. log4j.logger.java.sql.Connection=debug  
  33. log4j.logger.java.sql.Statement=debug  
  34. log4j.logger.java.sql.PreparedStatement=debug,stdout  
2.重写类MyDailyRollingFileAppender.java
[java] view plain copy
  1. package com.hytera.eems.util;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.Writer;  
  6. import java.text.SimpleDateFormat;  
  7. import java.util.Calendar;  
  8. import java.util.Date;  
  9. import java.util.GregorianCalendar;  
  10. import java.util.Locale;  
  11. import java.util.TimeZone;  
  12.   
  13. import org.apache.log4j.FileAppender;  
  14. import org.apache.log4j.Layout;  
  15. import org.apache.log4j.helpers.CountingQuietWriter;  
  16. import org.apache.log4j.helpers.LogLog;  
  17. import org.apache.log4j.helpers.OptionConverter;  
  18. import org.apache.log4j.spi.LoggingEvent;    
  19.   
  20. public class MyDailyRollingFileAppender extends FileAppender {  
  21.     // The code assumes that the following constants are in a increasing    
  22.     // sequence.    
  23.     static final int TOP_OF_TROUBLE = -1;    
  24.     static final int TOP_OF_MINUTE = 0;    
  25.     static final int TOP_OF_HOUR = 1;    
  26.     static final int HALF_DAY = 2;    
  27.     static final int TOP_OF_DAY = 3;    
  28.     static final int TOP_OF_WEEK = 4;    
  29.     static final int TOP_OF_MONTH = 5;    
  30.     
  31.     /**  
  32.      * The default maximum file size is 10MB.  
  33.      */    
  34.     protected long maxFileSize = 10 * 1024 * 1024;    
  35.     
  36.     /**  
  37.      * There is one backup file by default.  
  38.      */    
  39.     protected int maxBackupIndex = 1;    
  40.     
  41.     /**  
  42.      * The date pattern. By default, the pattern is set to "'.'yyyy-MM-dd"  
  43.      * meaning daily rollover.  
  44.      */    
  45.     private String datePattern = "'.'yyyy-MM-dd";    
  46.     
  47.     /**  
  48.      * The log file will be renamed to the value of the scheduledFilename  
  49.      * variable when the next interval is entered. For example, if the rollover  
  50.      * period is one hour, the log file will be renamed to the value of  
  51.      * "scheduledFilename" at the beginning of the next hour.  
  52.      *   
  53.      * The precise time when a rollover occurs depends on logging activity.  
  54.      */    
  55.     private String scheduledFilename;    
  56.     
  57.     /**  
  58.      * The next time we estimate a rollover should occur.  
  59.      */    
  60.     private long nextCheck = System.currentTimeMillis() - 1;    
  61.     
  62.     Date now = new Date();    
  63.     
  64.     SimpleDateFormat sdf;    
  65.     
  66.     RollingCalendar rc = new RollingCalendar();    
  67.     
  68.     int checkPeriod = TOP_OF_TROUBLE;    
  69.     
  70.     // The gmtTimeZone is used only in computeCheckPeriod() method.    
  71.     static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");    
  72.     
  73.     /**  
  74.      * The default constructor does nothing.  
  75.      */    
  76.     public MyDailyRollingFileAppender() {    
  77.     }    
  78.     
  79.     /**  
  80.      * Instantiate a <code>MyDailyRollingFileAppender</code> and open the file  
  81.      * designated by <code>filename</code>. The opened filename will become the  
  82.      * ouput destination for this appender.  
  83.      */    
  84.     public MyDailyRollingFileAppender(Layout layout, String filename,    
  85.             String datePattern) throws IOException {    
  86.         super(layout, filename, true);    
  87.         this.datePattern = datePattern;    
  88.         activateOptions();    
  89.     }    
  90.     
  91.     /**  
  92.      * Get the maximum size that the output file is allowed to reach before  
  93.      * being rolled over to backup files.  
  94.      *   
  95.      * @since 1.1  
  96.      */    
  97.     public long getMaximumFileSize() {    
  98.         return maxFileSize;    
  99.     }    
  100.     
  101.     /**  
  102.      * Set the maximum size that the output file is allowed to reach before  
  103.      * being rolled over to backup files.  
  104.      *   
  105.      * <p>  
  106.      * This method is equivalent to {@link #setMaxFileSize} except that it is  
  107.      * required for differentiating the setter taking a <code>long</code>  
  108.      * argument from the setter taking a <code>String</code> argument by the  
  109.      * JavaBeans {@link java.beans.Introspector Introspector}.  
  110.      *   
  111.      * @see #setMaxFileSize(String)  
  112.      */    
  113.     public void setMaximumFileSize(long maxFileSize) {    
  114.         this.maxFileSize = maxFileSize;    
  115.     }    
  116.     
  117.     /**  
  118.      * Set the maximum size that the output file is allowed to reach before  
  119.      * being rolled over to backup files.  
  120.      *   
  121.      * <p>  
  122.      * In configuration files, the <b>MaxFileSize</b> option takes an long  
  123.      * integer in the range 0 - 2^63. You can specify the value with the  
  124.      * suffixes "KB", "MB" or "GB" so that the integer is interpreted being  
  125.      * expressed respectively in kilobytes, megabytes or gigabytes. For example,  
  126.      * the value "10KB" will be interpreted as 10240.  
  127.      */    
  128.     public void setMaxFileSize(String value) {    
  129.         maxFileSize = OptionConverter.toFileSize(value, maxFileSize + 1);    
  130.     }    
  131.     
  132.     /**  
  133.      * Returns the value of the <b>MaxBackupIndex</b> option.  
  134.      */    
  135.     public int getMaxBackupIndex() {    
  136.         return maxBackupIndex;    
  137.     }    
  138.     
  139.     /**  
  140.      * Set the maximum number of backup files to keep around.  
  141.      *   
  142.      * <p>  
  143.      * The <b>MaxBackupIndex</b> option determines how many backup files are  
  144.      * kept before the oldest is erased. This option takes a positive integer  
  145.      * value. If set to zero, then there will be no backup files and the log  
  146.      * file will be truncated when it reaches <code>MaxFileSize</code>.  
  147.      */    
  148.     public void setMaxBackupIndex(int maxBackups) {    
  149.         this.maxBackupIndex = maxBackups;    
  150.     }    
  151.     
  152.     /**  
  153.      * The <b>DatePattern</b> takes a string in the same format as expected by  
  154.      * {@link SimpleDateFormat}. This options determines the rollover schedule.  
  155.      */    
  156.     public void setDatePattern(String pattern) {    
  157.         datePattern = pattern;    
  158.     }    
  159.     
  160.     /** Returns the value of the <b>DatePattern</b> option. */    
  161.     public String getDatePattern() {    
  162.         return datePattern;    
  163.     }    
  164.     
  165.     public void activateOptions() {    
  166.         super.activateOptions();    
  167.         if (datePattern != null && fileName != null) {    
  168.             now.setTime(System.currentTimeMillis());    
  169.             sdf = new SimpleDateFormat(datePattern);    
  170.             int type = computeCheckPeriod();    
  171.             printPeriodicity(type);    
  172.             rc.setType(type);    
  173.             File file = new File(fileName);    
  174.             scheduledFilename = fileName    
  175.                     + sdf.format(new Date(file.lastModified()));    
  176.     
  177.         } else {    
  178.             LogLog.error("Either File or DatePattern options are not set for appender ["    
  179.                     + name + "].");    
  180.         }    
  181.     }    
  182.     
  183.     void printPeriodicity(int type) {    
  184.         switch (type) {    
  185.         case TOP_OF_MINUTE:    
  186.             LogLog.debug("Appender [" + name + "] to be rolled every minute.");    
  187.             break;    
  188.         case TOP_OF_HOUR:    
  189.             LogLog.debug("Appender [" + name    
  190.                     + "] to be rolled on top of every hour.");    
  191.             break;    
  192.         case HALF_DAY:    
  193.             LogLog.debug("Appender [" + name    
  194.                     + "] to be rolled at midday and midnight.");    
  195.             break;    
  196.         case TOP_OF_DAY:    
  197.             LogLog.debug("Appender [" + name + "] to be rolled at midnight.");    
  198.             break;    
  199.         case TOP_OF_WEEK:    
  200.             LogLog.debug("Appender [" + name    
  201.                     + "] to be rolled at start of week.");    
  202.             break;    
  203.         case TOP_OF_MONTH:    
  204.             LogLog.debug("Appender [" + name    
  205.                     + "] to be rolled at start of every month.");    
  206.             break;    
  207.         default:    
  208.             LogLog.warn("Unknown periodicity for appender [" + name + "].");    
  209.         }    
  210.     }    
  211.     
  212.     // This method computes the roll over period by looping over the    
  213.     // periods, starting with the shortest, and stopping when the r0 is    
  214.     // different from from r1, where r0 is the epoch formatted according    
  215.     // the datePattern (supplied by the user) and r1 is the    
  216.     // epoch+nextMillis(i) formatted according to datePattern. All date    
  217.     // formatting is done in GMT and not local format because the test    
  218.     // logic is based on comparisons relative to 1970-01-01 00:00:00    
  219.     // GMT (the epoch).    
  220.     
  221.     int computeCheckPeriod() {    
  222.         RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone,    
  223.                 Locale.ENGLISH);    
  224.         // set sate to 1970-01-01 00:00:00 GMT    
  225.         Date epoch = new Date(0);    
  226.         if (datePattern != null) {    
  227.             for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {    
  228.                 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(    
  229.                         datePattern);    
  230.                 simpleDateFormat.setTimeZone(gmtTimeZone); // do all date    
  231.                                                             // formatting in GMT    
  232.                 String r0 = simpleDateFormat.format(epoch);    
  233.                 rollingCalendar.setType(i);    
  234.                 Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));    
  235.                 String r1 = simpleDateFormat.format(next);    
  236.                 // System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1);    
  237.                 if (r0 != null && r1 != null && !r0.equals(r1)) {    
  238.                     return i;    
  239.                 }    
  240.             }    
  241.         }    
  242.         return TOP_OF_TROUBLE; // Deliberately head for trouble...    
  243.     }    
  244.     
  245.     /**  
  246.      * Implements the usual roll over behaviour.  
  247.      *   
  248.      * <p>  
  249.      * If <code>MaxBackupIndex</code> is positive, then files {  
  250.      * <code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code> are renamed  
  251.      * to {<code>File.2</code>, ..., <code>File.MaxBackupIndex</code> .  
  252.      * Moreover, <code>File</code> is renamed <code>File.1</code> and closed. A  
  253.      * new <code>File</code> is created to receive further log output.  
  254.      *   
  255.      * <p>  
  256.      * If <code>MaxBackupIndex</code> is equal to zero, then the  
  257.      * <code>File</code> is truncated with no backup files created.  
  258.      */    
  259.     public// synchronization not necessary since doAppend is alreasy synched    
  260.     void sizeRollOver() {    
  261.         File target;    
  262.         File file;    
  263.     
  264.         LogLog.debug("rolling over count="    
  265.                 + ((CountingQuietWriter) qw).getCount());    
  266.         LogLog.debug("maxBackupIndex=" + maxBackupIndex);    
  267.     
  268.         String datedFilename = fileName + sdf.format(now);    
  269.     
  270.         if (maxBackupIndex > 0) {    
  271.             // Delete the oldest file, to keep Windows happy.    
  272.             file = new File(datedFilename + '.' + maxBackupIndex);    
  273.             if (file.exists())    
  274.                 file.delete();    
  275.     
  276.             // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3,    
  277.             // 2}    
  278.             for (int i = maxBackupIndex - 1; i >= 1; i--) {    
  279.                 file = new File(datedFilename + "." + i);    
  280.                 if (file.exists()) {    
  281.                     target = new File(datedFilename + '.' + (i + 1));    
  282.                     LogLog.debug("Renaming file " + file + " to " + target);    
  283.                     file.renameTo(target);    
  284.                 }    
  285.             }    
  286.     
  287.             // Rename fileName to datedFilename.1    
  288.             target = new File(datedFilename + "." + 1);    
  289.     
  290.             this.closeFile(); // keep windows happy.    
  291.     
  292.             file = new File(fileName);    
  293.             LogLog.debug("Renaming file " + file + " to " + target);    
  294.             file.renameTo(target);    
  295.         }else if (maxBackupIndex < 0){//infinite number of files     
  296.             //find the max backup index    
  297.             for (int i = 1; i < Integer.MAX_VALUE; i++) {    
  298.                 target = new File(datedFilename + "." + i);    
  299.                 if (! target.exists()) {//Rename fileName to datedFilename.i    
  300.                     this.closeFile();    
  301.                     file = new File(fileName);    
  302.                     file.renameTo(target);    
  303.                     LogLog.debug("Renaming file " + file + " to " + target);    
  304.                     break;    
  305.                 }    
  306.             }    
  307.         }    
  308.     
  309.         try {    
  310.             // This will also close the file. This is OK since multiple    
  311.             // close operations are safe.    
  312.             this.setFile(fileName, false, bufferedIO, bufferSize);    
  313.         } catch (IOException e) {    
  314.             LogLog.error("setFile(" + fileName + ", false) call failed.", e);    
  315.         }    
  316.         scheduledFilename = datedFilename;    
  317.     }    
  318.     
  319.     public synchronized void setFile(String fileName, boolean append,    
  320.             boolean bufferedIO, int bufferSize) throws IOException {    
  321.         super.setFile(fileName, append, this.bufferedIO, this.bufferSize);    
  322.         if (append) {    
  323.             File f = new File(fileName);    
  324.             ((CountingQuietWriter) qw).setCount(f.length());    
  325.         }    
  326.     }    
  327.     
  328.     protected void setQWForFiles(Writer writer) {    
  329.         this.qw = new CountingQuietWriter(writer, errorHandler);    
  330.     }    
  331.     
  332.     /**  
  333.      * Rollover the current file to a new file.  
  334.      */    
  335.     void timeRollOver() throws IOException {    
  336.     
  337.         /* Compute filename, but only if datePattern is specified */    
  338.         if (datePattern == null) {    
  339.             errorHandler.error("Missing DatePattern option in rollOver().");    
  340.             return;    
  341.         }    
  342.     
  343.         String datedFilename = fileName + sdf.format(now);    
  344.         // It is too early to roll over because we are still within the    
  345.         // bounds of the current interval. Rollover will occur once the    
  346.         // next interval is reached.    
  347.         if (scheduledFilename.equals(datedFilename)) {    
  348.             return;    
  349.         }    
  350.     
  351.         // close current file, and rename it to datedFilename    
  352.         this.closeFile();    
  353.     
  354.         File target = new File(scheduledFilename);    
  355.         if (target.exists()) {    
  356.             target.delete();    
  357.         }    
  358.     
  359.         File file = new File(fileName);    
  360.         boolean result = file.renameTo(target);    
  361.         if (result) {    
  362.             LogLog.debug(fileName + " -> " + scheduledFilename);    
  363.         } else {    
  364.             LogLog.error("Failed to rename [" + fileName + "] to ["    
  365.                     + scheduledFilename + "].");    
  366.         }    
  367.     
  368.         try {    
  369.             // This will also close the file. This is OK since multiple    
  370.             // close operations are safe.    
  371.             super.setFile(fileName, falsethis.bufferedIO, this.bufferSize);    
  372.         } catch (IOException e) {    
  373.             errorHandler.error("setFile(" + fileName + ", false) call failed.");    
  374.         }    
  375.         scheduledFilename = datedFilename;    
  376.     }    
  377.     
  378.     /**  
  379.      * This method differentiates MyDailyRollingFileAppender from its super class.  
  380.      *   
  381.      * <p>  
  382.      * Before actually logging, this method will check whether it is time to do  
  383.      * a rollover. If it is, it will schedule the next rollover time and then  
  384.      * rollover.  
  385.      * */    
  386.     protected void subAppend(LoggingEvent event) {    
  387.         long n = System.currentTimeMillis();    
  388.     
  389.         if (n >= nextCheck) {    
  390.             now.setTime(n);    
  391.             nextCheck = rc.getNextCheckMillis(now);    
  392.             try {    
  393.                 timeRollOver();    
  394.             } catch (IOException ioe) {    
  395.                 LogLog.error("rollOver() failed.", ioe);    
  396.             }    
  397.         } else if ((fileName != null)    
  398.                 && ((CountingQuietWriter) qw).getCount() >= maxFileSize) {    
  399.             sizeRollOver();    
  400.         }    
  401.         super.subAppend(event);    
  402.     
  403.     }    
  404. }    
  405.     
  406. /**  
  407.  * RollingCalendar is a helper class to MyDailyRollingFileAppender. Given a  
  408.  * periodicity type and the current time, it computes the start of the next  
  409.  * interval.  
  410.  * */    
  411. class RollingCalendar extends GregorianCalendar {    
  412.     
  413.     private static final long serialVersionUID = -3221682547248233865L;  
  414.     int type = MyDailyRollingFileAppender.TOP_OF_TROUBLE;    
  415.     
  416.     RollingCalendar() {    
  417.         super();    
  418.     }    
  419.     
  420.     RollingCalendar(TimeZone tz, Locale locale) {    
  421.         super(tz, locale);    
  422.     }    
  423.     
  424.     void setType(int type) {    
  425.         this.type = type;    
  426.     }    
  427.     
  428.     public long getNextCheckMillis(Date now) {    
  429.         return getNextCheckDate(now).getTime();    
  430.     }    
  431.     
  432.     public Date getNextCheckDate(Date now) {    
  433.         this.setTime(now);    
  434.     
  435.         switch (type) {    
  436.         case MyDailyRollingFileAppender.TOP_OF_MINUTE:    
  437.             this.set(Calendar.SECOND, 0);    
  438.             this.set(Calendar.MILLISECOND, 0);    
  439.             this.add(Calendar.MINUTE, 1);    
  440.             break;    
  441.         case MyDailyRollingFileAppender.TOP_OF_HOUR:    
  442.             this.set(Calendar.MINUTE, 0);    
  443.             this.set(Calendar.SECOND, 0);    
  444.             this.set(Calendar.MILLISECOND, 0);    
  445.             this.add(Calendar.HOUR_OF_DAY, 1);    
  446.             break;    
  447.         case MyDailyRollingFileAppender.HALF_DAY:    
  448.             this.set(Calendar.MINUTE, 0);    
  449.             this.set(Calendar.SECOND, 0);    
  450.             this.set(Calendar.MILLISECOND, 0);    
  451.             int hour = get(Calendar.HOUR_OF_DAY);    
  452.             if (hour < 12) {    
  453.                 this.set(Calendar.HOUR_OF_DAY, 12);    
  454.             } else {    
  455.                 this.set(Calendar.HOUR_OF_DAY, 0);    
  456.                 this.add(Calendar.DAY_OF_MONTH, 1);    
  457.             }    
  458.             break;    
  459.         case MyDailyRollingFileAppender.TOP_OF_DAY:    
  460.             this.set(Calendar.HOUR_OF_DAY, 0);    
  461.             this.set(Calendar.MINUTE, 0);    
  462.             this.set(Calendar.SECOND, 0);    
  463.             this.set(Calendar.MILLISECOND, 0);    
  464.             this.add(Calendar.DATE, 1);    
  465.             break;    
  466.         case MyDailyRollingFileAppender.TOP_OF_WEEK:    
  467.             this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek());    
  468.             this.set(Calendar.HOUR_OF_DAY, 0);    
  469.             this.set(Calendar.SECOND, 0);    
  470.             this.set(Calendar.MILLISECOND, 0);    
  471.             this.add(Calendar.WEEK_OF_YEAR, 1);    
  472.             break;    
  473.         case MyDailyRollingFileAppender.TOP_OF_MONTH:    
  474.             this.set(Calendar.DATE, 1);    
  475.             this.set(Calendar.HOUR_OF_DAY, 0);    
  476.             this.set(Calendar.SECOND, 0);    
  477.             this.set(Calendar.MILLISECOND, 0);    
  478.             this.add(Calendar.MONTH, 1);    
  479.             break;    
  480.         default:    
  481.             throw new IllegalStateException("Unknown periodicity type.");    
  482.         }    
  483.         return getTime();    
  484.     }    

参考链接:https://blog.csdn.net/hao114500043/article/details/52909109

猜你喜欢

转载自blog.csdn.net/luker_/article/details/80632187
今日推荐