1 Jun 2010 17:40
Re: Improving log4j so it can easily be used with servlet logging
Ralph Goers <ralph.goers <at> dslextreme.com>
2010-06-01 15:40:05 GMT
2010-06-01 15:40:05 GMT
On Jun 1, 2010, at 8:06 AM, Jacob Kjome wrote:
Personally, I think this is one of the huge flaws in J2EE - that the components that are in the container are exposed to the webapps running in them, but I can't fix that.
Do you know of an application framework in any language that doesn't have this "flaw"? Just curious. I'm not sure it can rightly be called a "flaw" if it cannot possibly be avoided. I'm not saying it can't. I just think that if it could, it would have by someone in some language by now.
Java itself had this pitfall with the endorsed libraries. They have addressed it by prefixing the classes with com.sun, instead of using org.apache.whatever. JBoss could do the same thing with all its 3rd party dependencies. Another way to do it is to expose only the interface on the class loader with a proxy implementation. The actual container would reside under a sibling classloader. Of course, this would impact performance, which I am sure is why it wasn't done. OTOH, what OSGi does is essentially this and many containers have started moving in that direction.
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.
In general, the approach you took makes sense.
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?
If it were then I would suggest that it be incorporated via a ContextAwareMessage, not an additional Object on the API. This is similar to the problem I ran into with StructuredData, having Appenders have to run through all the parameters doing instanceof is a hack.
Ageed, if you mean that generic code should not be using instanceof. Only code that has business using a particular type of context object should bother referencing it. For instance, a ServletContextLogAppender class could properly use instanceof to determine whether [one of] the current context logger object is ServletContext to determine if it is usable.
BTW, can you describe what the logging call would look like using a "ConextAwareMessage"? And would this be able to supply more than one external context?
Look at BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api. I don't have a ContextAwareMessage but you could easily create one. Whether it supports more than one external context would be up to it.
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.
I know what you mean, but in my version of 2.0 Logger Repositories don't exist. The LoggerContext contains the Map of all the loggers obtained by getLogger() and a reference to the configuration. So the LoggerContext is equivalent to what I think you mean by Logger Repositories.
If LoggerContext is indeed the equivalent of Logger Repository, then I think we're good to go.
Again, look at my branch. It isn't even close to done, but hopefully you can see how it could do this.