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.classic.rolling;
15  
16  import static org.junit.Assert.assertFalse;
17  import static org.junit.Assert.assertTrue;
18  
19  import java.util.Date;
20  
21  import org.junit.After;
22  import org.junit.Before;
23  import org.junit.Test;
24  
25  import ch.qos.logback.classic.ClassicTestConstants;
26  import ch.qos.logback.classic.Logger;
27  import ch.qos.logback.classic.LoggerContext;
28  import ch.qos.logback.classic.joran.JoranConfigurator;
29  import ch.qos.logback.classic.spi.ILoggingEvent;
30  import ch.qos.logback.core.CoreConstants;
31  import ch.qos.logback.core.joran.spi.JoranException;
32  import ch.qos.logback.core.rolling.RollingFileAppender;
33  import ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy;
34  import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
35  import ch.qos.logback.core.rolling.testUtil.ScaffoldingForRollingTests;
36  import ch.qos.logback.core.status.Status;
37  import ch.qos.logback.core.testUtil.StatusChecker;
38  import ch.qos.logback.core.util.StatusPrinter;
39  
40  public class TimeBasedRollingWithConfigFileTest extends ScaffoldingForRollingTests {
41  
42      LoggerContext lc = new LoggerContext();
43      StatusChecker statusChecker = new StatusChecker(lc);
44      Logger logger = lc.getLogger(this.getClass());
45      int fileSize = 0;
46      int fileIndexCounter = -1;
47      int sizeThreshold;
48  
49      @Before
50      @Override
51      public void setUp() {
52          lc.setName("test");
53          super.setUp();
54          lc.putProperty("randomOutputDir", randomOutputDir);
55      }
56  
57      @After
58      public void tearDown() throws Exception {
59      }
60  
61      void loadConfig(String confifFile) throws JoranException {
62          JoranConfigurator jc = new JoranConfigurator();
63          jc.setContext(lc);
64          jc.doConfigure(confifFile);
65          currentTime = System.currentTimeMillis();
66          recomputeRolloverThreshold(currentTime);
67      }
68  
69      @Test
70      public void basic() throws Exception {
71          String testId = "basic";
72          lc.putProperty("testId", testId);
73          loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
74          statusChecker.assertIsErrorFree();
75  
76          Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
77  
78          expectedFilenameList.add(randomOutputDir + "z" + testId);
79  
80          RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
81  
82          TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy();
83          TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy();
84  
85          String prefix = "Hello---";
86          int runLength = 4;
87          for (int i = 0; i < runLength; i++) {
88              logger.debug(prefix + i);
89              addExpectedFileNamedIfItsTime_ByDate(randomOutputDir, testId, false);
90              incCurrentTime(500);
91              tbnatp.setCurrentTime(currentTime);
92          }
93  
94          existenceCheck(expectedFilenameList);
95          sortedContentCheck(randomOutputDir, runLength, prefix);
96      }
97  
98      @Test
99      public void depratedSizeAndTimeBasedFNATPWarning() throws Exception {
100         String testId = "depratedSizeAndTimeBasedFNATPWarning";
101         lc.putProperty("testId", testId);
102         loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
103         StatusPrinter.print(lc);
104         statusChecker.assertContainsMatch(Status.WARN, CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
105     }
106     
107     @Test
108     public void timeAndSize() throws Exception {
109         String testId = "timeAndSize";
110         lc.putProperty("testId", testId);
111         String prefix = "Hello-----";
112 
113         // the number of times the log file will be written to before time based
114         // roll-over occurs
115         int approxWritesPerPeriod = 64;
116         sizeThreshold = prefix.length() * approxWritesPerPeriod;
117         lc.putProperty("sizeThreshold", "" + sizeThreshold);
118         loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
119         
120         StatusPrinter.print(lc);
121         // Test http://jira.qos.ch/browse/LOGBACK-1236
122         statusChecker.assertNoMatch(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED);
123         
124         Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
125 
126         expectedFilenameList.add(randomOutputDir + "z" + testId);
127 
128         RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
129 
130         statusChecker.assertIsErrorFree();
131 
132         TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy();
133         TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy();
134 
135         int timeIncrement = 1000 / approxWritesPerPeriod;
136         int runLength = approxWritesPerPeriod * 3;
137         for (int i = 0; i < runLength; i++) {
138             String msg = prefix + i;
139             logger.debug(msg);
140             addExpectedFileNamedIfItsTime(testId, msg, false);
141             incCurrentTime(timeIncrement);
142             tbnatp.setCurrentTime(currentTime);
143         }
144 
145         sortedContentCheck(randomOutputDir, runLength, prefix);
146         int eCount = existenceCount(expectedFilenameList);
147         // for various reasons, it is extremely difficult to have the files
148         // match exactly the expected archive files. Thus, we aim for
149         // an approximate match
150         assertTrue("exitenceCount=" + eCount + ", expectedFilenameList.size=" + expectedFilenameList.size(),
151                         eCount >= 4 && eCount > expectedFilenameList.size() / 2);
152     }
153 
154     @Test
155     public void timeAndSizeWithoutIntegerToken() throws Exception {
156         String testId = "timeAndSizeWithoutIntegerToken";
157         loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
158         Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
159         expectedFilenameList.add(randomOutputDir + "z" + testId);
160         RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
161         StatusPrinter.print(lc);
162 
163         statusChecker.assertContainsMatch("Missing integer token");
164         assertFalse(rfa.isStarted());
165     }
166 
167 
168     // see also LOGBACK-1176
169     @Test
170     public void timeAndSizeWithoutMaxFileSize() throws Exception {
171         String testId = "timeAndSizeWithoutMaxFileSize";
172         loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
173         Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
174         //expectedFilenameList.add(randomOutputDir + "z" + testId);
175         RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
176       
177 
178         //statusChecker.assertContainsMatch("Missing integer token");
179         assertFalse(rfa.isStarted());
180         StatusPrinter.print(lc);
181     }
182 
183     @Test
184     public void totalSizeCapSmallerThanMaxFileSize() throws Exception {
185         String testId = "totalSizeCapSmallerThanMaxFileSize";
186         lc.putProperty("testId", testId);
187         loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml");
188         Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME);
189         //expectedFilenameList.add(randomOutputDir + "z" + testId);
190         RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING");
191       
192         statusChecker.assertContainsMatch("totalSizeCap of \\[\\d* \\w*\\] is smaller than maxFileSize \\[\\d* \\w*\\] which is non-sensical");
193         assertFalse(rfa.isStarted());
194       
195     }
196 
197     void addExpectedFileNamedIfItsTime(String testId, String msg, boolean gzExtension) {
198         fileSize += msg.getBytes().length;
199 
200         if (passThresholdTime(nextRolloverThreshold)) {
201             fileIndexCounter = 0;
202             fileSize = 0;
203             addExpectedFileName(testId, getDateOfPreviousPeriodsStart(), fileIndexCounter, gzExtension);
204             recomputeRolloverThreshold(currentTime);
205             return;
206         }
207 
208         // windows can delay file size changes, so we only allow for
209         // fileIndexCounter 0 and 1
210         if ((fileIndexCounter < 1) && fileSize > sizeThreshold) {
211             addExpectedFileName(testId, getDateOfPreviousPeriodsStart(), ++fileIndexCounter, gzExtension);
212             fileSize = -1;
213             return;
214         }
215     }
216 
217     void addExpectedFileName(String testId, Date date, int fileIndexCounter, boolean gzExtension) {
218 
219         String fn = randomOutputDir + testId + "-" + SDF.format(date) + "." + fileIndexCounter;
220         System.out.println("Adding " + fn);
221         if (gzExtension) {
222             fn += ".gz";
223         }
224         expectedFilenameList.add(fn);
225     }
226 
227     @Override
228     protected void addExpectedFileNamedIfItsTime_ByDate(String outputDir, String testId, boolean gzExtension) {
229         if (passThresholdTime(nextRolloverThreshold)) {
230             addExpectedFileName_ByDate(outputDir, testId, getDateOfPreviousPeriodsStart(), gzExtension);
231             recomputeRolloverThreshold(currentTime);
232         }
233     }
234 }