[logback-dev] svn commit: r1822 - in logback/trunk: logback-core/src/main/java/ch/qos/logback/core/rolling logback-core/src/test/java/ch/qos/logback/core/rolling logback-examples/src/main/java/chapter4/conf logback-site/src/site/pages logback-site/src/site/pages/manual

noreply.ceki at qos.ch noreply.ceki at qos.ch
Tue Oct 7 17:23:53 CEST 2008


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


More information about the logback-dev mailing list