Author: rpopma
Date: Fri May 16 15:31:02 2014
New Revision: 1595233

URL: http://svn.apache.org/r1595233
Log:
Avoid paying the cost of constructing a ThrowableProxy until it is requested 
because (a) the event is serialized or (b) someone explicitly called 
#getThrowableProxy. (TBD: make similar changes to Log4jLogEvent?)

Modified:
    
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
    
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
    
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
    
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
    
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java

Modified: 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
URL: 
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java?rev=1595233&r1=1595232&r2=1595233&view=diff
==============================================================================
--- 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
 (original)
+++ 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java
 Fri May 16 15:31:02 2014
@@ -27,7 +27,6 @@ import org.apache.logging.log4j.core.Log
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
 import org.apache.logging.log4j.core.util.Clock;
 import org.apache.logging.log4j.core.util.ClockFactory;
@@ -241,8 +240,8 @@ public class AsyncLogger extends Logger 
         }
         final boolean includeLocation = 
config.loggerConfig.isIncludeLocation();
         info.translator.setValues(this, getName(), marker, fqcn, level, 
message, //
-                // thrown proxy or null
-                thrown == null ? null : new ThrowableProxy(thrown), //
+                // don't construct ThrowableProxy until required
+                thrown, //
 
                 // config properties are taken care of in the EventHandler
                 // thread in the #actualAsyncLog method

Modified: 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
URL: 
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java?rev=1595233&r1=1595232&r2=1595233&view=diff
==============================================================================
--- 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
 (original)
+++ 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java
 Fri May 16 15:31:02 2014
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -60,7 +61,8 @@ public class RingBufferLogEvent implemen
        private String fqcn;
        private Level level;
        private Message message;
-       private ThrowableProxy thrownProxy;
+       private transient Throwable thrown;
+    private ThrowableProxy thrownProxy;
        private Map<String, String> contextMap;
        private ContextStack contextStack;
        private String threadName;
@@ -71,7 +73,7 @@ public class RingBufferLogEvent implemen
 
        public void setValues(final AsyncLogger asyncLogger,
                        final String loggerName, final Marker marker, final 
String fqcn,
-                       final Level level, final Message data, final 
ThrowableProxy throwableProxy,
+                       final Level level, final Message data, final Throwable 
throwable,
                        final Map<String, String> map, final ContextStack 
contextStack,
                        final String threadName, final StackTraceElement 
location,
                        final long currentTimeMillis) {
@@ -81,7 +83,8 @@ public class RingBufferLogEvent implemen
                this.fqcn = fqcn;
                this.level = level;
                this.message = data;
-               this.thrownProxy = throwableProxy;
+               this.thrown = throwable;
+               this.thrownProxy = null;
                this.contextMap = map;
                this.contextStack = contextStack;
                this.threadName = threadName;
@@ -162,11 +165,23 @@ public class RingBufferLogEvent implemen
 
        @Override
        public Throwable getThrown() {
-               return thrownProxy == null ? null : thrownProxy.getThrowable();
+           // after deserialization, thrown is null but thrownProxy may be 
non-null
+           if (thrown == null) {
+               if (thrownProxy != null) {
+                   thrown = thrownProxy.getThrowable();
+               }
+           }
+  return thrown;
        }
 
        @Override
        public ThrowableProxy getThrownProxy() {
+           // lazily instantiate the (expensive) ThrowableProxy
+           if (thrownProxy == null) {
+               if (thrown != null) {
+                   thrownProxy = new ThrowableProxy(thrown);
+               }
+           }
                return this.thrownProxy;
        }
 
@@ -250,4 +265,9 @@ public class RingBufferLogEvent implemen
                                0 // currentTimeMillis
                );
        }
+       
+       private void writeObject(java.io.ObjectOutputStream out) throws 
IOException {
+           getThrownProxy(); // initialize the ThrowableProxy before 
serializing
+           out.defaultWriteObject();
+       }
 }

Modified: 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
URL: 
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java?rev=1595233&r1=1595232&r2=1595233&view=diff
==============================================================================
--- 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
 (original)
+++ 
logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEventTranslator.java
 Fri May 16 15:31:02 2014
@@ -21,7 +21,6 @@ import java.util.Map;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
-import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.message.Message;
 
 import com.lmax.disruptor.EventTranslator;
@@ -41,7 +40,7 @@ public class RingBufferLogEventTranslato
     private String fqcn;
     private Level level;
     private Message message;
-    private ThrowableProxy thrownProxy;
+    private Throwable thrown;
     private Map<String, String> contextMap;
     private ContextStack contextStack;
     private String threadName;
@@ -52,7 +51,7 @@ public class RingBufferLogEventTranslato
     @Override
     public void translateTo(final RingBufferLogEvent event, final long 
sequence) {
         event.setValues(asyncLogger, loggerName, marker, fqcn, level, message,
-                thrownProxy, contextMap, contextStack, threadName, location,
+                thrown, contextMap, contextStack, threadName, location,
                 currentTimeMillis);
         clear();
     }
@@ -79,7 +78,7 @@ public class RingBufferLogEventTranslato
 
     public void setValues(final AsyncLogger asyncLogger, final String 
loggerName,
             final Marker marker, final String fqcn, final Level level, final 
Message message,
-            final ThrowableProxy thrownProxy, final Map<String, String> 
contextMap,
+            final Throwable thrown, final Map<String, String> contextMap,
             final ContextStack contextStack, final String threadName,
             final StackTraceElement location, final long currentTimeMillis) {
         this.asyncLogger = asyncLogger;
@@ -88,7 +87,7 @@ public class RingBufferLogEventTranslato
         this.fqcn = fqcn;
         this.level = level;
         this.message = message;
-        this.thrownProxy = thrownProxy;
+        this.thrown = thrown;
         this.contextMap = contextMap;
         this.contextStack = contextStack;
         this.threadName = threadName;

Modified: 
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
URL: 
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java?rev=1595233&r1=1595232&r2=1595233&view=diff
==============================================================================
--- 
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
 (original)
+++ 
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
 Fri May 16 15:31:02 2014
@@ -55,7 +55,7 @@ public class AsyncLoggerTest {
         f.delete();
         final Logger log = LogManager.getLogger("com.foo.Bar");
         final String msg = "Async logger msg";
-        log.info(msg);
+        log.info(msg, new InternalError("this is not a real error"));
         ((LifeCycle) LogManager.getContext()).stop(); // stop async thread
 
         final BufferedReader reader = new BufferedReader(new FileReader(f));

Modified: 
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
URL: 
http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java?rev=1595233&r1=1595232&r2=1595233&view=diff
==============================================================================
--- 
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
 (original)
+++ 
logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
 Fri May 16 15:31:02 2014
@@ -17,9 +17,13 @@
 
 package org.apache.logging.log4j.core.async;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.util.Map;
 
 import org.apache.logging.log4j.Level;
@@ -27,6 +31,7 @@ import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
 import org.apache.logging.log4j.core.impl.ThrowableProxy;
 import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.message.TimestampMessage;
 import org.junit.Test;
 
@@ -43,7 +48,7 @@ public class RingBufferLogEventTest {
         String fqcn = null;
         Level level = null;
         Message data = null;
-        ThrowableProxy t = null;
+        Throwable t = null;
         Map<String, String> map = null;
         ContextStack contextStack = null;
         String threadName = null;
@@ -62,7 +67,7 @@ public class RingBufferLogEventTest {
         String fqcn = null;
         Level level = null;
         Message data = null;
-        ThrowableProxy t = null;
+        Throwable t = null;
         Map<String, String> map = null;
         ContextStack contextStack = null;
         String threadName = null;
@@ -81,7 +86,7 @@ public class RingBufferLogEventTest {
         String fqcn = null;
         Level level = null;
         Message data = null;
-        ThrowableProxy t = null;
+        Throwable t = null;
         Map<String, String> map = null;
         ContextStack contextStack = null;
         String threadName = null;
@@ -136,7 +141,7 @@ public class RingBufferLogEventTest {
         String fqcn = null;
         Level level = null;
         Message data = new TimeMsg("", 567);
-        ThrowableProxy t = null;
+        Throwable t = null;
         Map<String, String> map = null;
         ContextStack contextStack = null;
         String threadName = null;
@@ -147,4 +152,40 @@ public class RingBufferLogEventTest {
         assertEquals(567, evt.getTimeMillis());
     }
 
+    @Test
+    public void testSerializationDeserialization() throws IOException, 
ClassNotFoundException {
+        RingBufferLogEvent evt = new RingBufferLogEvent();
+        String loggerName = "logger.name";
+        Marker marker = null;
+        String fqcn = "f.q.c.n";
+        Level level = Level.TRACE;
+        Message data = new SimpleMessage("message");
+        Throwable t = new InternalError("not a real error");
+        Map<String, String> map = null;
+        ContextStack contextStack = null;
+        String threadName = "main";
+        StackTraceElement location = null;
+        long currentTimeMillis = 12345;
+        evt.setValues(null, loggerName, marker, fqcn, level, data, t, map,
+                contextStack, threadName, location, currentTimeMillis);
+        
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        out.writeObject(evt);
+        
+        ObjectInputStream in = new ObjectInputStream(new 
ByteArrayInputStream(baos.toByteArray()));
+        RingBufferLogEvent other = (RingBufferLogEvent) in.readObject();
+        assertEquals(loggerName, other.getLoggerName());
+        assertEquals(marker, other.getMarker());
+        assertEquals(fqcn, other.getLoggerFQCN());
+        assertEquals(level, other.getLevel());
+        assertEquals(data, other.getMessage());
+        assertNull("null after serialization", other.getThrown());
+        assertEquals(new ThrowableProxy(t), other.getThrownProxy());
+        assertEquals(map, other.getContextMap());
+        assertEquals(contextStack, other.getContextStack());
+        assertEquals(threadName, other.getThreadName());
+        assertEquals(location, other.getSource());
+        assertEquals(currentTimeMillis, other.getTimeMillis());
+    }
 }


Reply via email to