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/04/05 13:58:22 UTC

logging-log4j2 git commit: GC free GelfLayout

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-1356 [created] dce9b623d


GC free GelfLayout


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

Branch: refs/heads/LOG4J2-1356
Commit: dce9b623db47e34b0ce41718fdcecbb74b981434
Parents: e1b3f4c
Author: Mikael Ståldal <mi...@magine.com>
Authored: Tue Apr 5 13:58:14 2016 +0200
Committer: Mikael Ståldal <mi...@magine.com>
Committed: Tue Apr 5 13:58:14 2016 +0200

----------------------------------------------------------------------
 .../logging/log4j/core/layout/GelfLayout.java   | 67 +++++++++++++++-----
 log4j-core/src/test/resources/gcFreeLogging.xml |  4 +-
 pom.xml                                         |  6 +-
 3 files changed, 55 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dce9b623/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
index 084eae8..424cfff 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java
@@ -28,7 +28,9 @@ import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.core.net.Severity;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.core.util.KeyValuePair;
+import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.StringBuilderFormattable;
 import org.apache.logging.log4j.util.Strings;
 
 import java.io.*;
@@ -135,7 +137,7 @@ public final class GelfLayout extends AbstractStringLayout {
 
     @Override
     public byte[] toByteArray(final LogEvent event) {
-        StringBuilder text = toText(event, getStringBuilder());
+        StringBuilder text = toText(event, getStringBuilder(), false);
         final byte[] bytes = getBytes(text.toString());
         return compressionType != CompressionType.OFF && bytes.length > compressionThreshold ? compress(bytes) : bytes;
     }
@@ -146,7 +148,7 @@ public final class GelfLayout extends AbstractStringLayout {
             super.encode(event, destination);
             return;
         }
-        final StringBuilder text = toText(event, getStringBuilder());
+        final StringBuilder text = toText(event, getStringBuilder(), true);
         final TextEncoderHelper helper = getCachedTextEncoderHelper();
         helper.encodeText(text, destination);
     }
@@ -170,44 +172,77 @@ public final class GelfLayout extends AbstractStringLayout {
 
     @Override
     public String toSerializable(final LogEvent event) {
-        final StringBuilder text = toText(event, getStringBuilder());
+        final StringBuilder text = toText(event, getStringBuilder(), false);
         return text.toString();
     }
 
-    private StringBuilder toText(LogEvent event, StringBuilder builder) {
+    private StringBuilder toText(LogEvent event, StringBuilder builder, boolean gcFree) {
         final JsonStringEncoder jsonEncoder = JsonStringEncoder.getInstance();
         builder.append('{');
         builder.append("\"version\":\"1.1\",");
-        builder.append("\"host\":\"").append(jsonEncoder.quoteAsString(toNullSafeString(host))).append(QC);
+        builder.append("\"host\":\"");
+        jsonEncoder.quoteAsString(toNullSafeString(host), builder);
+        builder.append(QC);
         builder.append("\"timestamp\":").append(formatTimestamp(event.getTimeMillis())).append(C);
         builder.append("\"level\":").append(formatLevel(event.getLevel())).append(C);
         if (event.getThreadName() != null) {
-            builder.append("\"_thread\":\"").append(jsonEncoder.quoteAsString(event.getThreadName())).append(QC);
+            builder.append("\"_thread\":\"");
+            jsonEncoder.quoteAsString(event.getThreadName(), builder);
+            builder.append(QC);
         }
         if (event.getLoggerName() != null) {
-            builder.append("\"_logger\":\"").append(jsonEncoder.quoteAsString(event.getLoggerName())).append(QC);
+            builder.append("\"_logger\":\"");
+            jsonEncoder.quoteAsString(event.getLoggerName(), builder);
+            builder.append(QC);
         }
 
         for (final KeyValuePair additionalField : additionalFields) {
-            builder.append(QU).append(jsonEncoder.quoteAsString(additionalField.getKey())).append("\":\"")
-                    .append(jsonEncoder.quoteAsString(toNullSafeString(additionalField.getValue()))).append(QC);
+            builder.append(QU);
+            jsonEncoder.quoteAsString(additionalField.getKey(), builder);
+            builder.append("\":\"");
+            jsonEncoder.quoteAsString(toNullSafeString(additionalField.getValue()), builder);
+            builder.append(QC);
         }
         for (final Map.Entry<String, String> entry : event.getContextMap().entrySet()) {
-            builder.append(QU).append(jsonEncoder.quoteAsString(entry.getKey())).append("\":\"")
-                    .append(jsonEncoder.quoteAsString(toNullSafeString(entry.getValue()))).append(QC);
+            builder.append(QU);
+            jsonEncoder.quoteAsString(entry.getKey(), builder);
+            builder.append("\":\"");
+            jsonEncoder.quoteAsString(toNullSafeString(entry.getValue()), builder);
+            builder.append(QC);
         }
         if (event.getThrown() != null) {
-            builder.append("\"full_message\":\"").append(jsonEncoder.quoteAsString(formatThrowable(event.getThrown())))
-                    .append(QC);
+            builder.append("\"full_message\":\"");
+            jsonEncoder.quoteAsString(formatThrowable(event.getThrown()), builder);
+            builder.append(QC);
         }
 
-        builder.append("\"short_message\":\"").append(jsonEncoder.quoteAsString(toNullSafeString(event.getMessage().getFormattedMessage())))
-                .append(Q);
+        builder.append("\"short_message\":\"");
+        Message message = event.getMessage();
+        if (gcFree && message instanceof StringBuilderFormattable) {
+            StringBuilder messageBuffer = getMessageStringBuilder();
+            ((StringBuilderFormattable)message).formatTo(messageBuffer);
+            jsonEncoder.quoteAsString(messageBuffer, builder);
+        } else {
+            jsonEncoder.quoteAsString(toNullSafeString(message.getFormattedMessage()), builder);
+        }
+        builder.append(Q);
         builder.append('}');
         return builder;
     }
 
-    private String toNullSafeString(final String s) {
+    private static final ThreadLocal<StringBuilder> messageStringBuilder = new ThreadLocal<>();
+
+    private static StringBuilder getMessageStringBuilder() {
+        StringBuilder result = messageStringBuilder.get();
+        if (result == null) {
+            result = new StringBuilder(DEFAULT_STRING_BUILDER_SIZE);
+            messageStringBuilder.set(result);
+        }
+        result.setLength(0);
+        return result;
+    }
+
+    private CharSequence toNullSafeString(final CharSequence s) {
         return s == null ? Strings.EMPTY : s;
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dce9b623/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 560c83c..6cf9066 100644
--- a/log4j-core/src/test/resources/gcFreeLogging.xml
+++ b/log4j-core/src/test/resources/gcFreeLogging.xml
@@ -6,16 +6,14 @@
         <Pattern>%d %p %c{1.} [%t] %X{aKey} %m %ex%n</Pattern>
       </PatternLayout>
     </RandomAccessFile>
-<!--
     <RandomAccessFile name="RandomAccessFileGelf" fileName="gcfree.json" immediateFlush="false" append="false">
       <GelfLayout compressionType="OFF"/>
     </RandomAccessFile>
--->
   </Appenders>
   <Loggers>
     <Root level="info" includeLocation="false">
       <appender-ref ref="RandomAccessFilePattern"/>
-      <!-- <appender-ref ref="RandomAccessFileGelf"/> -->
+      <appender-ref ref="RandomAccessFileGelf"/>
     </Root>
   </Loggers>
 </Configuration>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/dce9b623/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b404f29..343bc29 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,7 +190,7 @@
     <slf4jVersion>1.7.13</slf4jVersion>
     <logbackVersion>1.1.3</logbackVersion>
     <jackson1Version>1.9.13</jackson1Version>
-    <jackson2Version>2.7.3</jackson2Version>
+    <jackson2Version>2.8.0-SNAPSHOT</jackson2Version>
     <springVersion>3.2.13.RELEASE</springVersion>
     <flumeVersion>1.6.0</flumeVersion>
     <disruptorVersion>3.3.4</disruptorVersion>
@@ -542,13 +542,13 @@
       <dependency>
         <groupId>com.fasterxml.jackson.dataformat</groupId>
         <artifactId>jackson-dataformat-yaml</artifactId>
-        <version>${jackson2Version}</version>
+        <version>2.7.3</version>
         <optional>true</optional>
       </dependency>
       <dependency>
         <groupId>com.fasterxml.jackson.dataformat</groupId>
         <artifactId>jackson-dataformat-xml</artifactId>
-        <version>${jackson2Version}</version>
+        <version>2.7.3</version>
         <optional>true</optional>
       </dependency>
       <dependency>