Re: Issues Logging wtith log4j at common and webapp levels

2012-12-03 Thread David Johle
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

2012-12-03 Thread Christopher Schultz
-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

2012-12-03 Thread André Warnier

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

2012-10-02 Thread David Johle
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

2012-10-02 Thread Mark Thomas
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