log4j не печатает stacktrace для исключений
Я использую log4j с tomcat. Когда я регистрирую исключения в своих JSP, сервлеты:
private Logger _log = Logger.getLogger(this.getClass());
...
try{...} catch (Exception e) {
_log.error("Error refreshing all prices", e);
}
Я получаю только первую строку исключения, без stacktrace.
17-Feb 17: 37:45 ошибка AutoContrib: 175-исключение при публикации файла csv:
Ява.ленг.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
8 ответов:
на самом деле, это, вероятно, из-за оптимизации точки доступа: после определенного количества одного и того же исключения он перестает печатать трассировку. Это можно отключить с помощью VM arg, см.:
от http://www.oracle.com/technetwork/java/javase/relnotes-139183.html:
компилятор в виртуальной машине сервера теперь обеспечивает правильные обратные трассировки стека для всех" холодных " встроенных исключений. Для целей производительности, когда такое исключение выбрасывается несколько раз, метод может быть перекомпилированы. После компиляции, компилятор может выбрать более быструю тактику использования предварительно выделенные исключения, которые не обеспечивают трассировку стека. Отключить полностью использование предварительно выделенных исключений, используйте этот новый флаг: - XX: - OmitStackTraceInFastThrow.
подробнее здесь:
то, что вы опубликовали, должно отображать трассировку стека, как указано в документация.
обратите внимание, что если вы не включаете сообщение (и просто позвоните
logger.error(ex)), то трассировка стека не регистрируется.
существует два перегруженных метода для метода ошибок.
logger.error(ex);logger.error("some oops string ", ex);Если вы используете 1-й метод, который будет печатать только имя исключения. если вы используете 2-й метод, некоторое сообщение вместе с исключением, которое будет печатать полную трассировку стека, подобную
e.printStackTrace()метод.
Как ответил @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); }
Я не использовал вызов fillStackTrace, поэтому я не могу комментировать, если это будет работать. Другой подход заключается в использовании небольшого метода, который возвращает форматированный текст из исключения.
public static String getStackTrace(Exception e) { StringWriter sWriter = new StringWriter(); PrintWriter pWriter = new PrintWriter(sWriter); e.printStackTrace(pWriter); return sWriter.toString(); }в вашем коде регистрации вы можете написать:
logger.error("An exception occurred: " + Utils.getStackTrace(e));
Я не вижу ничего плохого в вашей конфигурации, поэтому постарайтесь обновить
log4jк более новой (не обязательно последней) версии.хотя не проблема в этом случае, вам лучше сделать ваши лесорубы
private static final
используя Ваш пример кода:
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()); }вы увидите все трассировки стека отображается.
PS. Сделать логгер одноплодной...(Проверьте мою декларацию) сразу после объявления
public class MyClass {
вы можете добавить эти строки кода в свой блок catch.
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); }
Comments