Permalink
Browse files

Add cutom TBRP and unit test

  • Loading branch information...
1 parent 5f33810 commit 02fddd7aef1447252030d3a5cf1ddbd1b03ff3f0 @trothwell committed Nov 4, 2011
View
@@ -0,0 +1,5 @@
+.settings
+target
+.classpath
+.project
+*~
View
31 pom.xml
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.trothwell</groupId>
+ <artifactId>logback-test</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.0.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.10</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
@@ -0,0 +1,27 @@
+package org.trothwell.lbtest;
+
+import ch.qos.logback.core.rolling.RolloverFailure;
+import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;
+
+/**
+ * Causes rolling to occur by roles of {@link TimeBasedRollingPolicy} and when
+ * instance is closed (which occurs when appender is closed).
+ *
+ * @param <E>
+ * not quite sure :/
+ */
+public class CloseTBRP<E> extends TimeBasedRollingPolicy<E> {
+ @Override
+ public void stop() {
+ try {
+ addInfo("Rolling file due to policy closure: " + getActiveFileName());
+ synchronized (this) {
+ super.rollover();
+ }
+ } catch (RolloverFailure e) {
+ addError("Failed to complete rollover.", e);
+ } finally {
+ super.stop();
+ }
+ }
+}
@@ -0,0 +1,176 @@
+package org.trothwell.lbtest;
+
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.joran.JoranConfigurator;
+import ch.qos.logback.core.joran.spi.JoranException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.MDC;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class TestCloseTBRP {
+ private File tmp;
+ private LoggerContext lc;
+
+ @After
+ public void clean() throws IOException {
+ try {
+ try {
+ // FIXME: is everything flushed to the file?
+ TimeUnit.SECONDS.sleep(5);
+ } catch (InterruptedException e) {
+ echo("Interrupted in sleep.");
+ }
+ lc.stop();
+ } catch (RuntimeException e) {
+ echo("Exception while stopping: " + e.getClass().getSimpleName() + " - "
+ + e.getMessage());
+ throw e;
+ } finally {
+ // Always try to delete temp files
+ try {
+ // FIXME: should we wait for async compression process?
+ TimeUnit.SECONDS.sleep(15);
+ } catch (InterruptedException e) {
+ echo("Interrupted in sleep.");
+ } finally {
+ recursiveDelete(tmp);
+ }
+ }
+ }
+
+ /**
+ * Using a counter makes it a bit easier to determine which temp folder is
+ * which when looking at logs.
+ */
+ private static int counter = 0;
+
+ @Before
+ public void setup() throws IOException {
+ lc = new LoggerContext();
+ tmp = File.createTempFile(TestCloseTBRP.class.getSimpleName() + "_"
+ + (counter++) + "_", ".tmp");
+ if (!tmp.delete()) {
+ throw new IOException("Failed to delete: " + tmp.getAbsolutePath());
+ }
+ if (!tmp.mkdir()) {
+ throw new IOException("Failed to create folder: " + tmp.getAbsolutePath());
+ }
+ }
+
+ @Test
+ public void testCloseTBRP() throws IOException, JoranException {
+ URL cfg = TestCloseTBRP.class.getResource("config_closetbrp.xml");
+ assertNotNull(cfg);
+
+ lc.putProperty("TEMP_FOLDER", tmp.getAbsolutePath());
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(cfg);
+
+ Logger log = lc.getLogger("Test");
+ log.info("Test1"); // log to unknown
+ MDC.put("KEY", "key");
+ log.info("Test2"); // log to specific
+
+ List<String> txts = recursiveList(tmp, new FileFilter() {
+ public boolean accept(File f) {
+ return f.getName().endsWith(".txt");
+ }
+ });
+ assertEquals("The raw shouldn't exist.", 0, txts.size());
+
+ List<String> zips = recursiveList(tmp, new FileFilter() {
+ public boolean accept(File f) {
+ return f.getName().endsWith(".zip");
+ }
+ });
+ assertEquals("The raw should be converted to zip", 2, zips.size());
+
+ }
+
+ @Test
+ public void testTBRP() throws IOException, JoranException {
+ URL cfg = TestCloseTBRP.class.getResource("config_tbrp.xml");
+ assertNotNull(cfg);
+
+ LoggerContext lc = new LoggerContext();
+ lc.putProperty("TEMP_FOLDER", tmp.getAbsolutePath());
+ JoranConfigurator configurator = new JoranConfigurator();
+ configurator.setContext(lc);
+ configurator.doConfigure(cfg);
+
+ Logger log = lc.getLogger("Test");
+ log.info("Test1"); // log to unknown
+ MDC.put("KEY", "key");
+ log.info("Test2"); // log to specific
+
+ List<String> txts = recursiveList(tmp, new FileFilter() {
+ public boolean accept(File f) {
+ return f.getName().endsWith(".txt");
+ }
+ });
+ assertEquals("The 2 raw text files.", 2, txts.size());
+
+ List<String> zips = recursiveList(tmp, new FileFilter() {
+ public boolean accept(File f) {
+ return f.getName().endsWith(".zip");
+ }
+ });
+ assertEquals("No zips should have been converted", 0, zips.size());
+ }
+
+ private void echo(String msg) {
+ System.out.println(msg);
+ }
+
+ private void recursiveDelete(File folder) throws IOException {
+ for (File child : folder.listFiles()) {
+ if (child.isDirectory()) {
+ recursiveDelete(child);
+ } else if (child.isFile()) {
+ echo("Deleting file: " + child.getPath());
+ if (!child.delete()) {
+ throw new IOException("Failed to delete file: "
+ + child.getAbsolutePath());
+ }
+ } else if (child.exists()) {
+ // ?
+ } else {
+ }
+ }
+ echo("Deleting folder: " + folder.getPath());
+ if (!folder.delete()) {
+ throw new IOException("Failed to delete folder: "
+ + folder.getAbsolutePath());
+ }
+ }
+
+ private List<String> recursiveList(File folder, FileFilter filter) {
+ List<String> retval = new ArrayList<String>();
+ for (File child : folder.listFiles()) {
+ if (filter.accept(child)) {
+ retval.add(child.getAbsolutePath());
+ }
+ if (child.isDirectory()) {
+ retval.addAll(recursiveList(child, filter));
+ } else {
+ // file
+ }
+ }
+ return retval;
+ }
+}
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="true">
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>%d{HH:mm:ss.SSS zz} %-5level [%thread] %logger{35} [%-3X{KEY}] %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+ <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
+ <key>KEY</key>
+ <defaultValue>unknown</defaultValue>
+ </discriminator>
+ <sift>
+ <appender name="FILE-${KEY}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>%d{HH:mm:ss.SSS zz} %-5level [%thread] %logger{35} [%-3X{KEY}] %msg%n</pattern>
+ </encoder>
+ <rollingPolicy class="org.trothwell.lbtest.CloseTBRP">
+ <fileNamePattern>${TEMP_FOLDER}/${KEY}.%d{yyyy-MM-dd}.%i.txt.zip</fileNamePattern>
+ <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+ <maxFileSize>100MB</maxFileSize>
+ </timeBasedFileNamingAndTriggeringPolicy>
+ </rollingPolicy>
+ </appender>
+ </sift>
+ </appender>
+
+ <root level="TRACE">
+ <appender-ref ref="STDOUT" />
+ <appender-ref ref="SIFT" />
+ </root>
+</configuration>
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="true">
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>%d{HH:mm:ss.SSS zz} %-5level [%thread] %logger{35} [%-3X{KEY}] %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
+ <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
+ <key>KEY</key>
+ <defaultValue>unknown</defaultValue>
+ </discriminator>
+ <sift>
+ <appender name="FILE-${KEY}" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <pattern>%d{HH:mm:ss.SSS zz} %-5level [%thread] %logger{35} [%-3X{KEY}] %msg%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>${TEMP_FOLDER}/${KEY}.%d{yyyy-MM-dd}.%i.txt.zip</fileNamePattern>
+ <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+ <maxFileSize>100MB</maxFileSize>
+ </timeBasedFileNamingAndTriggeringPolicy>
+ </rollingPolicy>
+ </appender>
+ </sift>
+ </appender>
+
+ <root level="TRACE">
+ <appender-ref ref="STDOUT" />
+ <appender-ref ref="SIFT" />
+ </root>
+</configuration>

0 comments on commit 02fddd7

Please sign in to comment.