[logback-dev] svn commit: r2384 - in logback/trunk/logback-core/src: main/java/ch/qos/logback/core/rolling main/java/ch/qos/logback/core/rolling/helper test/java/ch/qos/logback/core/rolling test/java/ch/qos/logback/core/rolling/helper

noreply.ceki at qos.ch noreply.ceki at qos.ch
Thu Jul 30 21:53:35 CEST 2009


Author: ceki
Date: Thu Jul 30 21:53:35 2009
New Revision: 2384

Added:
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicyTest.java
Modified:
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicy.java
   logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
   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/helper/FileNamePattern.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
   logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java

Log:
ongoing work

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/DefaultTimeBasedFileNamingAndTriggeringPolicy.java	Thu Jul 30 21:53:35 2009
@@ -19,9 +19,9 @@
     long time = getCurrentTime();
 
     if (time >= nextCheck) {
-      Date dateInElapsedPeriod = dateInCurrentPeriod;
+      Date dateOfElapsedPeriod = dateInCurrentPeriod;
       elapsedPeriodsFileName = tbrp.fileNamePatternWCS
-          .convert(dateInElapsedPeriod);
+          .convert(dateOfElapsedPeriod);
       updateDateInCurrentPeriod(time);
       computeNextCheck();
       return true;

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicy.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicy.java	Thu Jul 30 21:53:35 2009
@@ -12,27 +12,67 @@
 import java.io.File;
 import java.util.Date;
 
-public class SizeAndTimeBasedFileNamingAndTriggeringPolicy<E> extends  TimeBasedFileNamingAndTriggeringPolicyBase<E> {
+import ch.qos.logback.core.util.FileSize;
 
+public class SizeAndTimeBasedFileNamingAndTriggeringPolicy<E> extends
+    TimeBasedFileNamingAndTriggeringPolicyBase<E> {
+
+  int currentPeriodsCounter = 0;
+  FileSize maxFileSize;
+  String maxFileSizeAsString;
 
   @Override
   public void start() {
     super.start();
     started = true;
-  }  
+  }
+
+  // IMPORTANT: This field can be updated by multiple threads. It follows that
+  // its values may *not* be incremented sequentially. However, we don't care
+  // about the actual value of the field except that from time to time the
+  // expression (invocationCounter++ & 0xF) == 0xF) should be true.
+  private int invocationCounter;
 
   public boolean isTriggeringEvent(File activeFile, final E event) {
     long time = getCurrentTime();
-
     if (time >= nextCheck) {
       Date dateInElapsedPeriod = dateInCurrentPeriod;
       elapsedPeriodsFileName = tbrp.fileNamePatternWCS
-          .convert(dateInElapsedPeriod);
+          .convertMultipleArguments(dateInElapsedPeriod, currentPeriodsCounter);
+      currentPeriodsCounter = 0;
       updateDateInCurrentPeriod(time);
       computeNextCheck();
       return true;
-    } else {
+    }
+
+    // for performance reasons, check for changes every 16 invocations
+    if (((invocationCounter++) & 0xF) != 0xF) {
       return false;
     }
+
+    if (activeFile.length() >= maxFileSize.getSize()) {
+      elapsedPeriodsFileName = tbrp.fileNamePatternWCS
+          .convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
+      currentPeriodsCounter++;
+      return true;
+    }
+
+    return false;
   }
+
+  @Override
+  public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
+    return tbrp.fileNamePatternWCS.convertMultipleArguments(
+        dateInCurrentPeriod, currentPeriodsCounter);
+  }
+
+  public String getMaxFileSize() {
+    return maxFileSizeAsString;
+  }
+
+  public void setMaxFileSize(String maxFileSize) {
+    this.maxFileSizeAsString = maxFileSize;
+    this.maxFileSize = FileSize.valueOf(maxFileSize);
+  }
+
 }

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/SizeBasedTriggeringPolicy.java	Thu Jul 30 21:53:35 2009
@@ -15,37 +15,46 @@
 import ch.qos.logback.core.util.FileSize;
 
 /**
- * SizeBasedTriggeringPolicy looks at size of the file being
- * currently written to. If it grows bigger than the specified size, 
- * the FileAppender using the SizeBasedTriggeringPolicy rolls the file
- * and creates a new one.
+ * SizeBasedTriggeringPolicy looks at size of the file being currently written
+ * to. If it grows bigger than the specified size, the FileAppender using the
+ * SizeBasedTriggeringPolicy rolls the file and creates a new one.
  * 
  * For more information about this policy, please refer to the online manual at
  * http://logback.qos.ch/manual/appenders.html#SizeBasedTriggeringPolicy
  * 
  * @author Ceki G&uuml;lc&uuml;
- *
+ * 
  */
 public class SizeBasedTriggeringPolicy<E> extends TriggeringPolicyBase<E> {
-  
+
   public static final String SEE_SIZE_FORMAT = "http://logback.qos.ch/codes.html#sbtp_size_format";
   /**
    * The default maximum file size.
    */
   public static final long DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
-  
-  String maxFileSizeAsString = Long.toString(DEFAULT_MAX_FILE_SIZE); 
+
+  String maxFileSizeAsString = Long.toString(DEFAULT_MAX_FILE_SIZE);
   FileSize maxFileSize;
 
   public SizeBasedTriggeringPolicy() {
   }
 
   public SizeBasedTriggeringPolicy(final String maxFileSize) {
-      setMaxFileSize(maxFileSize);
+    setMaxFileSize(maxFileSize);
   }
 
+  // IMPORTANT: This field can be updated by multiple threads. It follows that
+  // its values may *not* be incremented sequentially. However, we don't care
+  // about the actual value of the field except that from time to time the
+  // expression (invocationCounter++ & 0xF) == 0xF) should be true.
+  private int invocationCounter;
+
   public boolean isTriggeringEvent(final File activeFile, final E event) {
-    //System.out.println("Size"+file.length());
+    // for performance reasons, check for changes every 16 invocations
+    if (((invocationCounter++) & 0xF) != 0xF) {
+      return false;
+    }
+
     return (activeFile.length() >= maxFileSize.getSize());
   }
 
@@ -57,36 +66,34 @@
     this.maxFileSizeAsString = maxFileSize;
     this.maxFileSize = FileSize.valueOf(maxFileSize);
   }
-  
+
   long toFileSize(String value) {
-    if(value == null)
+    if (value == null)
       return DEFAULT_MAX_FILE_SIZE;
 
     String s = value.trim().toUpperCase();
     long multiplier = 1;
     int index;
 
-    if((index = s.indexOf("KB")) != -1) {
+    if ((index = s.indexOf("KB")) != -1) {
       multiplier = 1024;
       s = s.substring(0, index);
-    }
-    else if((index = s.indexOf("MB")) != -1) {
-      multiplier = 1024*1024;
+    } else if ((index = s.indexOf("MB")) != -1) {
+      multiplier = 1024 * 1024;
       s = s.substring(0, index);
-    }
-    else if((index = s.indexOf("GB")) != -1) {
-      multiplier = 1024*1024*1024;
+    } else if ((index = s.indexOf("GB")) != -1) {
+      multiplier = 1024 * 1024 * 1024;
       s = s.substring(0, index);
     }
-    if(s != null) {
+    if (s != null) {
       try {
         return Long.valueOf(s).longValue() * multiplier;
-      }
-      catch (NumberFormatException e) {
-        addError("[" + s + "] is not in proper int format. Please refer to "+SEE_SIZE_FORMAT);
+      } catch (NumberFormatException e) {
+        addError("[" + s + "] is not in proper int format. Please refer to "
+            + SEE_SIZE_FORMAT);
         addError("[" + value + "] not in expected format.", e);
       }
     }
     return DEFAULT_MAX_FILE_SIZE;
-  } 
+  }
 }

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	Thu Jul 30 21:53:35 2009
@@ -46,8 +46,7 @@
   private int maxHistory = NO_DELETE_HISTORY;
   private TimeBasedCleaner tbCleaner;
 
-  TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedTriggering = new DefaultTimeBasedFileNamingAndTriggeringPolicy<E>();
-
+  TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedTriggering;
   public void start() {
     // set the LR for our utility object
     renameUtil.setContext(this.context);
@@ -72,6 +71,9 @@
     addInfo("Will use the pattern " + fileNamePatternWCS
         + " for the active file");
 
+    if(timeBasedTriggering == null) {
+      timeBasedTriggering = new DefaultTimeBasedFileNamingAndTriggeringPolicy<E>();
+    }
     timeBasedTriggering.setContext(context);
     timeBasedTriggering.setTimeBasedRollingPolicy(this);
     timeBasedTriggering.start();
@@ -82,6 +84,10 @@
     }
   }
 
+  public void setTimeBasedTriggering(TimeBasedFileNamingAndTriggeringPolicy<E> timeBasedTriggering) {
+    this.timeBasedTriggering = timeBasedTriggering;
+  }
+  
   static String computeFileNameStr_WCS(String fileNamePatternStr,
       CompressionMode compressionMode) {
     int len = fileNamePatternStr.length();

Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java	(original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/rolling/helper/FileNamePattern.java	Thu Jul 30 21:53:35 2009
@@ -10,9 +10,7 @@
 
 package ch.qos.logback.core.rolling.helper;
 
-import java.util.Date;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import ch.qos.logback.core.Context;
@@ -94,7 +92,7 @@
   }
 
   
-  public String convertList(List<Object> objectList) {
+  public String convertMultipleArguments(Object... objectList) {
     StringBuilder buf = new StringBuilder();
     Converter<Object> c = headTokenConverter;
     while (c != null) {

Added: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicyTest.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeAndTimeBasedFileNamingAndTriggeringPolicyTest.java	Thu Jul 30 21:53:35 2009
@@ -0,0 +1,169 @@
+package ch.qos.logback.core.rolling;
+
+import static org.junit.Assert.assertTrue;
+
+import java.sql.Date;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.layout.EchoLayout;
+import ch.qos.logback.core.testUtil.RandomUtil;
+import ch.qos.logback.core.util.Compare;
+import ch.qos.logback.core.util.CoreTestConstants;
+
+public class SizeAndTimeBasedFileNamingAndTriggeringPolicyTest {
+  static final String DATE_PATTERN = "yyyy-MM-dd_HH_mm_ss";
+
+  int diff = RandomUtil.getPositiveInt();
+  String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + "/" + diff
+      + "/";
+
+  SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object> satbfnatPolicy = new SizeAndTimeBasedFileNamingAndTriggeringPolicy<Object>();
+
+  SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);
+
+  EchoLayout<Object> layout = new EchoLayout<Object>();
+  Context context = new ContextBase();
+
+  RollingFileAppender<Object> rfa1 = new RollingFileAppender<Object>();
+  TimeBasedRollingPolicy<Object> tbrp1 = new TimeBasedRollingPolicy<Object>();
+  Calendar cal = Calendar.getInstance();
+  long currentTime; // initialized in setUp()
+  long nextRolloverThreshold; // initialized in setUp()
+  List<String> expectedFilenameList = new ArrayList<String>();
+
+  int fileSize = 0;
+  int fileIndexCounter = 0;
+  int sizeThreshold;
+  
+  @Before
+  public void setUp() {
+    context.setName("test");
+    cal.set(Calendar.MILLISECOND, 333);
+    currentTime = cal.getTimeInMillis();
+    recomputeRolloverThreshold(currentTime);
+    System.out.println("at setUp() currentTime="
+        + sdf.format(new Date(currentTime)));
+
+  }
+
+  // assuming rollover every second
+  void recomputeRolloverThreshold(long ct) {
+    long delta = ct % 1000;
+    nextRolloverThreshold = (ct - delta) + 1000;
+  }
+
+  void initRFA(RollingFileAppender<Object> rfa, String filename) {
+    rfa.setContext(context);
+    rfa.setLayout(layout);
+    if (filename != null) {
+      rfa.setFile(filename);
+    }
+  }
+
+  void initTRBP(RollingFileAppender<Object> rfa, TimeBasedRollingPolicy<Object> tbrp,
+      String filenamePattern, int sizeThreshold, long givenTime, long lastCheck) {
+
+    tbrp.setContext(context);
+    satbfnatPolicy.setMaxFileSize(""+sizeThreshold);
+    tbrp.setTimeBasedTriggering(satbfnatPolicy);
+    tbrp.setFileNamePattern(filenamePattern);
+    tbrp.setParent(rfa);
+    tbrp.timeBasedTriggering.setCurrentTime(givenTime);
+    if (lastCheck != 0) {
+      tbrp.timeBasedTriggering.setDateInCurrentPeriod(new Date(lastCheck));
+    }
+    rfa.setRollingPolicy(tbrp);
+    tbrp.start();
+    rfa.start();
+  }
+
+  @Test
+  public void noCompression_FileBSet_NoRestart_1() throws Exception {
+    String testId = "test1";
+    System.out.println(randomOutputDir);
+    String file = randomOutputDir + "toto.log";
+    initRFA(rfa1, file);
+    sizeThreshold = 300;
+    initTRBP(rfa1, tbrp1, randomOutputDir + testId + "-%d{" + DATE_PATTERN
+        + "}-%i.txt", sizeThreshold, currentTime, 0);
+
+    addExpectedFileName(testId, getDateOfCurrentPeriodsStart(), fileIndexCounter, false);
+
+    incCurrentTime(100);
+    tbrp1.timeBasedTriggering.setCurrentTime(currentTime);
+
+    for (int i = 0; i < 100; i++) {
+      String msg = "Hello -----------------" + i;
+      rfa1.doAppend(msg);
+      addExpectedFileNamedIfItsTime(testId, msg, false);
+      incCurrentTime(20);
+      tbrp1.timeBasedTriggering.setCurrentTime(currentTime);
+    }
+    
+
+    massageExpectedFilesToCorresponToCurrentTarget(file);
+    int i = 0;
+    for (String fn : expectedFilenameList) {
+      System.out.println(fn);
+      //assertTrue(Compare.compare(fn, CoreTestConstants.TEST_DIR_PREFIX
+      //    + "witness/rolling/satb-test1." + i++));
+    }
+  }
+  
+  void massageExpectedFilesToCorresponToCurrentTarget(String file) {
+    // we added one too many files by date
+    expectedFilenameList.remove(expectedFilenameList.size() - 1);
+    expectedFilenameList.add(file);
+  }
+  
+  boolean passThresholdTime(long nextRolloverThreshold) {
+    return currentTime >= nextRolloverThreshold;
+  }
+  
+  void addExpectedFileNamedIfItsTime(String testId, String msg, boolean gzExtension) {
+    fileSize += msg.getBytes().length;
+    
+    if (passThresholdTime(nextRolloverThreshold)) {
+      fileIndexCounter = 0;
+      fileSize = 0;
+      addExpectedFileName(testId, getDateOfCurrentPeriodsStart(), fileIndexCounter,
+          gzExtension);
+      recomputeRolloverThreshold(currentTime);
+      return;
+    }
+    
+    // windows can delay file size changes
+    if((fileIndexCounter <= 1) && fileSize > sizeThreshold) {
+      addExpectedFileName(testId, getDateOfCurrentPeriodsStart(), ++fileIndexCounter,
+          gzExtension);
+      fileSize = 0;
+      return;
+    }
+    
+  }
+
+  void addExpectedFileName(String testId, Date date, int fileIndexCounter, boolean gzExtension) {
+    String fn = CoreTestConstants.OUTPUT_DIR_PREFIX + testId + "-" + sdf.format(date)+"-"+fileIndexCounter+".txt";
+    if (gzExtension) {
+      fn += ".gz";
+    }
+    expectedFilenameList.add(fn);
+  }
+  
+  Date getDateOfCurrentPeriodsStart() {
+    long delta = currentTime % 1000;
+    return new Date(currentTime - delta);
+  }
+  
+  void incCurrentTime(long increment) {
+    currentTime += increment;
+  }
+}

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/SizeBasedRollingTest.java	Thu Jul 30 21:53:35 2009
@@ -68,7 +68,7 @@
    * ActiveFileName is not set.
    */
   @Test
-  public void test1() throws Exception {
+  public void activeFileNameNotSet() throws Exception {
     // We purposefully use the \n as the line separator.
     // This makes the regression test system independent.
     Context context = new ContextBase();
@@ -101,7 +101,7 @@
    * Test basic rolling functionality.
    */
   @Test
-  public void test2() throws Exception {
+  public void smoke() throws Exception {
     Context context = new ContextBase();
 
     DummyLayout<Object> layout = new DummyLayout<Object>("0123456789");

Modified: logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java
==============================================================================
--- logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java	(original)
+++ logback/trunk/logback-core/src/test/java/ch/qos/logback/core/rolling/helper/FileNamePatternTest.java	Thu Jul 30 21:53:35 2009
@@ -11,9 +11,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.List;
 
 import org.junit.Test;
 
@@ -102,18 +100,10 @@
 
   @Test
   public void objectListConverter() {
-    List<Object> oList = new ArrayList<Object>();
-    
     Calendar cal = Calendar.getInstance();
     cal.set(2003, 4, 20, 17, 55);
-
-    oList.add(cal.getTime());
-    oList.add(79);
-    
-    
     FileNamePattern fnp = new FileNamePattern("foo-%d{yyyy.MM.dd}-%i.txt", context);
-    
-    assertEquals("foo-2003.05.20-79.txt", fnp.convertList(oList));
+    assertEquals("foo-2003.05.20-79.txt", fnp.convertMultipleArguments(cal.getTime(), 79));
   }
 
 }


More information about the logback-dev mailing list