You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2016/08/03 11:34:02 UTC
[12/28] logging-log4j2 git commit: LOG4J2-1341 (GC)
HighlightConverter and StyleConverter are now GC-free.
LOG4J2-1341 (GC) HighlightConverter and StyleConverter are now GC-free.
This closes GitHub pull request #34 (https://github.com/apache/logging-log4j2/pull/34).
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/c4af088d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/c4af088d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/c4af088d
Branch: refs/heads/LOG4J-1181
Commit: c4af088d7d0a181f4e9b84f401bd56f2e1342797
Parents: 8529086
Author: rpopma <rp...@apache.org>
Authored: Sun Jul 31 14:43:14 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sun Jul 31 14:43:14 2016 +0900
----------------------------------------------------------------------
.../log4j/core/pattern/HighlightConverter.java | 37 ++++++----
.../log4j/core/pattern/StyleConverter.java | 24 ++++--
.../core/pattern/HighlightConverterTest.java | 78 ++++++++++++++++++++
log4j-core/src/test/resources/gcFreeLogging.xml | 10 +--
.../resources/gcFreeMixedSyncAsyncLogging.xml | 10 +--
log4j-core/src/test/resources/log4j-style.xml | 4 +-
src/changes/changes.xml | 5 +-
src/site/xdoc/manual/garbagefree.xml | 10 ++-
8 files changed, 143 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
index 0e2f63d..c0ab673 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/HighlightConverter.java
@@ -34,14 +34,14 @@ import org.apache.logging.log4j.util.Strings;
* <p>
* For example:
* </p>
- *
+ *
* <pre>
* %highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}
* </pre>
* <p>
* You can define custom colors for each Level:
* </p>
- *
+ *
* <pre>
* %highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}{FATAL=red, ERROR=red, WARN=yellow, INFO=green, DEBUG=cyan,
* TRACE=black}
@@ -49,9 +49,9 @@ import org.apache.logging.log4j.util.Strings;
* <p>
* You can use a predefined style:
* </p>
- *
+ *
* <pre>
- * %highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}{STYLE=Log4j}
+ * %highlight{%d{ ISO8601 } [%t] %-5level: %msg%n%throwable}{STYLE=DEFAULT}
* </pre>
* <p>
* The available predefined styles are:
@@ -108,7 +108,7 @@ public final class HighlightConverter extends LogEventPatternConverter implement
* <p>
* The format of the option string in {@code option[1]} is:
* </p>
- *
+ *
* <pre>
* Level1=Value, Level2=Value, ...
* </pre>
@@ -193,6 +193,8 @@ public final class HighlightConverter extends LogEventPatternConverter implement
private final boolean noAnsi;
+ private final String defaultStyle;
+
/**
* Construct the converter.
*
@@ -205,6 +207,7 @@ public final class HighlightConverter extends LogEventPatternConverter implement
super("style", "style");
this.patternFormatters = patternFormatters;
this.levelStyles = levelStyles;
+ this.defaultStyle = AnsiEscape.getDefaultStyle();
this.noAnsi = noAnsi;
}
@@ -213,17 +216,25 @@ public final class HighlightConverter extends LogEventPatternConverter implement
*/
@Override
public void format(final LogEvent event, final StringBuilder toAppendTo) {
- final StringBuilder buf = new StringBuilder();
- for (final PatternFormatter formatter : patternFormatters) {
- formatter.format(event, buf);
+ final int start = toAppendTo.length();
+ int end = 0;
+ if (!noAnsi) { // use ANSI: set prefix
+ toAppendTo.append(levelStyles.get(event.getLevel()));
+ end = toAppendTo.length();
+ }
+
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0, size = patternFormatters.size(); i < size; i++) {
+ patternFormatters.get(i).format(event, toAppendTo);
}
- if (buf.length() > 0) {
- if (noAnsi) {
- toAppendTo.append(buf.toString());
+ // if we use ANSI we need to add the postfix or erase the unnecessary prefix
+ final boolean empty = toAppendTo.length() == end;
+ if (!noAnsi) {
+ if (empty) {
+ toAppendTo.setLength(start); // erase prefix
} else {
- toAppendTo.append(levelStyles.get(event.getLevel())).append(buf.toString()).
- append(AnsiEscape.getDefaultStyle());
+ toAppendTo.append(defaultStyle); // add postfix
}
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/StyleConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/StyleConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/StyleConverter.java
index 202d771..0d8c730 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/StyleConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/StyleConverter.java
@@ -94,17 +94,25 @@ public final class StyleConverter extends LogEventPatternConverter implements An
*/
@Override
public void format(final LogEvent event, final StringBuilder toAppendTo) {
- final StringBuilder buf = new StringBuilder();
- for (final PatternFormatter formatter : patternFormatters) {
- formatter.format(event, buf);
+ int start = 0;
+ int end = 0;
+ if (!noAnsi) { // use ANSI: set prefix
+ start = toAppendTo.length();
+ toAppendTo.append(style);
+ end = toAppendTo.length();
+ }
+
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0, size = patternFormatters.size(); i < size; i++) {
+ patternFormatters.get(i).format(event, toAppendTo);
}
- if (buf.length() > 0) {
- if (noAnsi) {
- // faster to test and do this than setting style and defaultStyle to empty strings.
- toAppendTo.append(buf.toString());
+ // if we use ANSI we need to add the postfix or erase the unnecessary prefix
+ if (!noAnsi) {
+ if (toAppendTo.length() == end) {
+ toAppendTo.setLength(start); // erase prefix
} else {
- toAppendTo.append(style).append(buf.toString()).append(defaultStyle);
+ toAppendTo.append(defaultStyle); // add postfix
}
}
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
new file mode 100644
index 0000000..6051f85
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
@@ -0,0 +1,78 @@
+package org.apache.logging.log4j.core.pattern;/*
+ * 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.
+ */
+
+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.SimpleMessage;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the HighlightConverter.
+ */
+public class HighlightConverterTest {
+
+ @Test
+ public void testAnsiEmpty() {
+ final String[] options = {"", PatternParser.NO_CONSOLE_NO_ANSI + "=false"};
+ final HighlightConverter converter = HighlightConverter.newInstance(null, options);
+
+ final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
+ new SimpleMessage("message in a bottle")).build();
+ final StringBuilder buffer = new StringBuilder();
+ converter.format(event, buffer);
+ assertEquals("", buffer.toString());
+ }
+
+ @Test
+ public void testAnsiNonEmpty() {
+ final String[] options = {"%-5level: %msg", PatternParser.NO_CONSOLE_NO_ANSI + "=false"};
+ final HighlightConverter converter = HighlightConverter.newInstance(null, options);
+
+ final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
+ new SimpleMessage("message in a bottle")).build();
+ final StringBuilder buffer = new StringBuilder();
+ converter.format(event, buffer);
+ assertEquals("\u001B[32mINFO : message in a bottle\u001B[m", buffer.toString());
+ }
+
+ @Test
+ public void testNoAnsiEmpty() {
+ final String[] options = {"", PatternParser.NO_CONSOLE_NO_ANSI + "=true"};
+ final HighlightConverter converter = HighlightConverter.newInstance(null, options);
+
+ final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
+ new SimpleMessage("message in a bottle")).build();
+ final StringBuilder buffer = new StringBuilder();
+ converter.format(event, buffer);
+ assertEquals("", buffer.toString());
+ }
+
+ @Test
+ public void testNoAnsiNonEmpty() {
+ final String[] options = {"%-5level: %msg", PatternParser.NO_CONSOLE_NO_ANSI + "=true"};
+ final HighlightConverter converter = HighlightConverter.newInstance(null, options);
+
+ final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
+ new SimpleMessage("message in a bottle")).build();
+ final StringBuilder buffer = new StringBuilder();
+ converter.format(event, buffer);
+ assertEquals("INFO : message in a bottle", buffer.toString());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/log4j-core/src/test/resources/gcFreeLogging.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/gcFreeLogging.xml b/log4j-core/src/test/resources/gcFreeLogging.xml
index f90d754..8893466 100644
--- a/log4j-core/src/test/resources/gcFreeLogging.xml
+++ b/log4j-core/src/test/resources/gcFreeLogging.xml
@@ -6,13 +6,13 @@
</Console>
<File name="File" fileName="target/gcfreefile.log" bufferedIO="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %m%n}</Pattern>
</PatternLayout>
</File>
<RollingFile name="RollingFile" fileName="target/gcfreeRollingFile.log"
filePattern="target/gcfree-%d{MM-dd-yy-HH-mm-ss}.log.gz">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %m%n}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50M" />
@@ -20,7 +20,7 @@
</RollingFile>
<RandomAccessFile name="RandomAccessFile" fileName="target/gcfreeRAF.log" immediateFlush="false" append="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %X{aKey} %m %ex%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %X{aKey} %m %ex%n}</Pattern>
</PatternLayout>
</RandomAccessFile>
<RollingRandomAccessFile name="RollingRandomAccessFile"
@@ -28,7 +28,7 @@
filePattern="target/afterRollover-%i.log" append="false"
immediateFlush="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %X{aKey} %m %location %ex%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %X{aKey} %m %location %ex%n}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50 M"/>
@@ -38,7 +38,7 @@
fileName="target/gcfreemmap.log"
immediateFlush="false" append="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %X{aKey} %m%ex%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %X{aKey} %m%ex%n}</Pattern>
</PatternLayout>
</MemoryMappedFile>
<RandomAccessFile name="RandomAccessFileGelf" fileName="target/gcfree.json" immediateFlush="false" append="false">
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/log4j-core/src/test/resources/gcFreeMixedSyncAsyncLogging.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/gcFreeMixedSyncAsyncLogging.xml b/log4j-core/src/test/resources/gcFreeMixedSyncAsyncLogging.xml
index e4c0000..50bff57 100644
--- a/log4j-core/src/test/resources/gcFreeMixedSyncAsyncLogging.xml
+++ b/log4j-core/src/test/resources/gcFreeMixedSyncAsyncLogging.xml
@@ -6,13 +6,13 @@
</Console>
<File name="File" fileName="target/gcfreefileMixed.log" bufferedIO="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %m%n}</Pattern>
</PatternLayout>
</File>
<RollingFile name="RollingFile" fileName="target/gcfreeRollingFileMixed.log"
filePattern="target/gcfree-%d{MM-dd-yy-HH-mm-ss}.log.gz">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %m%n}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50M" />
@@ -20,7 +20,7 @@
</RollingFile>
<RandomAccessFile name="RandomAccessFile" fileName="target/gcfreeRAFMixed.log" immediateFlush="false" append="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %X{aKey} %m %ex%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %X{aKey} %m %ex%n}</Pattern>
</PatternLayout>
</RandomAccessFile>
<RollingRandomAccessFile name="RollingRandomAccessFile"
@@ -28,7 +28,7 @@
filePattern="target/afterRollover-%i.log" append="false"
immediateFlush="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %X{aKey} %m %location %ex%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %X{aKey} %m %location %ex%n}</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50 M"/>
@@ -38,7 +38,7 @@
fileName="target/gcfreemmapMixed.log"
immediateFlush="false" append="false">
<PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %X{aKey} %m%ex%n</Pattern>
+ <Pattern>%highlight{%style{%d}{bright,cyan} %p %c{1.} [%t] %X{aKey} %m%ex%n}</Pattern>
</PatternLayout>
</MemoryMappedFile>
<RandomAccessFile name="RandomAccessFileGelf" fileName="target/gcfreeMixed.json" immediateFlush="false" append="false">
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/log4j-core/src/test/resources/log4j-style.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-style.xml b/log4j-core/src/test/resources/log4j-style.xml
index 9b18b37..6acf873 100644
--- a/log4j-core/src/test/resources/log4j-style.xml
+++ b/log4j-core/src/test/resources/log4j-style.xml
@@ -20,7 +20,7 @@
<Appenders>
<List name="List">
<PatternLayout>
- <Pattern>%d %highlight{%p} %style{%logger}{bright,cyan} %C{1.} %msg%n</Pattern>
+ <Pattern>%d %highlight{%p} %style{%logger}{bright,cyan}%style{}{bright,cyan} %C{1.} %msg%n</Pattern>
</PatternLayout>
</List>
</Appenders>
@@ -31,4 +31,4 @@
</Root>
</Loggers>
-</Configuration>
\ No newline at end of file
+</Configuration>
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 8ec3453..25d4b07 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -23,7 +23,10 @@
<title>Changes</title>
</properties>
<body>
- <release version="2.7.0" date="2016-MM-DD" description="GA Release 2.7.0">
+ <release version="2.7" date="2016-MM-DD" description="GA Release 2.7.0">
+ <action issue="LOG4J2-1341" dev="rpopma" type="fix" due-to="Richard Zschech">
+ (GC) HighlightConverter and StyleConverter are now GC-free.
+ </action>
<action issue="LOG4J2-1467" dev="rpopma, ggregory" type="fix" due-to="Ralf, Gary Gregory">
[OSGi] Missing import package.
</action>
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/c4af088d/src/site/xdoc/manual/garbagefree.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/garbagefree.xml b/src/site/xdoc/manual/garbagefree.xml
index 58ca1d0..46499d5 100644
--- a/src/site/xdoc/manual/garbagefree.xml
+++ b/src/site/xdoc/manual/garbagefree.xml
@@ -234,6 +234,14 @@
</td>
</tr>
<tr>
+ <td>%highlight{pattern}{style}</td>
+ <td>Adds ANSI colors (unless nested pattern is not garbage free)</td>
+ </tr>
+ <tr>
+ <td>style{pattern}{ANSI style}</td>
+ <td>Style the message (unless nested pattern is not garbage free)</td>
+ </tr>
+ <tr>
<td>%m, %msg, %message</td>
<td>Log message (unless message text contains '${')</td>
</tr>
@@ -501,4 +509,4 @@ public void garbageFree() {
</subsection>
</section>
</body>
-</document>
\ No newline at end of file
+</document>