1
2
3
4
5
6
7
8
9
10
11
12 package ch.qos.logback.core.rolling;
13
14 import static ch.qos.logback.core.CoreConstants.MANUAL_URL_PREFIX;
15
16 import java.io.File;
17 import java.time.Instant;
18
19 import ch.qos.logback.core.CoreConstants;
20 import ch.qos.logback.core.joran.spi.NoAutoStart;
21 import ch.qos.logback.core.rolling.helper.ArchiveRemover;
22 import ch.qos.logback.core.rolling.helper.CompressionMode;
23 import ch.qos.logback.core.rolling.helper.FileFilterUtil;
24 import ch.qos.logback.core.rolling.helper.SizeAndTimeBasedArchiveRemover;
25 import ch.qos.logback.core.util.Duration;
26 import ch.qos.logback.core.util.FileSize;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 @NoAutoStart
43 public class SizeAndTimeBasedFileNamingAndTriggeringPolicy<E> extends TimeBasedFileNamingAndTriggeringPolicyBase<E> {
44
45 enum Usage {
46 EMBEDDED, DIRECT
47 }
48
49 volatile int currentPeriodsCounter = 0;
50 FileSize maxFileSize;
51
52 Duration checkIncrement = null;
53
54 static String MISSING_INT_TOKEN = "Missing integer token, that is %i, in FileNamePattern [";
55 static String MISSING_DATE_TOKEN = "Missing date token, that is %d, in FileNamePattern [";
56
57 private final Usage usage;
58
59
60
61 public SizeAndTimeBasedFileNamingAndTriggeringPolicy() {
62 this(Usage.DIRECT);
63 }
64
65 public SizeAndTimeBasedFileNamingAndTriggeringPolicy(Usage usage) {
66 this.usage = usage;
67 }
68
69 public LengthCounter lengthCounter = new LengthCounterBase();
70
71
72
73 @Override
74 public void start() {
75
76 super.start();
77
78 if (usage == Usage.DIRECT) {
79 addWarn(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
80 addWarn(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED_BIS);
81 addWarn("For more information see " + MANUAL_URL_PREFIX + "appenders.html#SizeAndTimeBasedRollingPolicy");
82 }
83
84 if (!super.isErrorFree())
85 return;
86
87 if (maxFileSize == null) {
88 addError("maxFileSize property is mandatory.");
89 withErrors();
90 }
91
92
93
94
95 if (!validateDateAndIntegerTokens()) {
96 withErrors();
97 return;
98 }
99
100 archiveRemover = createArchiveRemover();
101 archiveRemover.setContext(context);
102
103
104
105
106 String regex = tbrp.fileNamePattern.toRegexForFixedDate(dateInCurrentPeriod);
107 String stemRegex = FileFilterUtil.afterLastSlash(regex);
108
109 computeCurrentPeriodsHighestCounterValue(stemRegex);
110
111 if (isErrorFree()) {
112 started = true;
113 }
114 }
115
116 private boolean validateDateAndIntegerTokens() {
117 boolean inError = false;
118 if (tbrp.fileNamePattern.getIntegerTokenConverter() == null) {
119 inError = true;
120 addError(MISSING_INT_TOKEN + tbrp.fileNamePatternStr + "]");
121 addError(CoreConstants.SEE_MISSING_INTEGER_TOKEN);
122 }
123 if (tbrp.fileNamePattern.getPrimaryDateTokenConverter() == null) {
124 inError = true;
125 addError(MISSING_DATE_TOKEN + tbrp.fileNamePatternStr + "]");
126 }
127
128 return !inError;
129 }
130
131 protected ArchiveRemover createArchiveRemover() {
132 return new SizeAndTimeBasedArchiveRemover(tbrp.fileNamePattern, rc);
133 }
134
135 void computeCurrentPeriodsHighestCounterValue(final String stemRegex) {
136 File file = new File(getCurrentPeriodsFileNameWithoutCompressionSuffix());
137 File parentDir = file.getParentFile();
138
139 File[] matchingFileArray = FileFilterUtil.filesInFolderMatchingStemRegex(parentDir, stemRegex);
140
141 if (matchingFileArray == null || matchingFileArray.length == 0) {
142 currentPeriodsCounter = 0;
143 return;
144 }
145 currentPeriodsCounter = FileFilterUtil.findHighestCounter(matchingFileArray, stemRegex);
146
147
148
149 if (tbrp.getParentsRawFileProperty() != null || (tbrp.compressionMode != CompressionMode.NONE)) {
150
151 currentPeriodsCounter++;
152 }
153 }
154
155 @Override
156 public boolean isTriggeringEvent(File activeFile, final E event) {
157
158 long currentTime = getCurrentTime();
159 long localNextCheck = atomicNextCheck.get();
160
161
162 if (currentTime >= localNextCheck) {
163 long nextCheckCandidate = computeNextCheck(currentTime);
164 atomicNextCheck.set(nextCheckCandidate);
165 Instant instantInElapsedPeriod = dateInCurrentPeriod;
166 elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(
167 instantInElapsedPeriod, currentPeriodsCounter);
168 currentPeriodsCounter = 0;
169 setDateInCurrentPeriod(currentTime);
170 lengthCounter.reset();
171 return true;
172 }
173
174 boolean result = checkSizeBasedTrigger(activeFile, currentTime);
175 if(result)
176 lengthCounter.reset();
177 return result;
178 }
179
180 private boolean checkSizeBasedTrigger(File activeFile, long currentTime) {
181
182
183
184
185
186 if (activeFile == null) {
187 addWarn("activeFile == null");
188 return false;
189 }
190 if (maxFileSize == null) {
191 addWarn("maxFileSize = null");
192 return false;
193 }
194
195
196
197 if (lengthCounter.getLength() >= maxFileSize.getSize()) {
198
199 elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInCurrentPeriod,
200 currentPeriodsCounter);
201 currentPeriodsCounter++;
202
203 return true;
204 }
205
206 return false;
207 }
208
209 public Duration getCheckIncrement() {
210 return null;
211 }
212
213 public void setCheckIncrement(Duration checkIncrement) {
214 addWarn("Since version 1.5.8, 'checkIncrement' property has no effect");
215 }
216
217 @Override
218 public String getCurrentPeriodsFileNameWithoutCompressionSuffix() {
219 return tbrp.fileNamePatternWithoutCompSuffix.convertMultipleArguments(dateInCurrentPeriod,
220 currentPeriodsCounter);
221 }
222
223 public void setMaxFileSize(FileSize aMaxFileSize) {
224 this.maxFileSize = aMaxFileSize;
225 }
226
227 @Override
228 public LengthCounter getLengthCounter() {
229 return lengthCounter;
230 }
231 }