001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.rolling; 015 016import static org.junit.Assert.assertFalse; 017import static org.junit.Assert.assertTrue; 018 019import java.util.Date; 020 021import org.junit.After; 022import org.junit.Before; 023import org.junit.Test; 024 025import ch.qos.logback.classic.ClassicTestConstants; 026import ch.qos.logback.classic.Logger; 027import ch.qos.logback.classic.LoggerContext; 028import ch.qos.logback.classic.joran.JoranConfigurator; 029import ch.qos.logback.classic.spi.ILoggingEvent; 030import ch.qos.logback.core.CoreConstants; 031import ch.qos.logback.core.joran.spi.JoranException; 032import ch.qos.logback.core.rolling.RollingFileAppender; 033import ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy; 034import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; 035import ch.qos.logback.core.rolling.testUtil.ScaffoldingForRollingTests; 036import ch.qos.logback.core.status.Status; 037import ch.qos.logback.core.testUtil.StatusChecker; 038import ch.qos.logback.core.util.StatusPrinter; 039 040public class TimeBasedRollingWithConfigFileTest extends ScaffoldingForRollingTests { 041 042 LoggerContext lc = new LoggerContext(); 043 StatusChecker statusChecker = new StatusChecker(lc); 044 Logger logger = lc.getLogger(this.getClass()); 045 int fileSize = 0; 046 int fileIndexCounter = -1; 047 int sizeThreshold; 048 049 @Before 050 @Override 051 public void setUp() { 052 lc.setName("test"); 053 super.setUp(); 054 lc.putProperty("randomOutputDir", randomOutputDir); 055 } 056 057 @After 058 public void tearDown() throws Exception { 059 } 060 061 void loadConfig(String confifFile) throws JoranException { 062 JoranConfigurator jc = new JoranConfigurator(); 063 jc.setContext(lc); 064 jc.doConfigure(confifFile); 065 currentTime = System.currentTimeMillis(); 066 recomputeRolloverThreshold(currentTime); 067 } 068 069 @Test 070 public void basic() throws Exception { 071 String testId = "basic"; 072 lc.putProperty("testId", testId); 073 loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); 074 statusChecker.assertIsErrorFree(); 075 076 Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME); 077 078 expectedFilenameList.add(randomOutputDir + "z" + testId); 079 080 RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING"); 081 082 TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy(); 083 TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy(); 084 085 String prefix = "Hello---"; 086 int runLength = 4; 087 for (int i = 0; i < runLength; i++) { 088 logger.debug(prefix + i); 089 addExpectedFileNamedIfItsTime_ByDate(randomOutputDir, testId, false); 090 incCurrentTime(500); 091 tbnatp.setCurrentTime(currentTime); 092 } 093 094 existenceCheck(expectedFilenameList); 095 sortedContentCheck(randomOutputDir, runLength, prefix); 096 } 097 098 @Test 099 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}