[jira] [Resolved] (LOG4J2-42) Improving log4j so it can easily be used with servlet logging
[ https://issues.apache.org/jira/browse/LOG4J2-42?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Ralph Goers resolved LOG4J2-42. --- Resolution: Fixed Fix Version/s: 2.0-rc2 Created ServletContextAppender in revision 1601789. Please verify and close > Improving log4j so it can easily be used with servlet logging > - > > Key: LOG4J2-42 > URL: https://issues.apache.org/jira/browse/LOG4J2-42 > Project: Log4j 2 > Issue Type: Wish > Components: API >Reporter: Curt Arnold > Fix For: 2.0-rc2 > > > On May 30, 2010, at 11:49 AM, Thorbjørn Ravn Andersen wrote: > There is one more thing that I would really like to see in log4j 2.0, namely > the ability for a servlet to log to a servlet container using log4j (and in > slf4j too but that is a different story). Currently that cannot be done, > because there is no way for the code asking for the logger to pass a "this" > reference to the logging framework. > I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is > changed to accept the class (as now), and a varargs of Objects. The objects > are passed to the appender when needing to do the actual logging, allowing a > ServletLoggerAppender to look for any object extending GenericServlet and > invoke its log method. > For client code it would mean that the logger object was retreived similar to: > Logger log = Logger.getLogger(this.getClass(), this); > We might even consider making the rule in log4j 2.0 that "the name of the > logger is the full name of the class of the first object"[2]. In that case > we could make do with: > Logger log = Logger.getLogger(this); > This would most likely also result in much other code being cleaner by > allowing to drop the "getClass()" clause. > What do you think? > [1] > http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 > > [2] For backwards compatability instances of Class should be treated slightly > different :) > -- > Thorbjørn Ravn Andersen "...plus... Tubular Bells!" > The follows at http://thread.gmane.org/gmane.comp.jakarta.log4j.devel/15576 -- This message was sent by Atlassian JIRA (v6.2#6252) - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] [Commented] (LOG4J2-42) Improving log4j so it can easily be used with servlet logging
[ https://issues.apache.org/jira/browse/LOG4J2-42?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13265660#comment-13265660 ] Ralph Goers commented on LOG4J2-42: --- LogManager.getLogger() passes the FQCN of the LogManager and thus determines the class that invoked it. ClassLoaderContextSelector uses this information to associate the Logger instance with the LoggerContext associated with the caller's ClassLoader. Unfortunately, the class itself isn't stored currently. > Improving log4j so it can easily be used with servlet logging > - > > Key: LOG4J2-42 > URL: https://issues.apache.org/jira/browse/LOG4J2-42 > Project: Log4j 2 > Issue Type: Wish > Components: API >Reporter: Curt Arnold > > On May 30, 2010, at 11:49 AM, Thorbjørn Ravn Andersen wrote: > There is one more thing that I would really like to see in log4j 2.0, namely > the ability for a servlet to log to a servlet container using log4j (and in > slf4j too but that is a different story). Currently that cannot be done, > because there is no way for the code asking for the logger to pass a "this" > reference to the logging framework. > I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is > changed to accept the class (as now), and a varargs of Objects. The objects > are passed to the appender when needing to do the actual logging, allowing a > ServletLoggerAppender to look for any object extending GenericServlet and > invoke its log method. > For client code it would mean that the logger object was retreived similar to: > Logger log = Logger.getLogger(this.getClass(), this); > We might even consider making the rule in log4j 2.0 that "the name of the > logger is the full name of the class of the first object"[2]. In that case > we could make do with: > Logger log = Logger.getLogger(this); > This would most likely also result in much other code being cleaner by > allowing to drop the "getClass()" clause. > What do you think? > [1] > http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 > > [2] For backwards compatability instances of Class should be treated slightly > different :) > -- > Thorbjørn Ravn Andersen "...plus... Tubular Bells!" > The follows at http://thread.gmane.org/gmane.comp.jakarta.log4j.devel/15576 -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa 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
Re: Improving log4j so it can easily be used with servlet logging
Den 01/06/10 00.53, Curt Arnold skrev: If the current logj4 API was extended to add user-supplied context, you'd have: Logger.info(Object message, Throwable thrown, Object context); In the context of a Servlet, you could end up doing: logger.info("Hello, World", null, this); logger.info("Goodbye, World", null, this); In the JSF snippet, it might be: logger.info("Hello, World", null, getContext()); There has been some discussion about how to handle varargs on the slf4j list which I think is more appropriate for the actual logger call. It is an interesting approach and it might be feasible to do some voodoo in the actual appender. -- Thorbjørn Ravn Andersen "...plus... Tubular Bells!" - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
[jira] Created: (LOG4J2-42) Improving log4j so it can easily be used with servlet logging
Improving log4j so it can easily be used with servlet logging - Key: LOG4J2-42 URL: https://issues.apache.org/jira/browse/LOG4J2-42 Project: Log4j 2 Issue Type: Wish Components: API Reporter: Curt Arnold On May 30, 2010, at 11:49 AM, Thorbjørn Ravn Andersen wrote: There is one more thing that I would really like to see in log4j 2.0, namely the ability for a servlet to log to a servlet container using log4j (and in slf4j too but that is a different story). Currently that cannot be done, because there is no way for the code asking for the logger to pass a "this" reference to the logging framework. I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is changed to accept the class (as now), and a varargs of Objects. The objects are passed to the appender when needing to do the actual logging, allowing a ServletLoggerAppender to look for any object extending GenericServlet and invoke its log method. For client code it would mean that the logger object was retreived similar to: Logger log = Logger.getLogger(this.getClass(), this); We might even consider making the rule in log4j 2.0 that "the name of the logger is the full name of the class of the first object"[2]. In that case we could make do with: Logger log = Logger.getLogger(this); This would most likely also result in much other code being cleaner by allowing to drop the "getClass()" clause. What do you think? [1] http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 [2] For backwards compatability instances of Class should be treated slightly different :) -- Thorbjørn Ravn Andersen "...plus... Tubular Bells!" The follows at http://thread.gmane.org/gmane.comp.jakarta.log4j.devel/15576 -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
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. > Ralph
Re: Improving log4j so it can easily be used with servlet logging
On Mon, 31 May 2010 22:48:25 -0700 Ralph Goers wrote: On May 31, 2010, at 10:31 PM, Jacob Kjome wrote: 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=12735918324&r=1&w=2 Thanks for the context. I guess I should subscribe to SLF4J User's - I only subscribe to the dev list. FWIW, in SLF4J ILoggerFactory plays the same role as LoggerContext in my Log4J2 API. Logback handles different types of Contexts as described at http://logback.qos.ch/manual/loggingSeparation.html. My intention is to do something similar. However, neither SLF4J or Logback provide links to an external context as far as I am aware. Logback's Logger Context is equivalent to Log4j's Logger Repository, just as Logback's ContextSelector is equivalent to Log4j's RepositorySelector. See another article written by Ceki back in 2002 http://articles.qos.ch/sc.html 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. Another Jira issue to open. In 2.0 it needs to be possible to let every webapp have its own LoggerContext even though the Log4J code might be shared. Logback currently provides this functionality. As has Log4j for a very long time, again, using a Logger Repository Selector. 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. 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? 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 partic
Re: Improving log4j so it can easily be used with servlet logging
On May 31, 2010, at 10:31 PM, Jacob Kjome wrote: > 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=12735918324&r=1&w=2 Thanks for the context. I guess I should subscribe to SLF4J User's - I only subscribe to the dev list. FWIW, in SLF4J ILoggerFactory plays the same role as LoggerContext in my Log4J2 API. Logback handles different types of Contexts as described at http://logback.qos.ch/manual/loggingSeparation.html. My intention is to do something similar. However, neither SLF4J or Logback provide links to an external context as far as I am aware. > > > 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. Another Jira issue to open. In 2.0 it needs to be possible to let every webapp have its own LoggerContext even though the Log4J code might be shared. Logback currently provides this functionality. 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. > > 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. > > 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. > > > 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
Re: Improving log4j so it can easily be used with servlet logging
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=12735918324&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
Re: Improving log4j so it can easily be used with servlet logging
On May 31, 2010, at 6: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. > Being able to pass an arbitrary object through as the user context is pretty key to it being usable. If you really wanted to pass an arbitrary context through, the naive way to do it would be: logger.log(message, thrown, new ContextWrapper(arbitraryObject)) But you would take a hit on every call regardless of the threshold. What would you suggest Context look like? - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
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
Re: Improving log4j so it can easily be used with servlet logging
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); In the context of a Servlet, you could end up doing: logger.info("Hello, World", null, this); logger.info("Goodbye, World", null, this); In the JSF snippet, it might be: logger.info("Hello, World", null, getContext()); The context object would pass through the call stack and eventually get incorporated into the logging event. You could then have a ServletContextAppender (or something like it do): public void doAppend(LogRecord logEvent) { ServletContext context = null; if(logEvent.getUserContext() instanceof ServletContext) { context = (ServletContext) logEvent.getUserContext(); } else if(logEvent.getUserContext() instanceof Servlet) { context = ((Servlet) logEvent.getUserContext()).getContext(); ... if(context != null) { ... context.log(...); } } We could likely have such a servlet appender in the default configuration since it would be innocuous unless a servlet context was passed. It may not be the right answer for this problem, but I think it will be the right answer for a non-empty class of problems. - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
On May 31, 2010, at 1:43 PM, Thorbjørn Ravn Andersen wrote: > Den 30/05/10 21.34, Ralph Goers skrev: >> Wouldn't it make more sense for the LoggerContext to have a reference to the >> ServletContext? The Appender could then do >> >> if (getContext().getServletContext() != null) { >> getContext().getServletContext().log(event.getFormattedMessage()); >> } >> >> > I do not know. I am unfamiliar with what the LoggerContext provides. Are > you suggesting that for each and every possible sub-context you will provide > a field in the LoggerContext? No. It would probably make more sense to do what JSF does when it is running in a Portal: Object obj = getContext().getExternalContext(); if (obj != null && obj instanceof ServletContext) { ((ServletContext) obj).log(event.getFormattedMessage()); } One could also do: if (getContext() instanceof LoggerServletContext) { ((LoggerServletContext) getContext()).getContext().log(event.getFormattedMessage()); } in which case LoggerServletContext would extend LoggerContext and provide the field. > >> Note that if the servlet adds its name to the MDC then all log records will >> have this available. >> >> To be honest though, I would have expected the desire would be to have the >> ServletContext's log methods route to Log4j, not the other way around. >> > The reason is simple. There is no guarantee that any J2EE container can or > will allow access to the filesystem. Using the servlet log-method is the > _ONLY_ well-defined way to log things inside a J2EE container without needing > to make assumptions and manual configurations (remember the container doesn't > help). > > Possible assumptions may be: > > * I can access the file system. > * Current working directory can be used (for writing or starting navigation) > * The JVM provides environment variable which can be used to locate the > user.home of the operating system user running the JVM. > * The JVM is allowed to write in user.home. > > I like debug logs placed in the filesystem, but I also like to be able to > send log messages to the standard log mechanism. The latter I cannot do > right now. > OK. But just because you can't write to the FileSystem doesn't mean that writing via the ServletContext's log method is your only option. You can write to a database, syslog, SNMP, SMTP, etc. But yes, some configuration would be required to make that happen. Writing to the containers log file is sub-optimal in a lot of cases for various reasons such as; a) writing debug logs to the local file system can be a security risk, and b) multiple webapps may end up in a co-mingled log file. While I understand your use case it is just one I would rarely, if ever, recommend. Ralph - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
Den 30/05/10 21.34, Ralph Goers skrev: Wouldn't it make more sense for the LoggerContext to have a reference to the ServletContext? The Appender could then do if (getContext().getServletContext() != null) { getContext().getServletContext().log(event.getFormattedMessage()); } I do not know. I am unfamiliar with what the LoggerContext provides. Are you suggesting that for each and every possible sub-context you will provide a field in the LoggerContext? Note that if the servlet adds its name to the MDC then all log records will have this available. To be honest though, I would have expected the desire would be to have the ServletContext's log methods route to Log4j, not the other way around. The reason is simple. There is no guarantee that any J2EE container can or will allow access to the filesystem. Using the servlet log-method is the _ONLY_ well-defined way to log things inside a J2EE container without needing to make assumptions and manual configurations (remember the container doesn't help). Possible assumptions may be: * I can access the file system. * Current working directory can be used (for writing or starting navigation) * The JVM provides environment variable which can be used to locate the user.home of the operating system user running the JVM. * The JVM is allowed to write in user.home. I like debug logs placed in the filesystem, but I also like to be able to send log messages to the standard log mechanism. The latter I cannot do right now. -- Thorbjørn Ravn Andersen "...plus... Tubular Bells!" - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
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? -- Thorbjørn Ravn Andersen "...plus... Tubular Bells!" - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
On May 30, 2010, at 2:12 PM, Curt Arnold wrote: > > On May 30, 2010, at 11:49 AM, Thorbjørn Ravn Andersen wrote: > >> There is one more thing that I would really like to see in log4j 2.0, namely >> the ability for a servlet to log to a servlet container using log4j (and in >> slf4j too but that is a different story). Currently that cannot be done, >> because there is no way for the code asking for the logger to pass a "this" >> reference to the logging framework. >> >> I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is >> changed to accept the class (as now), and a varargs of Objects. The objects >> are passed to the appender when needing to do the actual logging, allowing a >> ServletLoggerAppender to look for any object extending GenericServlet and >> invoke its log method. >> >> For client code it would mean that the logger object was retreived similar >> to: >> >> Logger log = Logger.getLogger(this.getClass(), this); >> >> >> We might even consider making the rule in log4j 2.0 that "the name of the >> logger is the full name of the class of the first object"[2]. In that case >> we could make do with: >> >> Logger log = Logger.getLogger(this); >> >> This would most likely also result in much other code being cleaner by >> allowing to drop the "getClass()" clause. >> >> What do you think? >> >> >> [1] >> http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 >> >> >> [2] For backwards compatability instances of Class should be treated >> slightly different :) >> >> -- >> Thorbjørn Ravn Andersen "...plus... Tubular Bells!" >> > > > 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. Passing the "context" as a parameter to logging calls is not the right way to handle this. Typically, only the top level classes are aware of the Servlet object or the ServletContext. All the calls underneath tend to be generic, such as everything in Apache Commons. The best way to handle this is to have different extensions of the LoggerContext that provide the information about the execution context. > > 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. As I said below, the Appender could just as easily check the context. In my environment ipaddress, hostname, requestURI, etc are all part of the MDC and are passed from the web tier to all the services that are invoked so that all the logs can be correlated against the same user, request, transaction, etc. Adding these to the context object is problematic because the context is shared across requests which the MDC is not. Ralph - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
On May 30, 2010, at 11:49 AM, Thorbjørn Ravn Andersen wrote: > There is one more thing that I would really like to see in log4j 2.0, namely > the ability for a servlet to log to a servlet container using log4j (and in > slf4j too but that is a different story). Currently that cannot be done, > because there is no way for the code asking for the logger to pass a "this" > reference to the logging framework. > > I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is > changed to accept the class (as now), and a varargs of Objects. The objects > are passed to the appender when needing to do the actual logging, allowing a > ServletLoggerAppender to look for any object extending GenericServlet and > invoke its log method. > > For client code it would mean that the logger object was retreived similar to: > > Logger log = Logger.getLogger(this.getClass(), this); > > > We might even consider making the rule in log4j 2.0 that "the name of the > logger is the full name of the class of the first object"[2]. In that case > we could make do with: > > Logger log = Logger.getLogger(this); > > This would most likely also result in much other code being cleaner by > allowing to drop the "getClass()" clause. > > What do you think? > > > [1] > http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 > > > [2] For backwards compatability instances of Class should be treated slightly > different :) > > -- > Thorbjørn Ravn Andersen "...plus... Tubular Bells!" > 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. On May 30, 2010, at 2:34 PM, Ralph Goers wrote: > Wouldn't it make more sense for the LoggerContext to have a reference to the > ServletContext? The Appender could then do > > if (getContext().getServletContext() != null) { > getContext().getServletContext().log(event.getFormattedMessage()); > } > > Note that if the servlet adds its name to the MDC then all log records will > have this available. > > To be honest though, I would have expected the desire would be to have the > ServletContext's log methods route to Log4j, not the other way around. > > Ralph The MDC is associated with the thread and a single thread over its lifetime may deal with multiple servlets. Using the MDC for user-supplied context then requires a decent amount of less than foolproof gymnastics to make sure that things don't linger in the MDC outside of the scope of the call. We should capture this in JIRA. - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org
Re: Improving log4j so it can easily be used with servlet logging
Wouldn't it make more sense for the LoggerContext to have a reference to the ServletContext? The Appender could then do if (getContext().getServletContext() != null) { getContext().getServletContext().log(event.getFormattedMessage()); } Note that if the servlet adds its name to the MDC then all log records will have this available. To be honest though, I would have expected the desire would be to have the ServletContext's log methods route to Log4j, not the other way around. Ralph On May 30, 2010, at 9:49 AM, Thorbjørn Ravn Andersen wrote: > There is one more thing that I would really like to see in log4j 2.0, namely > the ability for a servlet to log to a servlet container using log4j (and in > slf4j too but that is a different story). Currently that cannot be done, > because there is no way for the code asking for the logger to pass a "this" > reference to the logging framework. > > I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is > changed to accept the class (as now), and a varargs of Objects. The objects > are passed to the appender when needing to do the actual logging, allowing a > ServletLoggerAppender to look for any object extending GenericServlet and > invoke its log method. > > For client code it would mean that the logger object was retreived similar to: > > Logger log = Logger.getLogger(this.getClass(), this); > > > We might even consider making the rule in log4j 2.0 that "the name of the > logger is the full name of the class of the first object"[2]. In that case > we could make do with: > > Logger log = Logger.getLogger(this); > > This would most likely also result in much other code being cleaner by > allowing to drop the "getClass()" clause. > > What do you think? > > > [1] > http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 > > > [2] For backwards compatability instances of Class should be treated slightly > different :) > > -- > Thorbjørn Ravn Andersen "...plus... Tubular Bells!" > > > - > 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
Improving log4j so it can easily be used with servlet logging
There is one more thing that I would really like to see in log4j 2.0, namely the ability for a servlet to log to a servlet container using log4j (and in slf4j too but that is a different story). Currently that cannot be done, because there is no way for the code asking for the logger to pass a "this" reference to the logging framework. I would suggest that in log4j 2.0 the LoggerManager.getLogger() signature is changed to accept the class (as now), and a varargs of Objects. The objects are passed to the appender when needing to do the actual logging, allowing a ServletLoggerAppender to look for any object extending GenericServlet and invoke its log method. For client code it would mean that the logger object was retreived similar to: Logger log = Logger.getLogger(this.getClass(), this); We might even consider making the rule in log4j 2.0 that "the name of the logger is the full name of the class of the first object"[2]. In that case we could make do with: Logger log = Logger.getLogger(this); This would most likely also result in much other code being cleaner by allowing to drop the "getClass()" clause. What do you think? [1] http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/GenericServlet.html#log%28java.lang.String%29 [2] For backwards compatability instances of Class should be treated slightly different :) -- Thorbjørn Ravn Andersen "...plus... Tubular Bells!" - To unsubscribe, e-mail: log4j-dev-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-dev-h...@logging.apache.org