log4j not printing the stacktrace for exceptions

2019-01-17 02:16发布

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, without a stacktrace.

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

8条回答
劫难
2楼-- · 2019-01-17 02:44

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));
查看更多
Summer. ? 凉城
3楼-- · 2019-01-17 02:47

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);
}
查看更多
闹够了就滚
4楼-- · 2019-01-17 02:50

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);
}
查看更多
迷人小祖宗
5楼-- · 2019-01-17 02:58

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

查看更多
甜甜的少女心
6楼-- · 2019-01-17 02:59

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 {

查看更多
Ridiculous、
7楼-- · 2019-01-17 03:00

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.

查看更多
登录 后发表回答