On May 23, 2010, at 9:30 PM, Curt Arnold wrote: > >> >>> >>> The AsynchronousAppender in log4j requires trying to freeze LoggingEvent >>> which is still subject to message objects changing underneath it. Also it >>> generally perform unnecessary actions in freezing everything in the >>> LoggingEvent even though much of it will not be used. >>> >>> The framework should be designed to separate the parts required to be >>> synchronous (that is anything dealing with external objects) from the parts >>> that can be deferred. >> >> I don't think I really agree with this, at least the way you are expressing >> it. Typically, the "parts required to be synchronous" are also the ones that >> are expensive to resolve. What you are suggesting is that somehow it is >> easier to deal with a LogEvent that has a reference to another object that >> contains the references to the "synchronous objects" than to just copy the >> whole LogEvent. But copying simple object references like Strings doesn't >> cost all that much and may not even be worth doing if the appender needs >> some sort of serialized version of the LogEvent instead (SyslogAppender >> using either the serialized logging event or the IETFSyslogLayout that I >> haven't added yet). > > The summary in the second sentence feels the antithesis of what I'm > suggesting. > > Copying the "whole log event" so that the copy is not affected by any > potential changes is complicated, expensive and error-prone as seen in > log4j's AsyncAppender. The message parameter or any value in the MDC or NDC > in the log4j API can be any arbitrary object. If it is immutable, then you > are fine. If not and the object is serializable or clonable, you could > clonable. Otherwise, you are subject to changes that could occur after the > logging call. > > Restricting message, MDC and NDC parameters to strings is not desirable. > log4j allows it and there are reasonable and worthwhile reasons to use them.
You are correct. I had forgotten MDC and NDC allow Objects. I've gotten used to SLF4J only allowing Strings on the MDC. But the MDC I checked in does support Objects. I will have to look at what is happening with that in the LogEvent again. > > AsyncAppender does a not totally satisfactory clone of a LoggingEvent and > then runs the nested appender later on that clone, none of the nested > appenders code runs during the synchronous phase. The alternative I'm > suggesting is to allow appenders to see the LoggingEvent in the extraction > phase, get all the information that it needs (or possibly do the whole > action) and then leave a Runnable to complete the action. If fully > synchronous, the runnable would be immediately executed, if not, then sent to > a queue for later execution. Using a thread for to perform a synchronous activity is not something I think I'd be in favor of. Creating a thread is not trivial. Creating thread pools causes problems that have to be dealt with in servlet containers. Ceki and I had a discussion about that with a bug in Logback and I tended to agree with his position that creating long lived threads is bad. > > > >> >> In looking at Log4jLogEvent really the only fields that deal with external >> objects are the Message and the Throwable. I suppose a Throwable could be a >> problem if the caller has created their own exception type and added odd >> stuff to it (complex object references), although I can't say I've ever run >> across an Exception that does that. The Message can be solved by a) doing >> new SimpleMessage(message.getFormattedMessage()), b) serializing the message >> and deserializing it, or c) adding another method to the Message interface >> like "prepareForAsynch". > > "prepareForAsynch" has the same problem as serializing the logging event. > There is no bulletproof way to make an invariant copy of every arbitrary > objects and some may be extraordinary expensive. It seems to me to be much > clearer to have a phase where you have access to the LoggingEvent interface > in the scope of the logging call, but anything deferred must act on what was > extracted from that call. At the simplest, it could be to run the layout in > the extraction phase and hold the string for the completion phase. You are going to have to show me some code as I really don't see the difference between "prepareForAsynch" and a "phase". > > If I have an "itch" for log4j 2.0, this is it. I'm not sure where the path > would lead, but it is the path that I want to explore. I'm certainly not going to get in the way. The whole point of putting something out there is to have a place to start from. Ralph --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org