View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * 
4    * Copyright (C) 1999-2006, QOS.ch
5    * 
6    * This library is free software, you can redistribute it and/or modify it under
7    * the terms of the GNU Lesser General Public License as published by the Free
8    * Software Foundation.
9    */
10  package ch.qos.logback.core.rolling;
11  
12  import java.io.File;
13  
14  import ch.qos.logback.core.rolling.helper.CompressionMode;
15  import ch.qos.logback.core.rolling.helper.Compressor;
16  import ch.qos.logback.core.rolling.helper.FileNamePattern;
17  import ch.qos.logback.core.rolling.helper.IntegerTokenConverter;
18  import ch.qos.logback.core.rolling.helper.RenameUtil;
19  
20  /**
21   * When rolling over, <code>FixedWindowRollingPolicy</code> renames files
22   * according to a fixed window algorithm.
23   * 
24   * For more information about this policy, please refer to the online manual at
25   * http://logback.qos.ch/manual/appenders.html#FixedWindowRollingPolicy
26   * 
27   * @author Ceki G&uuml;lc&uuml;
28   */
29  public class FixedWindowRollingPolicy extends RollingPolicyBase {
30    static final String FNP_NOT_SET = "The \"FileNamePattern\" property must be set before using FixedWindowRollingPolicy. ";
31    static final String SEE_FNP_NOT_SET = "See also http://logback.qos.ch/codes.html#tbr_fnp_not_set";
32    static final String PRUDENT_MODE_UNSUPPORTED = "See also http://logback.qos.ch/codes.html#tbr_fnp_prudent_unsupported";
33    static final String SEE_PARENT_FN_NOT_SET = "Please refer to http://logback.qos.ch/codes.html#fwrp_parentFileName_not_set";
34    int maxIndex;
35    int minIndex;
36    RenameUtil util = new RenameUtil();
37  
38    /**
39     * It's almost always a bad idea to have a large window size, say over 12.
40     */
41    private static int MAX_WINDOW_SIZE = 12;
42  
43    public FixedWindowRollingPolicy() {
44      minIndex = 1;
45      maxIndex = 7;
46    }
47  
48    public void start() {
49      // set the LR for our utility object
50      util.setContext(this.context);
51     
52      if (fileNamePatternStr != null) {
53        fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
54        determineCompressionMode();
55      } else {
56        addError(FNP_NOT_SET);
57        addError(SEE_FNP_NOT_SET);
58        throw new IllegalStateException(FNP_NOT_SET + SEE_FNP_NOT_SET);
59      }
60  
61      if(isParentPrudent()) {
62        addError("Prudent mode is not supported with FixedWindowRollingPolicy.");
63        addError(PRUDENT_MODE_UNSUPPORTED);
64        throw new IllegalStateException("Prudent mode is not supported.");
65      }
66      
67      if (getParentsRawFileProperty() == null) {
68        addError("The File name property must be set before using this rolling policy.");
69        addError(SEE_PARENT_FN_NOT_SET);
70        throw new IllegalStateException("The \"File\" option must be set.");
71      }
72  
73      if (maxIndex < minIndex) {
74        addWarn("MaxIndex (" + maxIndex + ") cannot be smaller than MinIndex ("
75            + minIndex + ").");
76        addWarn("Setting maxIndex to equal minIndex.");
77        maxIndex = minIndex;
78      }
79  
80      if ((maxIndex - minIndex) > MAX_WINDOW_SIZE) {
81        addWarn("Large window sizes are not allowed.");
82        maxIndex = minIndex + MAX_WINDOW_SIZE;
83        addWarn("MaxIndex reduced to " + maxIndex);
84      }
85  
86      IntegerTokenConverter itc = fileNamePattern.getIntegerTokenConverter();
87  
88      if (itc == null) {
89        throw new IllegalStateException("FileNamePattern ["
90            + fileNamePattern.getPattern()
91            + "] does not contain a valid IntegerToken");
92      }
93    }
94  
95    public void rollover() throws RolloverFailure {
96      // Inside this method it is guaranteed that the hereto active log file is
97      // closed.
98      // If maxIndex <= 0, then there is no file renaming to be done.
99      if (maxIndex >= 0) {
100       // Delete the oldest file, to keep Windows happy.
101       File file = new File(fileNamePattern.convertInt(maxIndex));
102 
103       if (file.exists()) {
104         file.delete();
105       }
106 
107       // Map {(maxIndex - 1), ..., minIndex} to {maxIndex, ..., minIndex+1}
108       for (int i = maxIndex - 1; i >= minIndex; i--) {
109         String toRenameStr = fileNamePattern.convertInt(i);
110         File toRename = new File(toRenameStr);
111         // no point in trying to rename an inexistent file
112         if (toRename.exists()) {
113           util.rename(toRenameStr, fileNamePattern.convertInt(i + 1));
114         } else {
115           addInfo("Skipping roll=over for inexistent file " + toRenameStr);
116         }
117       }
118 
119       // move active file name to min
120       Compressor compressor;
121       switch (compressionMode) {
122       case NONE:
123         util.rename(getActiveFileName(), fileNamePattern
124             .convertInt(minIndex));
125         break;
126       case GZ:
127         compressor = new Compressor(CompressionMode.GZ,
128             getActiveFileName(), fileNamePattern.convertInt(minIndex));
129         compressor.setContext(this.context);
130         compressor.compress();
131         break;
132       case ZIP:
133         compressor = new Compressor(CompressionMode.ZIP,
134             getActiveFileName(), fileNamePattern.convertInt(minIndex));
135         compressor.setContext(this.context);
136         compressor.compress();
137         break;
138       }
139     }
140   }
141 
142   /**
143    * Return the value of the <b>ActiveFile</b> option.
144    * 
145    * @see {@link setActiveFileName}.
146    */
147   public String getActiveFileName() {
148     return getParentsRawFileProperty();
149   }
150 
151   public int getMaxIndex() {
152     return maxIndex;
153   }
154 
155   public int getMinIndex() {
156     return minIndex;
157   }
158 
159   public void setMaxIndex(int maxIndex) {
160     this.maxIndex = maxIndex;
161   }
162 
163   public void setMinIndex(int minIndex) {
164     this.minIndex = minIndex;
165   }
166 
167   public CompressionMode getCompressionMode() {
168     return compressionMode;
169   }
170 }