[
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: [email protected]):
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: [email protected]
For additional commands, e-mail: [email protected]