View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, 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 static ch.qos.logback.core.CoreConstants.MANUAL_URL_PREFIX;
17  
18  import java.io.File;
19  import java.util.Date;
20  
21  import ch.qos.logback.core.CoreConstants;
22  import ch.qos.logback.core.joran.spi.NoAutoStart;
23  import ch.qos.logback.core.rolling.helper.ArchiveRemover;
24  import ch.qos.logback.core.rolling.helper.CompressionMode;
25  import ch.qos.logback.core.rolling.helper.FileFilterUtil;
26  import ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover;
27  import ch.qos.logback.core.util.FileSize;
28  import ch.qos.logback.core.util.DefaultInvocationGate;
29  import ch.qos.logback.core.util.InvocationGate;
30  
31  @NoAutoStart
32  public class SizeAndTimeBasedFNATP<E> extends TimeBasedFileNamingAndTriggeringPolicyBase<E> {
33  
34      enum Usage {EMBEDDED, DIRECT};
35  
36      
37      int currentPeriodsCounter = 0;
38      FileSize maxFileSize;
39      // String maxFileSizeAsString;
40  
41      long nextSizeCheck = 0;
42      static String MISSING_INT_TOKEN = "Missing integer token, that is %i, in FileNamePattern [";
43      static String MISSING_DATE_TOKEN = "Missing date token, that is %d, in FileNamePattern [";
44  
45      private final Usage usage;
46      
47      public SizeAndTimeBasedFNATP() {
48          this(Usage.DIRECT);
49      }
50      
51      public SizeAndTimeBasedFNATP(Usage usage) {
52          this.usage = usage;
53      }
54      
55      @Override
56      public void start() {
57          // we depend on certain fields having been initialized in super class
58          super.start();
59          
60          if(usage == Usage.DIRECT) {
61            addWarn(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
62            addWarn("For more information see "+MANUAL_URL_PREFIX+"appenders.html#SizeAndTimeBasedRollingPolicy");
63          }
64          
65          if (!super.isErrorFree())
66              return;
67  
68          
69          if (maxFileSize == null) {
70              addError("maxFileSize property is mandatory.");
71              withErrors();
72          }
73  
74          if (!validateDateAndIntegerTokens()) {
75              withErrors();
76              return;
77          }
78  
79          archiveRemover = createArchiveRemover();
80          archiveRemover.setContext(context);
81  
82          // we need to get the correct value of currentPeriodsCounter.
83          // usually the value is 0, unless the appender or the application
84          // is stopped and restarted within the same period
85          String regex = tbrp.fileNamePattern.toRegexForFixedDate(dateInCurrentPeriod);
86          String stemRegex = FileFilterUtil.afterLastSlash(regex);
87  
88          computeCurrentPeriodsHighestCounterValue(stemRegex);
89  
90          if (isErrorFree()) {
91              started = true;
92          }
93      }
94  
95      private boolean validateDateAndIntegerTokens() {
96          boolean inError = false;
97          if (tbrp.fileNamePattern.getIntegerTokenConverter() == null) {
98              inError = true;
99              addError(MISSING_INT_TOKEN + tbrp.fileNamePatternStr + "]");
100             addError(CoreConstants.SEE_MISSING_INTEGER_TOKEN);
101         }
102         if (tbrp.fileNamePattern.getPrimaryDateTokenConverter() == null) {
103             inError = true;
104             addError(MISSING_DATE_TOKEN + tbrp.fileNamePatternStr + "]");
105         }
106 
107         return !inError;
108     }
109 
110     protected ArchiveRemover createArchiveRemover() {
111         return new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
112     }
113 
114     void computeCurrentPeriodsHighestCounterValue(final String stemRegex) {
115         File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix());
116         File parentDir = file.getParentFile();
117 
118         File[] matchingFileArray = FileFilterUtil.filesInFolderMatchingStemRegex(parentDir, stemRegex);
119 
120         if (matchingFileArray == null || matchingFileArray.length == 0) {
121             currentPeriodsCounter = 0;
122             return;
123         }
124         currentPeriodsCounter = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
125 
126         // if parent raw file property is not null, then the next
127         // counter is max found counter+1
128         if (tbrp.getParentsRawFileProperty() != null || (tbrp.compressionMode != CompressionMode.NONE)) {
129             // TODO test me
130             currentPeriodsCounter++;
131         }
132     }
133 
134     InvocationGate invocationGate = new DefaultInvocationGate();
135 
136     @Override
137     public boolean isTriggeringEvent(File activeFile, final E event) {
138 
139         long time = getCurrentTime();
140 
141         // first check for roll-over based on time
142         if (time >= nextCheck) {
143             Date dateInElapsedPeriod = dateInCurrentPeriod;
144             elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInElapsedPeriod, currentPeriodsCounter);
145             currentPeriodsCounter = 0;
146             setDateInCurrentPeriod(time);
147             computeNextCheck();
148             return true;
149         }
150 
151         // next check for roll-over based on size
152         if (invocationGate.isTooSoon(time)) {
153             return false;
154         }
155 
156         if (activeFile == null) {
157             addWarn("activeFile == null");
158             return false;
159         }
160         if (maxFileSize == null) {
161             addWarn("maxFileSize = null");
162             return false;
163         }
164         if (activeFile.length() >= maxFileSize.getSize()) {
165 
166             elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
167             currentPeriodsCounter++;
168             return true;
169         }
170 
171         return false;
172     }
173 
174     @Override
175     public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
176         return tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInCurrentPeriod, currentPeriodsCounter);
177     }
178 
179     public void setMaxFileSize(FileSize aMaxFileSize) {
180         this.maxFileSize = aMaxFileSize;
181     }
182 
183 }