Hang on! Doesn't this have large performance impact?
You're creating the ThrowableProxy, with all the reflection and stack trace
walking etc in the critical path - in the application thread that calls
Logger.log(msg, ex). So we're always paying the cost of constructing an
(expensive) ThrowableProxy, but how often is it actually used?

Can't we create a ThrowableProxy only when it is needed? And for async
loggers/appenders, do the construction in the consumer thread instead?
The simplest way to do this would be to keep the instance variable a normal
Throwable, and only construct and return a new ThrownProxy(thrown) when the
event.getThrownProxy() method is called. That should be the implementation
for all LogEvent implementation classes IMHO.

Remko



On Sat, May 10, 2014 at 4:16 AM, <ggreg...@apache.org> wrote:

> Author: ggregory
> Date: Fri May  9 19:16:53 2014
> New Revision: 1593598
>
> URL: http://svn.apache.org/r1593598
> Log:
> The RingBufferLogEvent should track a ThrowableProxy instead of a
> Throwable. This relates to the application listening side of Log4j events
> from a JSON or XML source (another app in another JVM).
>
> 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/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=1593598&r1=1593597&r2=1593598&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  9 19:16:53 2014
> @@ -30,6 +30,7 @@ import org.apache.logging.log4j.core.hel
>  import org.apache.logging.log4j.core.helpers.ClockFactory;
>  import org.apache.logging.log4j.core.helpers.Loader;
>  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.message.Message;
>  import org.apache.logging.log4j.message.MessageFactory;
> @@ -224,7 +225,7 @@ public class AsyncLogger extends Logger
>      }
>
>      @Override
> -    public void logMessage(final String fqcn, final Level level, final
> Marker marker, final Message message, final Throwable t) {
> +    public void logMessage(final String fqcn, final Level level, final
> Marker marker, final Message message, final Throwable thrown) {
>          Info info = threadlocalInfo.get();
>          if (info == null) {
>              info = new Info(new RingBufferLogEventTranslator(),
> Thread.currentThread().getName(), false);
> @@ -235,11 +236,13 @@ public class AsyncLogger extends Logger
>          // being logged calls Logger.log() from its toString() method
>          if (info.isAppenderThread &&
> disruptor.getRingBuffer().remainingCapacity() == 0) {
>              // bypass RingBuffer and invoke Appender directly
> -            config.loggerConfig.log(getName(), fqcn, marker, level,
> message, t);
> +            config.loggerConfig.log(getName(), fqcn, marker, level,
> message, thrown);
>              return;
>          }
>          final boolean includeLocation =
> config.loggerConfig.isIncludeLocation();
> -        info.translator.setValues(this, getName(), marker, fqcn, level,
> message, t, //
> +        info.translator.setValues(this, getName(), marker, fqcn, level,
> message, //
> +                // thrown proxy or null
> +                thrown == null ? null : new ThrowableProxy(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=1593598&r1=1593597&r2=1593598&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  9 19:16:53 2014
> @@ -59,8 +59,7 @@ public class RingBufferLogEvent implemen
>         private String fqcn;
>         private Level level;
>         private Message message;
> -       // TODO: Need to track a ThrowableProxy instead of a Throwable.
> -       private Throwable thrown;
> +       private ThrowableProxy thrownProxy;
>         private Map<String, String> contextMap;
>         private ContextStack contextStack;
>         private String threadName;
> @@ -71,7 +70,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
> Throwable t,
> +                       final Level level, final Message data, final
> ThrowableProxy throwableProxy,
>                         final Map<String, String> map, final ContextStack
> contextStack,
>                         final String threadName, final StackTraceElement
> location,
>                         final long currentTimeMillis) {
> @@ -81,7 +80,7 @@ public class RingBufferLogEvent implemen
>                 this.fqcn = fqcn;
>                 this.level = level;
>                 this.message = data;
> -               this.thrown = t;
> +               this.thrownProxy = throwableProxy;
>                 this.contextMap = map;
>                 this.contextStack = contextStack;
>                 this.threadName = threadName;
> @@ -162,12 +161,12 @@ public class RingBufferLogEvent implemen
>
>         @Override
>         public Throwable getThrown() {
> -               return thrown;
> +               return thrownProxy == null ? null :
> thrownProxy.getThrowable();
>         }
>
>         @Override
>         public ThrowableProxy getThrownProxy() {
> -               return new ThrowableProxy(this.thrown);
> +               return this.thrownProxy;
>         }
>
>         @Override
>
> 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=1593598&r1=1593597&r2=1593598&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  9 19:16:53 2014
> @@ -21,6 +21,7 @@ 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;
> @@ -40,7 +41,7 @@ public class RingBufferLogEventTranslato
>      private String fqcn;
>      private Level level;
>      private Message message;
> -    private Throwable thrown;
> +    private ThrowableProxy thrownProxy;
>      private Map<String, String> contextMap;
>      private ContextStack contextStack;
>      private String threadName;
> @@ -51,7 +52,7 @@ public class RingBufferLogEventTranslato
>      @Override
>      public void translateTo(final RingBufferLogEvent event, final long
> sequence) {
>          event.setValues(asyncLogger, loggerName, marker, fqcn, level,
> message,
> -                thrown, contextMap, contextStack, threadName, location,
> +                thrownProxy, contextMap, contextStack, threadName,
> location,
>                  currentTimeMillis);
>          clear();
>      }
> @@ -78,7 +79,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 Throwable thrown, final Map<String, String> contextMap,
> +            final ThrowableProxy thrownProxy, final Map<String, String>
> contextMap,
>              final ContextStack contextStack, final String threadName,
>              final StackTraceElement location, final long
> currentTimeMillis) {
>          this.asyncLogger = asyncLogger;
> @@ -87,7 +88,7 @@ public class RingBufferLogEventTranslato
>          this.fqcn = fqcn;
>          this.level = level;
>          this.message = message;
> -        this.thrown = thrown;
> +        this.thrownProxy = thrownProxy;
>          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/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=1593598&r1=1593597&r2=1593598&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  9 19:16:53 2014
> @@ -24,6 +24,7 @@ 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 org.apache.logging.log4j.message.TimestampMessage;
>  import org.junit.Test;
> @@ -41,7 +42,7 @@ public class RingBufferLogEventTest {
>          String fqcn = null;
>          Level level = null;
>          Message data = null;
> -        Throwable t = null;
> +        ThrowableProxy t = null;
>          Map<String, String> map = null;
>          ContextStack contextStack = null;
>          String threadName = null;
> @@ -60,7 +61,7 @@ public class RingBufferLogEventTest {
>          String fqcn = null;
>          Level level = null;
>          Message data = null;
> -        Throwable t = null;
> +        ThrowableProxy t = null;
>          Map<String, String> map = null;
>          ContextStack contextStack = null;
>          String threadName = null;
> @@ -79,7 +80,7 @@ public class RingBufferLogEventTest {
>          String fqcn = null;
>          Level level = null;
>          Message data = null;
> -        Throwable t = null;
> +        ThrowableProxy t = null;
>          Map<String, String> map = null;
>          ContextStack contextStack = null;
>          String threadName = null;
> @@ -134,7 +135,7 @@ public class RingBufferLogEventTest {
>          String fqcn = null;
>          Level level = null;
>          Message data = new TimeMsg("", 567);
> -        Throwable t = null;
> +        ThrowableProxy t = null;
>          Map<String, String> map = null;
>          ContextStack contextStack = null;
>          String threadName = null;
>
>
>

Reply via email to