[ 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