You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/03/04 15:23:21 UTC

[43/50] [abbrv] logging-log4j2 git commit: LOG4J2-1217 - PatternLayout option to limit length of text.

LOG4J2-1217 - PatternLayout option to limit length of text.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/df0270af
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/df0270af
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/df0270af

Branch: refs/heads/LOG4J2-1278-gc-free-logger
Commit: df0270af2ec4f4ad64474a778f5d9b2731d4cce9
Parents: ee4573b
Author: Matt Sicker <bo...@gmail.com>
Authored: Wed Mar 2 22:32:31 2016 -0600
Committer: Matt Sicker <bo...@gmail.com>
Committed: Wed Mar 2 22:32:31 2016 -0600

----------------------------------------------------------------------
 .../log4j/core/pattern/MaxLengthConverter.java  | 103 +++++++++++++++++++
 .../core/pattern/MaxLengthConverterTest.java    |  73 +++++++++++++
 src/changes/changes.xml                         |   3 +
 src/site/xdoc/manual/layouts.xml.vm             |  38 +++++++
 4 files changed, 217 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/df0270af/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MaxLengthConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MaxLengthConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MaxLengthConverter.java
new file mode 100644
index 0000000..ca053f2
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MaxLengthConverter.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.pattern;
+
+import java.util.List;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+
+/**
+ * Max length pattern converter. Limit contained text to a maximum length.
+ * On invalid length the default value 100 is used (and an error message is logged).
+ * If max length is greater than 20, an abbreviated text will get ellipsis ("...") appended.
+ * Example usage (for email subject):
+ * {@code "%maxLen{[AppName, ${hostName}, ${web:contextPath}] %p: %c{1} - %m%notEmpty{ =>%ex{short}}}{160}"}
+ *
+ * @author Thies Wellpott
+ */
+@Plugin(name = "maxLength", category = PatternConverter.CATEGORY)
+@ConverterKeys({"maxLength", "maxLen"})
+public final class MaxLengthConverter extends LogEventPatternConverter {
+
+    /**
+     * Gets an instance of the class.
+     *
+     * @param config  The current Configuration.
+     * @param options pattern options, an array of two elements: pattern, max length (defaults to 100 on invalid value).
+     * @return instance of class.
+     */
+    public static MaxLengthConverter newInstance(final Configuration config, final String[] options) {
+        if (options.length != 2) {
+            LOGGER.error("Incorrect number of options on maxLength: expected 2 received {}: {}", options.length,
+                options);
+            return null;
+        }
+        if (options[0] == null) {
+            LOGGER.error("No pattern supplied on maxLength");
+            return null;
+        }
+        if (options[1] == null) {
+            LOGGER.error("No length supplied on maxLength");
+            return null;
+        }
+        final PatternParser parser = PatternLayout.createPatternParser(config);
+        final List<PatternFormatter> formatters = parser.parse(options[0]);
+        return new MaxLengthConverter(formatters, AbstractAppender.parseInt(options[1], 100));
+    }
+
+
+    private final List<PatternFormatter> formatters;
+    private final int maxLength;
+
+    /**
+     * Construct the converter.
+     *
+     * @param formatters The PatternFormatters to generate the text to manipulate.
+     * @param maxLength  The max. length of the resulting string. Ellipsis ("...") is appended on shorted string, if greater than 20.
+     */
+    private MaxLengthConverter(final List<PatternFormatter> formatters, final int maxLength) {
+        super("MaxLength", "maxLength");
+        this.maxLength = maxLength;
+        this.formatters = formatters;
+        LOGGER.trace("new MaxLengthConverter with {}", maxLength);
+    }
+
+
+    @Override
+    public void format(final LogEvent event, final StringBuilder toAppendTo) {
+        final StringBuilder buf = new StringBuilder();
+        for (final PatternFormatter formatter : formatters) {
+            formatter.format(event, buf);
+            if (buf.length() > maxLength) {        // stop early
+                break;
+            }
+        }
+        if (buf.length() > maxLength) {
+            buf.setLength(maxLength);
+            if (maxLength > 20) {        // only append ellipses if length is not very short
+                buf.append("...");
+            }
+        }
+        toAppendTo.append(buf);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/df0270af/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MaxLengthConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MaxLengthConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MaxLengthConverterTest.java
new file mode 100644
index 0000000..e379915
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MaxLengthConverterTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.pattern;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class MaxLengthConverterTest {
+
+    private static MaxLengthConverter converter = MaxLengthConverter.newInstance(null, new String[]{"%m", "10"});
+
+    @Test
+    public void testUnderMaxLength() throws Exception {
+        final Message message = new SimpleMessage("0123456789");
+        final LogEvent event = Log4jLogEvent.newBuilder()
+            .setLoggerName("MyLogger")
+            .setLevel(Level.DEBUG)
+            .setMessage(message)
+            .build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        assertEquals("0123456789", sb.toString());
+    }
+
+    @Test
+    public void testOverMaxLength() throws Exception {
+        final Message message = new SimpleMessage("01234567890123456789");
+        final LogEvent event = Log4jLogEvent.newBuilder()
+            .setLoggerName("MyLogger")
+            .setLevel(Level.DEBUG)
+            .setMessage(message)
+            .build();
+        final StringBuilder sb = new StringBuilder();
+        converter.format(event, sb);
+        assertEquals("0123456789", sb.toString());
+    }
+    @Test
+    public void testOverMaxLength21WithEllipsis() throws Exception {
+        final Message message = new SimpleMessage("012345678901234567890123456789");
+        final LogEvent event = Log4jLogEvent.newBuilder()
+            .setLoggerName("MyLogger")
+            .setLevel(Level.DEBUG)
+            .setMessage(message)
+            .build();
+        final StringBuilder sb = new StringBuilder();
+        MaxLengthConverter.newInstance(null, new String[]{"%m", "21"}).format(event, sb);
+        assertEquals("012345678901234567890...", sb.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/df0270af/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index aa6581c..5066c0a 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -190,6 +190,9 @@
       <action issue="LOG4J2-1306" dev="mattsicker" type="update">
         JeroMqAppender should use ShutdownCallbackRegistry instead of runtime hooks.
       </action>
+      <action issue="LOG4J2-1217" dev="mattsicker" type="add" due-to="Thies Wellpott">
+        PatternLayout option to limit length of text.
+      </action>
     </release>
     <release version="2.5" date="2015-12-06" description="GA Release 2.5">
       <action issue="LOG4J2-324" dev="rpopma" type="fix">

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/df0270af/src/site/xdoc/manual/layouts.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/layouts.xml.vm b/src/site/xdoc/manual/layouts.xml.vm
index fa602e4..d193380 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -910,6 +910,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternMap"/>
                 <b>K</b>{key}<br />
                 <b>map</b>{key}<br />
                 <b>MAP</b>{key}
@@ -957,6 +958,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternMessage"/>
                 <b>m</b><br />
                 <b>msg</b><br />
                 <b>message</b>
@@ -977,18 +979,40 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternMarker"/>
                 <b>marker</b>
               </td>
               <td>The full name of the marker, including parents, if one is present.</td>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternMarkerSimpleName"/>
                 <b>markerSimpleName</b>
               </td>
               <td>The simple name of the marker (not including parents), if one is present.</td>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternMaxLength"/>
+                <b>maxLen</b><br/>
+                <b>maxLength</b>
+              </td>
+              <td>
+                <p>
+                  Outputs the result of evaluating the pattern and truncating the result. If the length is greater
+                  than 20, then the output will contain a trailing ellipsis. If the provided length is invalid, a
+                  default value of 100 is used.
+                </p>
+                <p>
+                  Example syntax: <code>%maxLen{%p: %c{1} - %m%notEmpty{ =>%ex{short}}}{160}</code> will be limited to
+                  160 characters with a trailing ellipsis. Another example: <code>%maxLen{%m}{20}</code> will be
+                  limited to 20 characters and no trailing ellipsis.
+                </p>
+              </td>
+            </tr>
+            <tr>
+              <td align="center">
+                <a name="PatternNewLine"/>
                 <b>n</b>
               </td>
               <td>
@@ -1029,6 +1053,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternLevel"/>
                 <b>p</b>|<b>level</b>{<em>level</em>=<em>label</em>, <em>level</em>=<em>label</em>, ...}
                 <b>p</b>|<b>level</b>{length=<em>n</em>}
                 <b>p</b>|<b>level</b>{lowerCase=<em>true</em>|<em>false</em>}
@@ -1065,6 +1090,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternRelative"/>
                 <b>r</b><br />
                 <b>relative</b>
               </td>
@@ -1074,6 +1100,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternReplace"/>
                 <b>replace</b>{pattern}{regex}{substitution}
               </td>
               <td>
@@ -1089,6 +1116,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternException"/>
                 <b>rEx</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
                 <b>rException</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
                 <b>rThrowable</b>["none"|"short"|"full"|depth],[filters(packages)}
@@ -1109,6 +1137,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternSequenceNumber"/>
                 <b>sn</b><br />
                 <b>sequenceNumber</b>
               </td>
@@ -1118,6 +1147,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternStyle"/>
                 <b>style</b>{pattern}{ANSI style}
               </td>
               <td>
@@ -1239,6 +1269,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternThreadId"/>
                 <b>T</b><br />
                 <b>tid</b><br />
                 <b>threadId</b>
@@ -1247,6 +1278,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternThreadName"/>
                 <b>t</b><br />
                 <b>thread</b><br />
                 <b>threadName</b>
@@ -1255,6 +1287,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternThreadPriority"/>
                 <b>tp</b><br />
                 <b>threadPriority</b>
               </td>
@@ -1262,6 +1295,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternNDC"/>
                 <b>x</b><br />
                 <b>NDC</b>
               </td>
@@ -1271,6 +1305,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternMDC"/>
                 <b>X</b>{key[,key2...]}<br />
                 <b>mdc</b>{key[,key2...]}<br />
                 <b>MDC</b>{key[,key2...]}
@@ -1300,6 +1335,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternUUID"/>
                 <b>u</b>{"RANDOM" | "TIME"}<br />
                 <b>uuid</b>
               </td>
@@ -1314,6 +1350,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternExtendedException"/>
                 <b>xEx</b>{"none"|"short"|"full"|depth],[filters(packages)}<br />
                 <b>xException</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
                 <b>xThrowable</b>["none"|"short"|"full"|depth],[filters(packages)}
@@ -1338,6 +1375,7 @@ WARN  [main]: Message 2</pre>
             </tr>
             <tr>
               <td align="center">
+                <a name="PatternPercentLiteral"/>
                 <b>%</b>
               </td>
               <td>The sequence %% outputs a single percent sign.