1
2
3
4
5
6
7
8
9
10 package ch.qos.logback.core.rolling;
11
12 import java.io.File;
13 import java.util.Date;
14 import java.util.concurrent.Future;
15
16 import ch.qos.logback.core.rolling.helper.AsynchronousCompressor;
17 import ch.qos.logback.core.rolling.helper.CompressionMode;
18 import ch.qos.logback.core.rolling.helper.Compressor;
19 import ch.qos.logback.core.rolling.helper.DateTokenConverter;
20 import ch.qos.logback.core.rolling.helper.FileNamePattern;
21 import ch.qos.logback.core.rolling.helper.RenameUtil;
22 import ch.qos.logback.core.rolling.helper.RollingCalendar;
23 import ch.qos.logback.core.rolling.helper.TimeBasedCleaner;
24
25
26
27
28
29
30
31
32
33
34
35 public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements
36 TriggeringPolicy<E> {
37 static final String FNP_NOT_SET = "The FileNamePattern option must be set before using TimeBasedRollingPolicy. ";
38 static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
39 static final int NO_DELETE_HISTORY = 0;
40
41 RollingCalendar rc;
42 long currentTime;
43 long nextCheck;
44
45 boolean isTimeForced = false;
46 Date lastCheck = null;
47 String elapsedPeriodsFileName;
48 FileNamePattern activeFileNamePattern;
49 RenameUtil util = new RenameUtil();
50 String latestActiveFileName;
51 Future<?> future;
52
53 int maxHistory = NO_DELETE_HISTORY;
54 TimeBasedCleaner tbCleaner;
55
56 public void setCurrentTime(long timeInMillis) {
57 currentTime = timeInMillis;
58 isTimeForced = true;
59 }
60
61 public long getCurrentTime() {
62
63 if (isTimeForced) {
64 return currentTime;
65 } else {
66 return System.currentTimeMillis();
67 }
68 }
69
70 public void start() {
71
72 util.setContext(this.context);
73
74
75 if (fileNamePatternStr != null) {
76 fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
77 determineCompressionMode();
78 } else {
79 addWarn(FNP_NOT_SET);
80 addWarn(SEE_FNP_NOT_SET);
81 throw new IllegalStateException(FNP_NOT_SET + SEE_FNP_NOT_SET);
82 }
83
84 DateTokenConverter dtc = fileNamePattern.getDateTokenConverter();
85
86 if (dtc == null) {
87 throw new IllegalStateException("FileNamePattern ["
88 + fileNamePattern.getPattern()
89 + "] does not contain a valid DateToken");
90 }
91
92 int len = fileNamePatternStr.length();
93 switch (compressionMode) {
94 case GZ:
95 activeFileNamePattern = new FileNamePattern(fileNamePatternStr.substring(
96 0, len - 3), this.context);
97
98 break;
99 case ZIP:
100 activeFileNamePattern = new FileNamePattern(fileNamePatternStr.substring(
101 0, len - 4), this.context);
102 break;
103 case NONE:
104 activeFileNamePattern = fileNamePattern;
105 }
106 addInfo("Will use the pattern " + activeFileNamePattern
107 + " for the active file");
108
109 rc = new RollingCalendar();
110 rc.init(dtc.getDatePattern());
111 addInfo("The date pattern is '" + dtc.getDatePattern()
112 + "' from file name pattern '" + fileNamePattern.getPattern() + "'.");
113 rc.printPeriodicity(this);
114
115
116
117 if (lastCheck == null) {
118 lastCheck = new Date();
119 lastCheck.setTime(getCurrentTime());
120 if (getParentsRawFileProperty() != null) {
121 File currentFile = new File(getParentsRawFileProperty());
122 if (currentFile.exists() && currentFile.canRead()) {
123 lastCheck.setTime(currentFile.lastModified());
124 }
125 }
126 }
127 nextCheck = rc.getNextTriggeringMillis(lastCheck);
128
129 if (maxHistory != NO_DELETE_HISTORY) {
130 tbCleaner = new TimeBasedCleaner(fileNamePattern, rc, maxHistory);
131 }
132 }
133
134
135 public CompressionMode getCompressionMode() {
136 return compressionMode;
137 }
138
139
140
141
142 void setLastCheck(Date _lastCheck) {
143 this.lastCheck = _lastCheck;
144 }
145
146 boolean rolloverTargetIsParentFile() {
147 return (getParentsRawFileProperty() != null && getParentsRawFileProperty()
148 .equals(elapsedPeriodsFileName));
149 }
150
151 public void rollover() throws RolloverFailure {
152
153
154
155
156 if(compressionMode == CompressionMode.NONE) {
157 if (getParentsRawFileProperty() != null) {
158 util.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
159 }
160 } else {
161 if(getParentsRawFileProperty() == null) {
162 doCompression(false, elapsedPeriodsFileName, elapsedPeriodsFileName);
163 } else {
164 doCompression(true, elapsedPeriodsFileName, elapsedPeriodsFileName);
165 }
166 }
167
168 if (tbCleaner != null) {
169 tbCleaner.clean(new Date(getCurrentTime()));
170 }
171 }
172
173 void doCompression(boolean renameToTempFile, String nameOfFile2Compress,
174 String nameOfCompressedFile) throws RolloverFailure {
175 Compressor compressor = null;
176
177 if (renameToTempFile) {
178 String tmpTarget = nameOfFile2Compress + System.nanoTime() + ".tmp";
179 util.rename(getParentsRawFileProperty(), tmpTarget);
180 nameOfFile2Compress = tmpTarget;
181 }
182
183 switch (compressionMode) {
184 case GZ:
185 addInfo("GZIP compressing [" + nameOfFile2Compress + "].");
186 compressor = new Compressor(CompressionMode.GZ, nameOfFile2Compress,
187 nameOfCompressedFile);
188 compressor.setContext(this.context);
189 break;
190 case ZIP:
191 addInfo("ZIP compressing [" + nameOfFile2Compress + "]");
192 compressor = new Compressor(CompressionMode.ZIP, nameOfFile2Compress,
193 nameOfCompressedFile);
194 compressor.setContext(this.context);
195 break;
196 }
197
198 AsynchronousCompressor ac = new AsynchronousCompressor(compressor);
199 future = ac.compressAsynchronously();
200
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 public String getActiveFileName() {
224 if (getParentsRawFileProperty() == null) {
225 String newName = activeFileNamePattern.convertDate(lastCheck);
226 latestActiveFileName = newName;
227 return newName;
228 } else {
229 return getParentsRawFileProperty();
230 }
231 }
232
233 public boolean isTriggeringEvent(File activeFile, final E event) {
234 long time = getCurrentTime();
235
236 if (time >= nextCheck) {
237
238
239
240
241 elapsedPeriodsFileName = activeFileNamePattern.convertDate(lastCheck);
242
243 lastCheck.setTime(time);
244 nextCheck = rc.getNextTriggeringMillis(lastCheck);
245 return true;
246 } else {
247 return false;
248 }
249 }
250
251
252
253
254
255
256 public int getMaxHistory() {
257 return maxHistory;
258 }
259
260
261
262
263
264
265
266 public void setMaxHistory(int maxHistory) {
267 this.maxHistory = maxHistory;
268 }
269
270 @Override
271 public String toString() {
272 return "c.q.l.core.rolling.TimeBasedRollingPolicy";
273 }
274
275 }