View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.rolling;
15  
16  import java.io.File;
17  import java.util.Date;
18  
19  import ch.qos.logback.core.joran.spi.NoAutoStart;
20  import ch.qos.logback.core.rolling.helper.CompressionMode;
21  import ch.qos.logback.core.rolling.helper.FileFilterUtil;
22  import ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover;
23  import ch.qos.logback.core.util.FileSize;
24  
25  @NoAutoStart
26  public class SizeAndTimeBasedFNATP<E> extends
27          TimeBasedFileNamingAndTriggeringPolicyBase<E> {
28  
29    int currentPeriodsCounter = 0;
30    FileSize maxFileSize;
31    String maxFileSizeAsString;
32  
33    @Override
34    public void start() {
35      // we depend on certain fields having been initialized
36      // in super.start()
37      super.start();
38  
39      archiveRemover = new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
40      archiveRemover.setContext(context);
41  
42      // we need to get the correct value of currentPeriodsCounter.
43      // usually the value is 0, unless the appender or the application
44      // is stopped and restarted within the same period
45      String regex = tbrp.fileNamePattern.toRegex(dateInCurrentPeriod);
46      String stemRegex = FileFilterUtil.afterLastSlash(regex);
47  
48  
49      computeCurrentPeriodsHighestCounterValue(stemRegex);
50  
51      started = true;
52    }
53  
54    void computeCurrentPeriodsHighestCounterValue(final String stemRegex) {
55      File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix());
56      File parentDir = file.getParentFile();
57  
58      File[] matchingFileArray = FileFilterUtil
59              .filesInFolderMatchingStemRegex(parentDir, stemRegex);
60  
61      if (matchingFileArray == null || matchingFileArray.length == 0) {
62        currentPeriodsCounter = 0;
63        return;
64      }
65      currentPeriodsCounter = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
66  
67      // if parent raw file property is not null, then the next
68      // counter is max  found counter+1
69      if (tbrp.getParentsRawFileProperty() != null || (tbrp.compressionMode != CompressionMode.NONE)) {
70        // TODO test me
71        currentPeriodsCounter++;
72      }
73    }
74  
75    // IMPORTANT: This field can be updated by multiple threads. It follows that
76    // its values may *not* be incremented sequentially. However, we don't care
77    // about the actual value of the field except that from time to time the
78    // expression (invocationCounter++ & invocationMask) == invocationMask) should be true.
79    private int invocationCounter;
80    private int invocationMask = 0x1;
81  
82    public boolean isTriggeringEvent(File activeFile, final E event) {
83  
84      long time = getCurrentTime();
85      if (time >= nextCheck) {
86        Date dateInElapsedPeriod = dateInCurrentPeriod;
87        elapsedPeriodsFileName = tbrp.fileNamePatternWCS
88                .convertMultipleArguments(dateInElapsedPeriod, currentPeriodsCounter);
89        currentPeriodsCounter = 0;
90        setDateInCurrentPeriod(time);
91        computeNextCheck();
92        return true;
93      }
94  
95      // for performance reasons, check for changes every 16,invocationMask invocations
96      if (((++invocationCounter) & invocationMask) != invocationMask) {
97        return false;
98      }
99      if (invocationMask < 0x0F) {
100       invocationMask = (invocationMask << 1) + 1;
101     }
102 
103     if (activeFile.length() >= maxFileSize.getSize()) {
104       elapsedPeriodsFileName = tbrp.fileNamePatternWCS
105               .convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
106       currentPeriodsCounter++;
107       return true;
108     }
109 
110     return false;
111   }
112 
113   private String getFileNameIncludingCompressionSuffix(Date date, int counter) {
114     return tbrp.fileNamePattern.convertMultipleArguments(
115             dateInCurrentPeriod, counter);
116   }
117 
118 
119   @Override
120   public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
121     return tbrp.fileNamePatternWCS.convertMultipleArguments(
122             dateInCurrentPeriod, currentPeriodsCounter);
123   }
124 
125   public String getMaxFileSize() {
126     return maxFileSizeAsString;
127   }
128 
129   public void setMaxFileSize(String maxFileSize) {
130     this.maxFileSizeAsString = maxFileSize;
131     this.maxFileSize = FileSize.valueOf(maxFileSize);
132   }
133 }