[ 
https://issues.apache.org/jira/browse/LOG4J2-151?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13553617#comment-13553617
 ] 

Remko Popma edited comment on LOG4J2-151 at 1/16/13 1:25 PM:
-------------------------------------------------------------

I'm planning to use the LMAX Disruptor library 
(http://lmax-exchange.github.com/disruptor/).
To pass on data to the thread that does the actual logging, I use a similar 
approach as LogEventProxy, with one difference that Disruptor pre-allocates the 
event objects, to avoid creating a new event instance for every call to 
Logger.log() on the publisher (application) side. (The Log4jLogEvent instance 
is created on the event handling thread on the consumer side.)

I do pass on the context map using (ThreadContext.isEmpty() ? null : 
ThreadContext.getImmutableContext())
and may pass on the stack too with (ThreadContext.getDepth() == 0 ? null : 
ThreadContext.cloneStack())
because these are fairly cheap.
However, not calculating Log4jLogEvent.location is a big performance win.

This is still a work in progress, but preliminary tests show it is possible to 
get to 450 nanos per call to Logger.log.
I may be able to get it down to 150 nanos by always passing a null context map 
and stack and using a custom clock implementation instead of 
System.currentTimeMillis().

(Side note: In my application I don't need the location or the stack so I can 
save time by leaving out this information unconditionally.
For a more general solution it would be nice if the Logger would somehow be 
able to find out if any of the appenders has a layout where stack, context map 
or location is used. The logger could then include this information only if 
necessary.)
                
      was (Author: rem...@yahoo.com):
    I'm planning to use the LMAX Disruptor library 
(http://lmax-exchange.github.com/disruptor/).
To pass on data to the thread that does the actual logging, I use a similar 
approach as LogEventProxy, with one difference that Disruptor pre-allocates the 
event objects, to avoid creating a new event instance for every call to 
Logger.log() on the publisher (application) side. (The Log4jLogEvent instance 
is created on the event handling thread on the consumer side.)

I do pass on the context map using (ThreadContext.isEmpty() ? null : 
ThreadContext.getImmutableContext())
and may pass on the stack too with (ThreadContext.getDepth() == 0 ? null : 
ThreadContext.cloneStack())
because these are fairly cheap.
However, not calculating Log4jLogEvent.location is a big performance win.

This is still a work in progress, but preliminary tests show it is possible to 
get to 450 nanos per call to Logger.log.
I may be able to get it down to 150 nanos by always passing a null stack and 
using a custom clock implementation instead of System.currentTimeMillis().

(Side note: In my application I don't need the location or the stack so I can 
save time by leaving out this information unconditionally.
For a more general solution it would be nice if the Logger would somehow be 
able to find out if any of the appenders has a layout where stack, context map 
or location is used. The logger could then include this information only if 
necessary.)
                  
> Please facilitate subclassing Logger and LoggerContext (in 
> org.apache.logging.log4j.core)
> -----------------------------------------------------------------------------------------
>
>                 Key: LOG4J2-151
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-151
>             Project: Log4j 2
>          Issue Type: New Feature
>          Components: Core
>    Affects Versions: 2.0-beta3
>            Reporter: Remko Popma
>
> I would like to create a custom logger, while reusing the 
> org.apache.logging.log4j.core.Logger functionality.
> The following two changes would make subclassing possible:
> * change visibility of method Logger$PrivateConfig#logEvent(LogEvent) (line 
> 265) from protected to public
> * change visibility of method LoggerContext#newInstance(LoggerContext, 
> String) (line 310) from private to protected
> My use case is that I want to create an asynchronous Logger for low latency 
> logging.
> This custom logger hands off control to a separate thread as early as 
> possible. In my case, AsynchAppender is not a good match for my requirements, 
> as with that approach (a) the logging call still needs to flow down the 
> hierarchy to the appender, doing synchronization and creating objects at 
> various points on the way, and (b) when serializing the LogEvent, the 
> getSource() method is always called, which is expensive.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-dev-h...@logging.apache.org

Reply via email to