Re: Issues Logging wtith log4j at common and webapp levels
Well I managed to accomplish my goal 100% with the help of some new features in Log4j 2.x (currently beta-3). My eventual setup was to use the BasicContextSelector to ensure only a single logging heirarchy was created for the whole VM regardless of webapps. Then I tag events per-webapp using a ServletFilter to manipulate the ThreadContext, and send them all through a central RoutingAppender which in turn directs the entries (based on the tag) to the appropriate FileAppender. Since the tagging is done at the request level, both webapp specific classes, central libraries, and even VM-wide singletons used by a request all carry that tag (it uses ThreadLocal internally) and thus get routed properly. As for the remaining System.out calls in JSP files, separate Loggers are defined for those to capture the events created by swallowOutput (which don't carry the tag) and manually route them the appropriate FileAppender. Eventually that extra fluff can go away though. Another nice part about this is I only have a single instance of the logj4 libraries a single centralized configuration file, which is A Good Thing(tm) for this setup. Lots of other features in log4j2 that I was able to benefit from as well like dynamic reconfiguration and such, so I also set up my internal Tomcat logging (read: anything without a tag) to route into Tomcat's log. Sorry JULI, you just weren't good enough for me ;) On 02/10/2012 20:29, Mark Thomas wrote: Thanks for the clear question. While it was quite long, it was very readable, relevant and on point. That meant I got to the end rather than giving up after a few lines which is what usually happens with me and long questions. So in summary, I'm just trying to get shared libraries to have their log4j-based logging written to the webapp-specific log files of the calling webapp. Is this possible? If so, what's the trick? It can be done - with some caveats. Tomcat does this with Jasper. The short version is: - The loggers can not be static - There must be an instance of the class per web-app. If you have singletons and an instance per webapp doesn't make sense then the only option that comes to mind (after not much thinking) is that you need to pass the logger to the singleton rather than it using its own. HTH, Mark - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: [OT] Issues Logging wtith log4j at common and webapp levels
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 David, On 12/3/12 1:57 PM, David Johle wrote: Well I managed to accomplish my goal 100% with the help of some new features in Log4j 2.x (currently beta-3). Holy crap, the log4j folks are finally going to release an update. After the abortive attempt some years ago, I'm glad they are once again pushing for a 2.0-release. ...and of course, I now have to change everything about the way I use log4j. :( - -chris -BEGIN PGP SIGNATURE- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with undefined - http://www.enigmail.net/ iEYEARECAAYFAlC9CVoACgkQ9CaO5/Lv0PDl9gCfU9o0jGC13Z2NyhaOKWBzXIr/ 3cUAoJz0tVZmVZulYQ/mT4TygxKkWJPe =cFYt -END PGP SIGNATURE- - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Re: Issues Logging wtith log4j at common and webapp levels
David Johle wrote: Well I managed to accomplish my goal 100% with the help of some new features in Log4j 2.x (currently beta-3). My eventual setup was to use the BasicContextSelector to ensure only a single logging heirarchy was created for the whole VM regardless of webapps. Then I tag events per-webapp using a ServletFilter to manipulate the ThreadContext, and send them all through a central RoutingAppender which in turn directs the entries (based on the tag) to the appropriate FileAppender. Since the tagging is done at the request level, both webapp specific classes, central libraries, and even VM-wide singletons used by a request all carry that tag (it uses ThreadLocal internally) and thus get routed properly. As for the remaining System.out calls in JSP files, separate Loggers are defined for those to capture the events created by swallowOutput (which don't carry the tag) and manually route them the appropriate FileAppender. Eventually that extra fluff can go away though. Another nice part about this is I only have a single instance of the logj4 libraries a single centralized configuration file, which is A Good Thing(tm) for this setup. Lots of other features in log4j2 that I was able to benefit from as well like dynamic reconfiguration and such, so I also set up my internal Tomcat logging (read: anything without a tag) to route into Tomcat's log. Sorry JULI, you just weren't good enough for me ;) I am not sure that I understand everything here (Tomcat logging has long been quite a puzzle for me), but I seem to perceive the hope of seeing a long-time dream come true, as a sysadmin with limited Tomcat/Java/Juli/log4j knowledge : setting up *one* logging configuration that will just swallow everything from Tomcat and webapps - no matter how sneaky - into preferably one logfile to start with, with a sensible rotation. And /then/ start refining, as needed. If so, many thanks. Would you care to enter the setup instructions in a WiKi article ? I'm willing to be the test pigeon with a couple of running Tomcats, own webapps, foreign webapps etc. - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Issues Logging wtith log4j at common and webapp levels
I am having some issues getting the right planetary alignment of file locations configuration settings to get logging to work how I'd ideally like it. I think I'm having some undesireable interactions with static members and classloaders and such. This post is a bit of a novel, sorry about that, but I like to give all the details instead of having everyone incorrectly assume what is going on or worse yet being one of those annoying plz hlp me, kthxbai types that expects some kind of miracle. First off, here is some relevant system configuration information: RHEL5 Java 1.6 Tomcat 7.0.30 I have configured Tomcat to have 4 Host entries, so 4 webapp/contexts total. It's a clustered setup as well, but for this task that is not relevant, only that there are multiple contexts. And now some back story to make things more clear: I have a code library in a JAR and a pile (read: 5 digit quantity) of JSP files which represent a 10+ year evolution of code touched by many different developers. The JSPs are full of scriptlets with Java code (I know that's less than ideal, hence the cleanup efforts) and both the JSP Java code in the JAR are littered with System.out.println() Exception.printStackTrace() calls for various logging and/or debugging purposes. I have been working to modernize this to use a proper logging framework, and have standardized on log4j as it is what has been used in several other applications I have developed -- some of which are now utility libraries shared with and used by the web applications. Previously (Tomcat 5.0.x) we had all internal logging going to the catalina.out, and each webapp's logging going to a file local to the filesystem heirarchy used by said webapp. The webapps themselves use the same backend codebase and it must always be in sync, so to avoid complications we always deployed the JAR to the common lib directory. Despite being in the common area, the System.out output was still being captured by the swallowOutput=true setting, and thus the shared logging statements were still going to the respective webapp logfile that made calls to those libraries. When first upgrading Tomcat to 7.x we ran into some issues with getting the logs to the right places because of the new JULI stuff xand whatnot, and eventually got it to work by configuring log4j at the webapp level, and still using the swallowOutput=true to capture the System stuff. This was working great, and all System.out content was sent to the log4j appender local to the webapp. This was still an ugly way of doing logging though, so time to get rid of the bad practices. So now to make use of the logging framework: I first decided to tackle the JAR, went the shared code library and re-wrote every call (a lot!) to System.out.println() and Exception.printStackTrace() to use a proper log4j method indicating a logging level and passing exceptions when appropriate. However, when I deployed the new JAR file my results were not exactly as expected/desired. Some of the early logging was ending up in the catalina.out, along with some log4j configuration warnings. I converted the relevant class to use JULI instead as it was an extention of the DeltaManager from Tomcat, and thus created prior to the context itself, and used only by Tomcat. The only problem here is that it referenced some utility classes that were shared, and thus those still produced the log4j startup errors. So then I converted tomcat to use log4j for internal logging as well, which cleared up those errors, and made for a clean console. I set up a quick testing JSP which made System.out calls, log4j calls, and a call to a shared Java class which did a log4j call. I put this testing page on two different webapps and could hit each one and determine if the logging destinations were correct. I went on to test more logging and found that calls to log4j within the utility libraries (called from JSPs) were either not showing up anywhere at all, or all going to the webapp logs of the first loaded webapp, regardless of which one actually sourced them. This, I realized, was due to only having the log4j/etc. JAR files at the common classloader level. So I then ended up with a copy of log4j (and the JULI adapter stuff needed) in the common lib, as well as in each WEB-INF/lib. The System.out calls (the ones remaining, not yet converted) in the JSP files are still being routed to their respective local/per-webapp logs, so that's good. Calls to log4j directly from the JSP files also lead to the local log files, and I was able to get the URI as part of the logformat, so that's good. Calls to log4j from the shared Java classes, no so much. FWIW, I am using typical static logger declarations such as this in my Java classes: private static final Logger log = Logger.getLogger(LogTest.class); So that brings us to the current issue: No matter which webapp makes a call to the shared
Re: Issues Logging wtith log4j at common and webapp levels
On 02/10/2012 20:29, David Johle wrote: Thanks for the clear question. While it was quite long, it was very readable, relevant and on point. That meant I got to the end rather than giving up after a few lines which is what usually happens with me and long questions. So in summary, I'm just trying to get shared libraries to have their log4j-based logging written to the webapp-specific log files of the calling webapp. Is this possible? If so, what's the trick? It can be done - with some caveats. Tomcat does this with Jasper. The short version is: - The loggers can not be static - There must be an instance of the class per web-app. If you have singletons and an instance per webapp doesn't make sense then the only option that comes to mind (after not much thinking) is that you need to pass the logger to the singleton rather than it using its own. HTH, Mark - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org