views:

457

answers:

4

Hi,

I am using log4j with tomcat. When I log exceptions in my JSPs, servlets:

private Logger _log = Logger.getLogger(this.getClass());
...
try{...} catch (Exception e) {
    _log.error("Error refreshing all prices", e);
}

I only get the first line of the exception.

17-Feb 17:37:45 ERROR AutoContrib:175 - Exception while publishing csv file: java.lang.ArrayIndexOutOfBoundsException

Not very helpful at all!

My log4j.properties file (/tomcat/common/classes/log4j.properties) looks like this:

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{dd-MMM HH:mm:ss} %5p %c{1}:%L - %m%n
log4j.appender.stdout.threshold=info

log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.maxFileSize=5000KB
log4j.appender.file.maxBackupIndex=10
log4j.appender.file.File=${catalina.home}/logs/web.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd-MMM HH:mm:ss} %5p %c{1}:%L - %m%n
log4j.appender.file.threshold=info

log4j.rootLogger=debug, stdout, file

Thanks for any help or advice

Ryan

A: 

Using your code sample:

private static final Logger _log = Logger.getLogger(MyClass.class);
...
try{...} catch (Exception e) {
    //Change
    //_log.error("Error refreshing all prices", e);

   //To
    _log.error("Error refreshing all prices", e.fillInStackTrace());
}

You'll see all the stack trace displayed.

PS. Make Logger a singleton...(check my declaration) just after declaring public class MyClass {

The Elite Gentleman
Thanks for the advice! I will try this now. BTW, for the singleton approach you can't use 'this' with the static getLoggger(). I guess I can use getLogger(MyClass.class)
Ryan
True Ryan!. It makes instantiation faster seeing that the singleton already exists after creation.
The Elite Gentleman
ideally, he shouldn't need this
Bozho
that changes the stack trace to be the state of the current thread. It will no longer be the stack trace for the thrown exception
objects
That's correct, Definition of `fillInStackTrace()`: `Fills in the execution stack trace. This method records within this Throwable object information about the current state of the stack frames for the current thread.` and that's what we want. So recording all the stack frames from the thread that executed it. After all, Web apps especially are thread-executed, so that makes perfect sense.
The Elite Gentleman
the stack trace of the thread is different from the stack trace of the exception. The stack trace of the exception shows where the exception occurred, the stack trace of the thread (in this case) shows where the exception was caught.
objects
I understand what you're saying @objects, `fillInStackTrace` also records the Cause of the exception. So you can ideally check in the cause to see where the fault lies.
The Elite Gentleman
fillInStackTrace does not record the cause afaik, it (the cause) is set when the exception is created (fillInStackTrace is also called at that point)
objects
A: 

I don't see anything wrong with your config, so try to upgrade log4j to a newer (not necessarily the latest) version.

Though not the problem in this case, you'd better make your loggers private static final

Bozho
A: 

I haven't used the fillStackTrace call, so I cannot comment if that will work. Another approach is to use a little method that returns the formatted text from an Exception.

public static String getStackTrace(Exception e)
{
    StringWriter sWriter = new StringWriter();
    PrintWriter pWriter = new PrintWriter(sWriter);
    e.printStackTrace(pWriter);
    return sWriter.toString();
}

In your logging code, you could write:

logger.error("An exception occurred: " + Utils.getStackTrace(e));
Luhar
ideally, he shouldn't need this
Bozho
A: 

What you have posted should display the stack trace as stated in the javadoc.

Note that if you don't include a message (and just call logger.error(ex)) then the stack trace is not logged.

objects