log4j没有打印异常的stacktrace

Rya*_*yan 67 java logging tomcat log4j

我正在使用log4j和tomcat.当我在JSP中记录异常时,servlet:

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

我只得到异常的第一行,没有堆栈跟踪.

17-Feb 17:37:45 ERROR AutoContrib:175 - 发布csv文件时出现异常:java.lang.ArrayIndexOutOfBoundsException

根本没有帮助!

我的log4j.properties文件(/tomcat/common/classes/log4j.properties)如下所示:

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
Run Code Online (Sandbox Code Playgroud)

min*_*imo 78

实际上,这可能是由于热点优化:在抛出一定数量的相同异常后,它会停止打印出跟踪.可以使用VM arg关闭此功能,请参阅:

来自http://www.oracle.com/technetwork/java/javase/relnotes-139183.html:

服务器VM中的编译器现在为所有"冷"内置异常提供正确的堆栈回溯.出于性能目的,当抛出这样的异常几次时,可以重新编译该方法.重新编译之后,编译器可以使用不提供堆栈跟踪的预分配异常来选择更快的策略.要完全禁用预分配的异常,请使用以下新标志:-XX:-OmitStackTraceInFastThrow.

更多信息:

http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/

  • 为什么Java...为什么...? (11认同)
  • 没有什么比在生产系统上用“java.lang.NullPointerException”敲头并试图找出它在类中的位置更好的了。 (4认同)

obj*_*cts 22

您发布的内容应显示javadoc中所述的堆栈跟踪.

请注意,如果您不包含消息(并且只是调用logger.error(ex)),则不会记录堆栈跟踪.

  • 啊.它就是.这就是咬我的.记录错误不会打印堆栈跟踪.您需要记录带有错误的消息才能获得该消息. (3认同)

Ven*_*oya 17

错误方法有两种重载方法.

  1. logger.error(ex);
  2. logger.error("some oops string ", ex);

如果您使用1st方法,它只会打印Exception的名称.如果你使用第二种方法,一些消息和异常将打印类似于e.printStackTrace()方法的完整堆栈跟踪 .


Roc*_*der 6

就像上面的@Luhar回答的那样,我在同样的事情上挣扎,最后这对我有用; 这种方法的好处是我们不必修改像JVM,Log4J这样的系统级设置,因为我们从来不知道它可能会带来新的意外惊喜!

try {

...
..

} catch (Exception er) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        er.printStackTrace(new PrintStream(os));
        LOGGER.error(new String(os.toByteArray()));
        //LOGGER.error(er);
}
Run Code Online (Sandbox Code Playgroud)