/** * Logback: the reliable, generic, fast and flexible logging framework. * Copyright (C) 1999-2015, QOS.ch. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. */ package ch.qos.logback.classic.rolling; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.util.Date; import org.junit.After; import org.junit.Before; import org.junit.Test; import ch.qos.logback.classic.ClassicTestConstants; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.joran.JoranConfigurator; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.CoreConstants; import ch.qos.logback.core.joran.spi.JoranException; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.ScaffoldingForRollingTests; import ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicy; import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; import ch.qos.logback.core.status.Status; import ch.qos.logback.core.status.StatusChecker; import ch.qos.logback.core.util.StatusPrinter; public class TimeBasedRollingWithConfigFileTest extends ScaffoldingForRollingTests { LoggerContext lc = new LoggerContext(); StatusChecker statusChecker = new StatusChecker(lc); Logger logger = lc.getLogger(this.getClass()); int fileSize = 0; int fileIndexCounter = -1; int sizeThreshold; @Before @Override public void setUp() { lc.setName("test"); super.setUp(); lc.putProperty("randomOutputDir", randomOutputDir); } @After public void tearDown() throws Exception { } void loadConfig(String confifFile) throws JoranException { JoranConfigurator jc = new JoranConfigurator(); jc.setContext(lc); jc.doConfigure(confifFile); currentTime = System.currentTimeMillis(); recomputeRolloverThreshold(currentTime); } @Test public void basic() throws Exception { String testId = "basic"; lc.putProperty("testId", testId); loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); statusChecker.assertIsErrorFree(); Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME); expectedFilenameList.add(randomOutputDir + "z" + testId); RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING"); TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy(); TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy(); String prefix = "Hello---"; int runLength = 4; for (int i = 0; i < runLength; i++) { logger.debug(prefix + i); addExpectedFileNamedIfItsTime_ByDate(randomOutputDir, testId, false); incCurrentTime(500); tbnatp.setCurrentTime(currentTime); } existenceCheck(expectedFilenameList); sortedContentCheck(randomOutputDir, runLength, prefix); } @Test public void depratedSizeAndTimeBasedFNATPWarning() throws Exception { String testId = "depratedSizeAndTimeBasedFNATPWarning"; lc.putProperty("testId", testId); loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); StatusPrinter.print(lc); statusChecker.assertContainsMatch(Status.WARN, CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED); } @Test public void timeAndSize() throws Exception { String testId = "timeAndSize"; lc.putProperty("testId", testId); String prefix = "Hello-----"; // the number of times the log file will be written to before time based // roll-over occurs int approxWritesPerPeriod = 64; sizeThreshold = prefix.length() * approxWritesPerPeriod; lc.putProperty("sizeThreshold", "" + sizeThreshold); loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); StatusPrinter.print(lc); // Test http://jira.qos.ch/browse/LOGBACK-1236 statusChecker.assertNoMatch(CoreConstants.SIZE_AND_TIME_BASED_FNATP_IS_DEPRECATED); Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME); expectedFilenameList.add(randomOutputDir + "z" + testId); RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING"); statusChecker.assertIsErrorFree(); TimeBasedRollingPolicy<ILoggingEvent> tprp = (TimeBasedRollingPolicy<ILoggingEvent>) rfa.getTriggeringPolicy(); TimeBasedFileNamingAndTriggeringPolicy<ILoggingEvent> tbnatp = tprp.getTimeBasedFileNamingAndTriggeringPolicy(); int timeIncrement = 1000 / approxWritesPerPeriod; int runLength = approxWritesPerPeriod * 3; for (int i = 0; i < runLength; i++) { String msg = prefix + i; logger.debug(msg); addExpectedFileNamedIfItsTime(testId, msg, false); incCurrentTime(timeIncrement); tbnatp.setCurrentTime(currentTime); } sortedContentCheck(randomOutputDir, runLength, prefix); int eCount = existenceCount(expectedFilenameList); // for various reasons, it is extremely difficult to have the files // match exactly the expected archive files. Thus, we aim for // an approximate match assertTrue("exitenceCount=" + eCount + ", expectedFilenameList.size=" + expectedFilenameList.size(), eCount >= 4 && eCount > expectedFilenameList.size() / 2); } @Test public void timeAndSizeWithoutIntegerToken() throws Exception { String testId = "timeAndSizeWithoutIntegerToken"; loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME); expectedFilenameList.add(randomOutputDir + "z" + testId); RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING"); StatusPrinter.print(lc); statusChecker.assertContainsMatch("Missing integer token"); assertFalse(rfa.isStarted()); } // see also LOGBACK-1176 @Test public void timeAndSizeWithoutMaxFileSize() throws Exception { String testId = "timeAndSizeWithoutMaxFileSize"; loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME); //expectedFilenameList.add(randomOutputDir + "z" + testId); RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING"); //statusChecker.assertContainsMatch("Missing integer token"); assertFalse(rfa.isStarted()); StatusPrinter.print(lc); } @Test public void totalSizeCapSmallerThanMaxFileSize() throws Exception { String testId = "totalSizeCapSmallerThanMaxFileSize"; lc.putProperty("testId", testId); loadConfig(ClassicTestConstants.JORAN_INPUT_PREFIX + "rolling/" + testId + ".xml"); Logger root = lc.getLogger(Logger.ROOT_LOGGER_NAME); //expectedFilenameList.add(randomOutputDir + "z" + testId); RollingFileAppender<ILoggingEvent> rfa = (RollingFileAppender<ILoggingEvent>) root.getAppender("ROLLING"); statusChecker.assertContainsMatch("totalSizeCap of \\[\\d* \\w*\\] is smaller than maxFileSize \\[\\d* \\w*\\] which is non-sensical"); assertFalse(rfa.isStarted()); } void addExpectedFileNamedIfItsTime(String testId, String msg, boolean gzExtension) { fileSize += msg.getBytes().length; if (passThresholdTime(nextRolloverThreshold)) { fileIndexCounter = 0; fileSize = 0; addExpectedFileName(testId, getDateOfPreviousPeriodsStart(), fileIndexCounter, gzExtension); recomputeRolloverThreshold(currentTime); return; } // windows can delay file size changes, so we only allow for // fileIndexCounter 0 and 1 if ((fileIndexCounter < 1) && fileSize > sizeThreshold) { addExpectedFileName(testId, getDateOfPreviousPeriodsStart(), ++fileIndexCounter, gzExtension); fileSize = -1; return; } } void addExpectedFileName(String testId, Date date, int fileIndexCounter, boolean gzExtension) { String fn = randomOutputDir + testId + "-" + SDF.format(date) + "." + fileIndexCounter; System.out.println("Adding " + fn); if (gzExtension) { fn += ".gz"; } expectedFilenameList.add(fn); } @Override protected void addExpectedFileNamedIfItsTime_ByDate(String outputDir, String testId, boolean gzExtension) { if (passThresholdTime(nextRolloverThreshold)) { addExpectedFileName_ByDate(outputDir, testId, getDateOfPreviousPeriodsStart(), gzExtension); recomputeRolloverThreshold(currentTime); } } }