[ https://issues.apache.org/jira/browse/LOG4J2-151?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13555017#comment-13555017 ]
Remko Popma commented on LOG4J2-151: ------------------------------------ Ralph, You were right that the ThreadContext and call stack (location) were tricky when creating an asynchronous logger. For the stack trace problem, I proposed to make an API change to the Layout interface in LOG4J2-153. I realize this impacts quite a few classes, but the performance benefits are large and I don't see any other way to do it in a generic way. The ThreadContext is a different problem, but I believe significant performance gains can be made here as well. In my custom logger I modified ThreadContext to use a copy-on-write mechanism, and this brought copying the ThreadContext down from 200 to 20 nanos. I made a patch for ThreadContext based on the beta-3 source, but I just checked out trunk and found it has changed a lot... Instead, I wrote up the idea in LOG4J2-154, I hope this is still useful... I shaved off an additional 300 nanos by using a custom clock (essentially a class that updates a volatile long field to the value of System.currentTimeMillis in a background thread once every millisecond). Getting the value of that volatile long field is much cheaper than calling System.currentTimeMillis, but you lose some precision. The time increases in increments of 10 milliseconds on Solaris, and 16 milliseconds on Windows. So there is a trade-off here. I'm not sure if it is worth offering this as a standard option in log4j. "useFastButCoarseClock=true", anyone? :-) Finally, using a RandomAccessFile is much faster than a BufferedOutputStream on the platforms that I tested on (Solaris, Linux and Windows XP). To give you an idea, logging 100,000 events of 500 bytes (after warmup of 10 x 100,000 events) took ~8700 nanos per line with the standard BufferedOutputStream, and ~5200 per line with a RandomAccessFileAppender in my environment. Let me know if you want more detail. Best regards, Remko > 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