You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2013/02/19 08:35:39 UTC

svn commit: r1447605 - in /logging/log4j/log4j2/trunk: core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java src/changes/changes.xml

Author: rgoers
Date: Tue Feb 19 07:35:39 2013
New Revision: 1447605

URL: http://svn.apache.org/r1447605
Log:
LOG4J2-158 - Add RFC 5424 compliant escaping rules to RFC5424Layout.

Modified:
    logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
    logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java
    logging/log4j/log4j2/trunk/src/changes/changes.xml

Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java?rev=1447605&r1=1447604&r2=1447605&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java Tue Feb 19 07:35:39 2013
@@ -65,6 +65,10 @@ public final class RFC5424Layout extends
      * Match newlines in a platform-independent manner.
      */
     public static final Pattern NEWLINE_PATTERN = Pattern.compile("\\r?\\n");
+    /**
+     * Match characters which require escaping
+     */
+    public static final Pattern PARAM_VALUE_ESCAPE_PATTERN = Pattern.compile("[\\\"\\]\\\\]");
 
     private static final String DEFAULT_MDCID = "mdc";
     private static final int TWO_DIGITS = 10;
@@ -230,13 +234,14 @@ public final class RFC5424Layout extends
                 text = msg.getFormattedMessage();
             }
             if (includeMDC) {
+                Map<String, String> map = event.getContextMap();
                 if (mdcRequired != null) {
-                    checkRequired(event.getContextMap());
+                    checkRequired(map);
                 }
                 final int ein = id == null || id.getEnterpriseNumber() < 0 ?
                     enterpriseNumber : id.getEnterpriseNumber();
                 final StructuredDataId mdcSDID = new StructuredDataId(mdcId, ein, null, null);
-                formatStructuredElement(mdcSDID, event.getContextMap(), buf, checker);
+                formatStructuredElement(mdcSDID, map, buf, checker);
             }
             if (text != null && text.length() > 0) {
                 buf.append(" ").append(escapeNewlines(text, escapeNewLine));
@@ -385,12 +390,28 @@ public final class RFC5424Layout extends
         final SortedMap<String, String> sorted = new TreeMap<String, String>(map);
         for (final Map.Entry<String, String> entry : sorted.entrySet()) {
             if (checker.check(entry.getKey()) && entry.getValue() != null) {
-                sb.append(" ");
-                sb.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
+                sb
+                        .append(" ")
+                        .append(escapeNewlines(
+                        		escapeSDParams(
+                        				entry.getKey()),
+                                escapeNewLine))
+                        .append("=\"")
+                        .append(
+                                escapeNewlines(
+                                        escapeSDParams(
+                                                entry.getValue()),
+                                        escapeNewLine))
+                        .append("\"");
             }
         }
     }
 
+    private String escapeSDParams(String value)
+    {
+        return PARAM_VALUE_ESCAPE_PATTERN.matcher(value).replaceAll("\\\\$0");
+    }
+
     /**
      * Interface used to check keys in a Map.
      */

Modified: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java?rev=1447605&r1=1447604&r2=1447605&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java (original)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java Tue Feb 19 07:35:39 2013
@@ -51,6 +51,10 @@ public class RFC5424LayoutTest {
     private static final String line4 =
         "ATM - Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"]" +
         "[RequestContext@18060 ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete";
+    private static final String lineEscaped3 = "ATM - - [RequestContext@3692 escaped=\"Testing escaping #012 \\\" \\] \\\"\" loginId=\"JohnDoe\"] filled mdc";
+    private static final String lineEscaped4 = 
+        "ATM - Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"]" +
+        "[RequestContext@18060 escaped=\"Testing escaping #012 \\\" \\] \\\"\" ipAddress=\"192.168.0.120\" loginId=\"JohnDoe\"] Transfer Complete";
 
     static ConfigurationFactory cf = new BasicConfigurationFactory();
 
@@ -132,6 +136,69 @@ public class RFC5424LayoutTest {
     }
 
     /**
+     * Test case for escaping newlines and other SD PARAM-NAME special characters.
+     */
+    @Test
+    public void testEscape() throws Exception {
+        for (final Appender appender : root.getAppenders().values()) {
+            root.removeAppender(appender);
+        }
+        // set up appender
+        final AbstractStringLayout layout = RFC5424Layout.createLayout("Local0", "Event", "3692", "true", "RequestContext",
+            "true", "#012", "ATM", null, "key1, key2, locale", null, "loginId", null, null, null);
+        final ListAppender appender = new ListAppender("List", null, layout, true, false);
+
+        appender.start();
+
+        // set appender on root and set level to debug
+        root.addAppender(appender);
+        root.setLevel(Level.DEBUG);
+        
+        ThreadContext.put("loginId", "JohnDoe");
+
+        // output starting message
+        root.debug("starting mdc pattern test");
+
+        root.debug("empty mdc");
+
+        ThreadContext.put("escaped", "Testing escaping \n \" ] \"");
+
+        root.debug("filled mdc");
+
+        ThreadContext.put("ipAddress", "192.168.0.120");
+        ThreadContext.put("locale", Locale.US.getDisplayName());
+        try {
+            final StructuredDataMessage msg = new StructuredDataMessage("Transfer@18060", "Transfer Complete", "Audit");
+            msg.put("ToAccount", "123456");
+            msg.put("FromAccount", "123457");
+            msg.put("Amount", "200.00");
+            root.info(MarkerManager.getMarker("EVENT"), msg);
+
+            List<String> list = appender.getMessages();
+
+            assertTrue("Expected line 1 to end with: " + line1 + " Actual " + list.get(0), list.get(0).endsWith(line1));
+            assertTrue("Expected line 2 to end with: " + line2 + " Actual " + list.get(1), list.get(1).endsWith(line2));
+            assertTrue("Expected line 3 to end with: " + lineEscaped3 + " Actual " + list.get(2), list.get(2).endsWith(lineEscaped3));
+            assertTrue("Expected line 4 to end with: " + lineEscaped4 + " Actual " + list.get(3), list.get(3).endsWith(lineEscaped4));
+
+            appender.clear();
+
+            ThreadContext.remove("loginId");
+
+            root.debug("This is a test");
+
+            list = appender.getMessages();
+            assertTrue("No messages expected, found " + list.size(), list.size() == 0);
+        } finally {
+            root.removeAppender(appender);
+            ThreadContext.clear();
+
+            appender.stop();
+        }
+
+    }
+
+    /**
      * Test case for MDC conversion pattern.
      */
     @Test
@@ -169,5 +236,4 @@ public class RFC5424LayoutTest {
             appender.stop();
         }
     }
-
 }

Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1447605&r1=1447604&r2=1447605&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Tue Feb 19 07:35:39 2013
@@ -23,7 +23,9 @@
 
   <body>
     <release version="2.0-beta5" date="@TBD@" description="Bug fixes and enhancements">
-
+      <action issue="LOG4J2-158" dev="rgoers" due-to="Scott Severtson">
+        Add RFC 5424 compliant escaping rules to RFC5424Layout.
+      </action>
     </release>
     <release version="2.0-beta4" date="2012-01-28" description="Bug fixes and enhancements">
       <action issue="LOG4J2-156" dev="ggregory" type="fix" due-to="Andreas Born">