Permalink
Browse files

Add DebugPatternLayout

This is useful when you want to suppress stack traces at
DEBUG level.  It is a pattern layout that accepts 2
patterns, one for level<=DEBUG and another for level>DEBUG.
  • Loading branch information...
1 parent aca3cc2 commit 3f2feebe67b86d510d5544337f05a71a786d6d4b @dsyer committed Dec 18, 2012
View
@@ -27,7 +27,7 @@
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
- <version>1.2.14</version>
+ <version>1.2.16</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -57,8 +57,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <source>1.5</source>
- <target>1.5</target>
+ <source>1.6</source>
+ <target>1.6</target>
</configuration>
</plugin>
<plugin>
@@ -0,0 +1,82 @@
+package org.springframework.util.log4j;
+
+import org.apache.log4j.EnhancedPatternLayout;
+import org.apache.log4j.Level;
+import org.apache.log4j.helpers.OptionConverter;
+import org.apache.log4j.helpers.PatternConverter;
+import org.apache.log4j.pattern.BridgePatternConverter;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * Log4j layout that logs DEBUG (and TRACE) with a different pattern than INFO (and above). The default pattern is set
+ * as per the {@link EnhancedPatternLayout}, and the DEBUG pattern is set via the
+ * {@link #setDebugConversionPattern(String)} property. E.g. to suppress stack traces in DEBUG:
+ *
+ * <pre>
+ * LOG_PATTERN=[%d{yyyy-MM-dd HH:mm:ss.SSS}] %t %5p %c{1}: %m%n
+ * log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+ * log4j.appender.CONSOLE.layout=org.cloudfoundry.identity.uaa.log4j.DebugPatternLayout
+ * log4j.appender.CONSOLE.layout.ConversionPattern=${LOG_PATTERN}
+ * log4j.appender.CONSOLE.layout.DebugConversionPattern=${LOG_PATTERN}%throwable{0}
+ * log4j.appender.CONSOLE.threshold=DEBUG
+ * </pre>
+ *
+ * @author Dave Syer
+ *
+ */
+public class DebugPatternLayout extends EnhancedPatternLayout {
+
+ private PatternConverter debugFormatter;
+
+ private String conversionPattern;
+
+ @Override
+ public boolean ignoresThrowable() {
+ boolean result = super.ignoresThrowable();
+ if (!result) {
+ return false;
+ }
+ if (result && debugFormatter instanceof BridgePatternConverter) {
+ result = ((BridgePatternConverter) debugFormatter).ignoresThrowable();
+ }
+ return result;
+ }
+
+ public void setDebugConversionPattern(String conversionPattern) {
+ this.conversionPattern = OptionConverter.convertSpecialChars(conversionPattern);
+ debugFormatter = createPatternParser(this.conversionPattern).parse();
+ }
+
+ @Override
+ public void activateOptions() {
+ super.activateOptions();
+ if (debugFormatter == null) {
+ setDebugConversionPattern(getConversionPattern());
+ }
+ if (!ignoresThrowable() && super.ignoresThrowable()) {
+ setConversionPattern(getConversionPattern() + "%throwable{long}");
+ }
+ }
+
+ @Override
+ public String format(LoggingEvent event) {
+ if (event.getLevel().equals(Level.DEBUG) || !event.getLevel().isGreaterOrEqual(Level.DEBUG)) {
+ StringBuffer buf = new StringBuffer();
+ debugFormatter.format(buf, event);
+ convertTwoLinesToOneLine(buf, " [", "]");
+ return buf.toString();
+ }
+ return super.format(event);
+ }
+
+ public static void convertTwoLinesToOneLine(StringBuffer input, String prefix, String suffix) {
+ String ending = "\n";
+ int index = input.indexOf(ending);
+ int nextIndex = input.indexOf(ending, index + 1);
+ if (index > 0 && nextIndex > 0 && input.indexOf(ending, nextIndex + 1) < 0) {
+ input.replace(index, index+1, prefix);
+ input.replace(input.length()-1, input.length(), suffix);
+ }
+ }
+
+}
@@ -0,0 +1,54 @@
+package org.springframework.util.log4j;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.spi.RootLogger;
+import org.junit.Test;
+
+public class DebugPatternLayoutTests {
+
+ private static Logger logger = Logger.getLogger(DebugPatternLayoutTests.class);
+
+ @Test
+ public void testLogError() {
+ logger.error("No!!!!", new RuntimeException("Planned"));
+ }
+
+ @Test
+ public void testLogDebug() {
+ logger.debug("Yes!!!!", new RuntimeException("Planned"));
+ }
+
+ @Test
+ public void testFormatWithDebugAndThreeLines() throws Exception {
+ String format = getFormat(2, Level.DEBUG);
+ assertEquals(3, format.split("(?m)\n").length);
+ }
+
+ @Test
+ public void testFormatWithDebugAndTwoLinesConverted() throws Exception {
+ String format = getFormat(1, Level.DEBUG);
+ assertEquals(1, format.split("(?m)\n").length);
+ }
+
+ @Test
+ public void testFormatWithInfo() throws Exception {
+ String format = getFormat(1, Level.INFO);
+ assertTrue("Wrong format: " + format, format.split("(?m)\n").length > 3);
+ }
+
+ private String getFormat(int trace, Level level) throws Exception {
+ DebugPatternLayout layout = new DebugPatternLayout();
+ layout.setConversionPattern("%p: %c %m%n");
+ layout.setDebugConversionPattern("%p: %c %m%n%throwable{" + trace + "}");
+ layout.activateOptions();
+ String format = layout.format(new LoggingEvent(DebugPatternLayoutTests.class.getName(), new RootLogger(
+ Level.DEBUG), level, "Hello", new RuntimeException("Planned")));
+ return format;
+ }
+
+}

0 comments on commit 3f2feeb

Please sign in to comment.