I thought it might be useful to interject with some history about Log4j and ServletContext logging. Please see this recent thread on the slf4j-user list for some pertinent details explaining how this is actually possible today with Log4j 1.2...
http://marc.info/?t=127359183200004&r=1&w=2 Now that you are familiar with that, let's address the LoggerContext stuff. I agree with Ralph's objections to Curt's proposal (though possibly not for the same reasons). However, I'm not necessarily in agreement with Ralph either. First, some basic questions.... Can there be only one LoggerContext as is implied by LogManager.setContext(LoggerContext)? Why not support multiple contexts at any given time? And just because a context has been set, does that imply that the context itself logs (as opposed to merely providing some contextual information) or that all logging should go to that context when it is set regardless of configured appenders? And what if LogManager exists at the container level, meaning that Log4j is being shared by all apps? We can't use the context of one app for all apps, e.g., we can't be using a single webapp's ServletContext to log for all apps. The context should be scoped to the current Logger Repository, not the classloader of the LogManager. In any case, isn't this what an Appender is for? To me, unless a logging configuration specifies that logging information for a given logger ought to go to an appender that directs logging to the servlet context, then it shouldn't go to the servlet context regardless of any supplied context. It should go to whatever appender it is configured to go to. Here are my requirements... 1. I would only agree with a context (zero or more) being able to be supplied to a Logger method if it is made absolutely clear that just because a context is provided, does not imply that context will have any effect on logging, as it would depend on whether the current configured appenders recognize, and make use of, the context. If an appender is assigned to the logger in question AND it supports the provided context, then it would be utilized, otherwise not. That said, I'm not sure that it's worth the API pollution nor amount of confusion that this would inevitably create for users? 2. It MUST be possible to set the context in some other more general way. Why? Because, in the case of a ServletContext, it is only available to application classes that participate in the servlet lifecycle, not general library classes. All classes that log must be able to participate. 3. It must work for ANY number of Logger Repositories, not just the default one. The solution that Aleksei Valikov came up with, and I implemented in the Log4j sandbox [1][2], implements #2 and #3 above using plain old Log4j 1.2. A few things could be improved upon, such as the static ServletContext registration concept and the requirement that appender configuration must provide the context path. Fallback to a non-context dependent appender would be beneficial as well. The first two issues could be ameliorated by using a servlet Filter to register a ThreadLocal for the request request/response lifecyle. The last could be addressed simply by an update to the appender to allow for a fallback appender to be configured. As has been shown, all of this can be done *without* the concept of an API-level LoggerContext and, in fact, with the current production version of Log4j. I strongly suggest that this LoggerContext stuff be thought through a bit more before polluting the API with the concept. I'm not against the concept in general. I just want to make sure that it isn't being implemented the wrong way for the wrong reasons. Thoughts? [1] http://svn.apache.org/repos/asf/logging/sandbox/log4j/log4j_sandbox/tags/LOG4J_SANDBOX_ALPHA3/src/java/org/apache/log4j/servlet/ServletContextLogAppender.java [2] http://svn.apache.org/repos/asf/logging/sandbox/log4j/log4j_sandbox/tags/LOG4J_SANDBOX_ALPHA3/src/java/org/apache/log4j/servlet/ServletContextLogAppenderListener.java Jake On 5/31/2010 5:56 PM, Ralph Goers wrote: > > On May 31, 2010, at 3:53 PM, Curt Arnold wrote: > >> >> On May 31, 2010, at 3:28 PM, Thorbjørn Ravn Andersen wrote: >> >>> Den 30/05/10 23.12, Curt Arnold skrev: >>>> I don't have this in code or in the JIRA, but I have mentioned in recent >>>> threads the idea of a user-supplied context object in logging calls. >>>> Currently log4j has a thread associated context (the MDC and NDC) and >>>> there are JVM level context (line ending separator), but there is no >>>> concept of a user-supplied context unless embedded in the message >>>> parameter. >>>> In this case, the logging call is operating in the "context" of the >>>> servlet request, and you could do pass the servlet as the user-context >>>> object. A servlet appender could check if the user context object was a >>>> Servlet and if so delegate to its log method. We could also add patterns >>>> for %ipaddr, %ipport, etc, that would attempt to recognize the >>>> user-context object and extract that info if it could recognize the type. >>>> >>> I am unsure of what you describe. Could you write some pseudocode showing >>> what you mean? >>> >> >> I'm working way below the client API at the moment, but the general idea is >> that in addition to MDC and NDC (aka the thread-associated context), the >> stack trace (aka the caller context), you can provide context with an >> explicit context parameter on the logging call. >> >> If the current logj4 API was extended to add user-supplied context, you'd >> have: >> >> Logger.info(Object message, Throwable thrown, Object context); > > I would object to this - see my other post. I could tolerate this if it was > > Logger.into(Object message, Throwable thrown, Context context); > > But since the Context is likely to have the same life expectancy as the > LoggerContext it makes more sense to just tie those together. > > public class LoggerContextListener implements ServletContextListener { > public void contextInitialized(ServletContextEvent event) { > LogManager.setContext(new > ServletLoggerContext(event.getServletContext())); > } > > } > > public class ServletLoggerContext extends LoggerContext { > > private ServletContext context; > > public ServletLoggerContext(ServletContext context) { > super(); > this.context = context; > } > > public Object getExternalContext() { > return this.context; > } > } > > > > Ralph > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org > For additional commands, e-mail: log4j-dev-h...@logging.apache.org > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org