Author: ceki
Date: Tue Oct  7 17:23:52 2008
New Revision: 1822

Modified:
   
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
   
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithCleanTest.java
   
logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-RollingTimeBased.xml
   logback/trunk/logback-site/src/site/pages/manual/appenders.html
   logback/trunk/logback-site/src/site/pages/news.html

Log:
Fixing LBCORE-11

- added unit tests 
- updated the documentation


Modified: 
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
==============================================================================
--- 
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
    (original)
+++ 
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.java
    Tue Oct  7 17:23:52 2008
@@ -13,8 +13,6 @@
 import java.util.Date;
 import java.util.concurrent.Future;
 
-import sun.misc.Cleaner;
-
 import ch.qos.logback.core.rolling.helper.AsynchronousCompressor;
 import ch.qos.logback.core.rolling.helper.Compressor;
 import ch.qos.logback.core.rolling.helper.CompressionMode;
@@ -26,11 +24,11 @@
 
 /**
  * <code>TimeBasedRollingPolicy</code> is both easy to configure and quite
- * powerful. It allows the rollover to be made based on time conditions. It is
- * possible to specify that the rollover must occur each day, or month, for
- * example.
+ * powerful. It allows the roll over to be made based on time. It is
+ * possible to specify that the roll over occur once per day, per week or 
+ * per month.
  * 
- * For more information about this policy, please refer to the online manual at
+ * <p>For more information, please refer to the online manual at
  * http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy
  * 
  * @author Ceki G&uuml;lc&uuml;
@@ -39,6 +37,8 @@
     TriggeringPolicy<E> {
   static final String FNP_NOT_SET = "The FileNamePattern option must be set 
before using TimeBasedRollingPolicy. ";
   static final String SEE_FNP_NOT_SET = "See also 
http://logback.qos.ch/codes.html#tbr_fnp_not_set";;
+  static final int DEFAULT_MAX_HISTORY = 0;
+
   RollingCalendar rc;
   long currentTime;
   long nextCheck;
@@ -51,8 +51,9 @@
   String lastGeneratedFileName;
   Future<?> future;
 
+  int maxHistory = DEFAULT_MAX_HISTORY;
   TimeBasedCleaner tbCleaner;
-  
+
   public void setCurrentTime(long timeInMillis) {
     currentTime = timeInMillis;
     isTimeForced = true;
@@ -116,9 +117,9 @@
     lastCheck.setTime(getCurrentTime());
     nextCheck = rc.getNextTriggeringMillis(lastCheck);
 
-    tbCleaner = new TimeBasedCleaner(fileNamePattern, rc, 5);
-    // Date nc = new Date();
-    // nc.setTime(nextCheck);
+    if (maxHistory != DEFAULT_MAX_HISTORY) {
+      tbCleaner = new TimeBasedCleaner(fileNamePattern, rc, maxHistory);
+    }
   }
 
   public void rollover() throws RolloverFailure {
@@ -136,7 +137,9 @@
       }
     }
 
-    tbCleaner.clean(new Date(getCurrentTime()));
+    if (tbCleaner != null) {
+      tbCleaner.clean(new Date(getCurrentTime()));
+    }
     
     // let's update the parent active file name
     setParentFileName(getNewActiveFileName());
@@ -180,13 +183,15 @@
    * file equals the file name for the current period as computed by the
    * <b>FileNamePattern</b> option.
    * 
-   * <p>The RollingPolicy must know wether it is responsible for changing the 
name
+   * <p>
+   * The RollingPolicy must know wether it is responsible for changing the name
    * of the active file or not. If the active file name is set by the user via
    * the configuration file, then the RollingPolicy must let it like it is. If
    * the user does not specify an active file name, then the RollingPolicy
    * generates one.
    * 
-   * <p>To be sure that the file name used by the parent class has been 
generated
+   * <p>
+   * To be sure that the file name used by the parent class has been generated
    * by the RollingPolicy and not specified by the user, we keep track of the
    * last generated name object and compare its reference to the parent file
    * name. If they match, then the RollingPolicy knows it's responsible for the
@@ -230,6 +235,25 @@
     }
   }
 
+  /**
+   * Get the number of archive files to keep.
+   * 
+   * @return number of archive files to keep
+   */
+  public int getMaxHistory() {
+    return maxHistory;
+  }
+
+  /**
+   * Set the maximum number of archive files to keep.
+   * 
+   * @param maxHistory
+   *                number of archive files to keep
+   */
+  public void setMaxHistory(int maxHistory) {
+    this.maxHistory = maxHistory;
+  }
+
   @Override
   public String toString() {
     return "c.q.l.core.rolling.TimeBasedRollingPolicy";

Modified: 
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithCleanTest.java
==============================================================================
--- 
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithCleanTest.java
     (original)
+++ 
logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/TimeBasedRollingWithCleanTest.java
     Tue Oct  7 17:23:52 2008
@@ -1,7 +1,11 @@
 package ch.qos.logback.core.rolling;
 
+import static org.junit.Assert.assertEquals;
 
-
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
 
 import org.junit.After;
 import org.junit.Before;
@@ -16,44 +20,96 @@
 
   Context context = new ContextBase();
   EchoLayout<Object> layout = new EchoLayout<Object>();
-  
-  static final String DATE_PATTERN = "yyyy-MM-dd_HH_mm_ss";
-  
+
+  static final String MONTHLY_DATE_PATTERN = "yyyy-MM";
+  static final String DAILY_DATE_PATTERN = "yyyy-MM-dd";
+
+  static final long MILLIS_IN_MINUTE = 60 * 1000;
+  static final long MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
+  static final long MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
+  static final long MILLIS_IN_MONTH = 30 * MILLIS_IN_DAY;
+
   @Before
   public void setUp() throws Exception {
     context.setName("test");
+
+    // remove all files containing the string 'clean'
+    File dir = new File(Constants.OUTPUT_DIR_PREFIX);
+    if (dir.isDirectory()) {
+      File[] toDelete = dir.listFiles(new FilenameFilter() {
+        public boolean accept(File dir, String name) {
+          return name.contains("clean");
+        }
+      });
+      for (File f : toDelete) {
+        System.out.println(f);
+        f.delete();
+      }
+    }
   }
 
   @After
   public void tearDown() throws Exception {
   }
 
-  
   @Test
-  public void smoke() {
+  public void montlyRollover() throws Exception {
+    doRollover(Constants.OUTPUT_DIR_PREFIX + "clean-%d{" + MONTHLY_DATE_PATTERN
+        + "}.txt", MILLIS_IN_MONTH, 20);
+
+  }
+
+  @Test
+  public void dailyRollover() throws Exception {
+    doRollover(Constants.OUTPUT_DIR_PREFIX + "clean-%d{" + DAILY_DATE_PATTERN
+        + "}.txt.zip", MILLIS_IN_DAY, 5);
+  }
+
+  void doRollover(String fileNamePattern, long delay, int maxHistory)
+      throws Exception {
     long currentTime = System.currentTimeMillis();
-    
+
     RollingFileAppender<Object> rfa = new RollingFileAppender<Object>();
     rfa.setContext(context);
     rfa.setLayout(layout);
-    rfa.setFile(Constants.OUTPUT_DIR_PREFIX + "clean.txt");
+    // rfa.setFile(Constants.OUTPUT_DIR_PREFIX + "clean.txt");
     TimeBasedRollingPolicy tbrp = new TimeBasedRollingPolicy();
     tbrp.setContext(context);
-    tbrp.setFileNamePattern(Constants.OUTPUT_DIR_PREFIX + "clean-%d{"
-        + DATE_PATTERN + "}.txt");
+    tbrp.setFileNamePattern(fileNamePattern);
+
+    tbrp.setMaxHistory(maxHistory);
     tbrp.setParent(rfa);
     tbrp.setCurrentTime(currentTime);
     tbrp.start();
     rfa.setRollingPolicy(tbrp);
     rfa.start();
-   
-    for (int i = 0; i < 10; i++) {
+
+    for (int i = 0; i < maxHistory * 3; i++) {
       rfa.doAppend("Hello---" + i);
-      tbrp.setCurrentTime(addTime(tbrp.getCurrentTime(), 500));      
+      tbrp.setCurrentTime(addTime(tbrp.getCurrentTime(), delay / 2));
+      if (tbrp.future != null) {
+        tbrp.future.get(200, TimeUnit.MILLISECONDS);
+      }
     }
-   
+    rfa.stop();
+    check(maxHistory + 1);
   }
-  
+
+  void check(int expectedCount) {
+    // remove all files containing the string 'clean'
+    File dir = new File(Constants.OUTPUT_DIR_PREFIX);
+    if (dir.isDirectory()) {
+      File[] match = dir.listFiles(new FilenameFilter() {
+        public boolean accept(File dir, String name) {
+          return name.contains("clean");
+        }
+      });
+      //System.out.println(Arrays.toString(match));
+      assertEquals(expectedCount, match.length);
+    }
+
+  }
+
   static long addTime(long currentTime, long timeToWait) {
     return currentTime + timeToWait;
   }

Modified: 
logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-RollingTimeBased.xml
==============================================================================
--- 
logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-RollingTimeBased.xml
     (original)
+++ 
logback/trunk/logback-examples/src/main/java/chapter4/conf/logback-RollingTimeBased.xml
     Tue Oct  7 17:23:52 2008
@@ -3,6 +3,8 @@
    <File>logFile.log</File>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <FileNamePattern>logFile.%d{yyyy-MM-dd}.log</FileNamePattern>
+     <!-- keep 30 days worth of history -->
+     <MaxHistory>30</MaxHistory> 
    </rollingPolicy>
 
    <layout class="ch.qos.logback.classic.PatternLayout">

Modified: logback/trunk/logback-site/src/site/pages/manual/appenders.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/manual/appenders.html     
(original)
+++ logback/trunk/logback-site/src/site/pages/manual/appenders.html     Tue Oct 
 7 17:23:52 2008
@@ -557,8 +557,10 @@
 <div class="source"><pre>java chapter4.ConfigurationTester 
src/main/java/chapter4/conf/logback-fileAppender.xml</pre></div>
        
        
-       <a name="RollingFileAppender"></a>
-       <h3>RollingFileAppender</h3>
+       
+       <h3>
+  <a name="RollingFileAppender" 
+     href="#RollingFileAppender">RollingFileAppender</a></h3>
        
        <p><a
        
href="../xref/ch/qos/logback/core/rolling/RollingFileAppender.html"><code>RollingFileAppender</code></a>
@@ -674,9 +676,11 @@
        given a reference to its parent via the <code>setParent</code>
        method.
        </p>
-       
-       <a name="FixedWindowRollingPolicy"></a>
-       <h4>FixedWindowRollingPolicy</h4>
+
+       <h4>    
+    <a name="FixedWindowRollingPolicy" 
+       href="#FixedWindowRollingPolicy">FixedWindowRollingPolicy</a>
+  </h4>
 
        <p>When rolling over, <a
        
href="../xref/ch/qos/logback/core/rolling/FixedWindowRollingPolicy.html">
@@ -854,17 +858,20 @@
   &lt;/root>
 &lt;/configuration></pre></div>
        
-       <a name="TimeBasedRollingPolicy"></a>
-       <h4>TimeBasedRollingPolicy</h4>
+  <h4>
+    <a name="TimeBasedRollingPolicy" 
href="#TimeBasedRollingPolicy">TimeBasedRollingPolicy</a>
+  </h4>
+
        <p>
                <a 
href="../xref/ch/qos/logback/core/rolling/TimeBasedRollingPolicy.html">
-               <code>TimeBasedRollingPolicy</code></a> is probably the most
-               popular rolling polciy. It allows defines a rollover policy 
based
-               on time, say by day or by month.
+               <code>TimeBasedRollingPolicy</code></a> is possibly the most
+               popular rolling polciy. It defines a rollover policy based on
+               time, say by day or by month.
        </p>
 
-       <p><code>TimeBasedRollingPolicy</code>'s has only one mandatory
-       option, namely <span class="option">FileNamePattern</span>.
+       <p><code>TimeBasedRollingPolicy</code>'s admits two properties, the
+       mandatory <span class="option">FileNamePattern</span> property and
+       the optinal <span class="option">MaxHistory</span> property.
        </p>
        
        <p><span class="option">FileNamePattern</span> option defines the
@@ -1010,17 +1017,24 @@
        interfaces.
        </p>
 
-       <p>By setting the <span class="option">File</span> option you can
+       <p>By setting the <span class="option">File</span> property you can
        decouple the location of the active log file and the location of the
        archived log files. The logging output will be targeted into the
-       file specified by the <span class="option">File</span> option. It
+       file specified by the <span class="option">File</span> property. It
        follows that the name of the active log file will not change over
        time. However, if you choose to omit the <span
-       class="option">File</span> option, then the active file will be
+       class="option">File</span> property, then the active file will be
        computed anew for each period based on the value of <span
        class="option">FileNamePattern</span>.
        </p>
        
+  <p>The <span class="option">MaxHistory</span> property controls the
+  maximum number of archive files to keep, deleting older files. For
+  example, if you specify monthly rollover, and set <span
+  class="option">MaxHistory</span> to 6, then 6 months worth of
+  archives files will be kept with files older than 6 months deleted.
+  </p>
+
        
        <p>For various reasons, rollovers are not clock-driven but depend on
        the arrival of logging events. For example, on 8th of March 2002,
@@ -1048,6 +1062,8 @@
     &lt;File>logFile.log&lt;/File>
     <b>&lt;rollingPolicy 
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       &lt;FileNamePattern>logFile.%d{yyyy-MM-dd}.log&lt;/FileNamePattern>
+      &lt;!-- keep 30 days worth of history -->
+      &lt;MaxHistory>30&lt;/MaxHistory>
     &lt;/rollingPolicy></b>
 
     &lt;layout class="ch.qos.logback.classic.PatternLayout">

Modified: logback/trunk/logback-site/src/site/pages/news.html
==============================================================================
--- logback/trunk/logback-site/src/site/pages/news.html (original)
+++ logback/trunk/logback-site/src/site/pages/news.html Tue Oct  7 17:23:52 2008
@@ -68,6 +68,10 @@
   file compressed asyncronously (in a separate thread).
   </p>
 
+  <p>Fixed issue <a
+  href="http://jira.qos.ch/browse/LBCORE-11";>LBCORE-11</a>.  It is now
+  possible to instruct TimeBasedRollingPolicy to delete old files,
+  thus controlling then number of archived log files.</p>
 
   <p>Fixed issue <a
   href="http://jira.qos.ch/browse/LBCORE-27";>LBCORE-27</a> reported by
_______________________________________________
logback-dev mailing list
[email protected]
http://qos.ch/mailman/listinfo/logback-dev

Reply via email to