I am using log4j with tomcat. When I log exceptions in my JSPs, servlets:
private Logger _log = Logger.getLogger(this.getClass());
...
try{...} catch (Except
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
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.
Like answered by @Luhar above, I struggled with same thing and finally this worked for me; Good thing about this approach is we don't have to tinker with system level settings like JVM, Log4J since we never know it may lead to new unexpected surprise !
try {
...
..
} catch (Exception er) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
er.printStackTrace(new PrintStream(os));
LOGGER.error(new String(os.toByteArray()));
//LOGGER.error(er);
}
You can add these lines of code in your catch block.
catch (SQLException e) {
CharArrayWriter cw = new CharArrayWriter();
PrintWriter w = new PrintWriter(cw);
e.printStackTrace(w);
w.close();
String trace = cw.toString();
log.error("This is complete stacktrace", trace);
}
Actually, it's probably due to a hotspot optimization: after a certain number of the same exception being thrown it stops printing out trace. This can be turned off with a VM arg, see:
From http://www.oracle.com/technetwork/java/javase/relnotes-139183.html :
The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow.
More here:
http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/
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 {