1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.rolling;
15
16 import static ch.qos.logback.core.CoreConstants.CODES_URL;
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.rolling.helper.*;
23
24
25
26
27
28
29
30
31
32
33 public class FixedWindowRollingPolicy extends RollingPolicyBase {
34 static final String FNP_NOT_SET = "The \"FileNamePattern\" property must be set before using FixedWindowRollingPolicy. ";
35 static final String PRUDENT_MODE_UNSUPPORTED = "See also " + CODES_URL + "#tbr_fnp_prudent_unsupported";
36 static final String SEE_PARENT_FN_NOT_SET = "Please refer to " + CODES_URL + "#fwrp_parentFileName_not_set";
37 int maxIndex;
38 int minIndex;
39 RenameUtil util = new RenameUtil();
40 Compressor compressor;
41
42 public static final String ZIP_ENTRY_DATE_PATTERN = "yyyy-MM-dd_HHmm";
43
44
45
46
47 private static int MAX_WINDOW_SIZE = 20;
48
49 public FixedWindowRollingPolicy() {
50 minIndex = 1;
51 maxIndex = 7;
52 }
53
54 public void start() {
55 util.setContext(this.context);
56
57 if (fileNamePatternStr != null) {
58 determineCompressionMode();
59 adjustCompressionModeAndFileNamePatternStrIfNecessary();
60 fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
61 } else {
62 addError(FNP_NOT_SET);
63 addError(CoreConstants.SEE_FNP_NOT_SET);
64 throw new IllegalStateException(FNP_NOT_SET + CoreConstants.SEE_FNP_NOT_SET);
65 }
66
67 if (isParentPrudent()) {
68 addError("Prudent mode is not supported with FixedWindowRollingPolicy.");
69 addError(PRUDENT_MODE_UNSUPPORTED);
70 throw new IllegalStateException("Prudent mode is not supported.");
71 }
72
73 if (getParentsRawFileProperty() == null) {
74 addError("The File name property must be set before using this rolling policy.");
75 addError(SEE_PARENT_FN_NOT_SET);
76 throw new IllegalStateException("The \"File\" option must be set.");
77 }
78
79 if (maxIndex < minIndex) {
80 addWarn("MaxIndex (" + maxIndex + ") cannot be smaller than MinIndex (" + minIndex + ").");
81 addWarn("Setting maxIndex to equal minIndex.");
82 maxIndex = minIndex;
83 }
84
85 final int maxWindowSize = getMaxWindowSize();
86 if ((maxIndex - minIndex) > maxWindowSize) {
87 addWarn("Large window sizes are not allowed.");
88 maxIndex = minIndex + maxWindowSize;
89 addWarn("MaxIndex reduced to " + maxIndex);
90 }
91
92 IntegerTokenConverter itc = fileNamePattern.getIntegerTokenConverter();
93
94 if (itc == null) {
95 throw new IllegalStateException(
96 "FileNamePattern [" + fileNamePattern.getPattern() + "] does not contain a valid IntegerToken");
97 }
98
99 if (compressionMode == CompressionMode.ZIP) {
100 String zipEntryFileNamePatternStr = transformFileNamePatternFromInt2Date(fileNamePatternStr);
101 zipEntryFileNamePattern = new FileNamePattern(zipEntryFileNamePatternStr, context);
102 }
103 compressor = new Compressor(compressionMode);
104 compressor.setContext(this.context);
105 super.start();
106 }
107
108
109
110
111
112
113
114 protected int getMaxWindowSize() {
115 return MAX_WINDOW_SIZE;
116 }
117
118 private String transformFileNamePatternFromInt2Date(String fileNamePatternStr) {
119 String slashified = FileFilterUtil.slashify(fileNamePatternStr);
120 String stemOfFileNamePattern = FileFilterUtil.afterLastSlash(slashified);
121 return stemOfFileNamePattern.replace("%i", "%d{" + ZIP_ENTRY_DATE_PATTERN + "}");
122 }
123
124 public void rollover() throws RolloverFailure {
125
126
127
128
129 if (maxIndex >= 0) {
130
131 File file = new File(fileNamePattern.convertInt(maxIndex));
132
133 if (file.exists()) {
134 file.delete();
135 }
136
137
138 for (int i = maxIndex - 1; i >= minIndex; i--) {
139 String toRenameStr = fileNamePattern.convertInt(i);
140 File toRename = new File(toRenameStr);
141
142 if (toRename.exists()) {
143 util.rename(toRenameStr, fileNamePattern.convertInt(i + 1));
144 } else {
145 addInfo("Skipping roll-over for inexistent file " + toRenameStr);
146 }
147 }
148
149
150 switch (compressionMode) {
151 case NONE:
152 util.rename(getActiveFileName(), fileNamePattern.convertInt(minIndex));
153 break;
154 case GZ:
155 case XZ:
156 compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex), null);
157 break;
158 case ZIP:
159 compressor.compress(getActiveFileName(), fileNamePattern.convertInt(minIndex),
160 zipEntryFileNamePattern.convert(new Date()));
161 break;
162 }
163 }
164 }
165
166
167
168
169 public String getActiveFileName() {
170 return getParentsRawFileProperty();
171 }
172
173 public int getMaxIndex() {
174 return maxIndex;
175 }
176
177 public int getMinIndex() {
178 return minIndex;
179 }
180
181 public void setMaxIndex(int maxIndex) {
182 this.maxIndex = maxIndex;
183 }
184
185 public void setMinIndex(int minIndex) {
186 this.minIndex = minIndex;
187 }
188 }