Регистрация лучшей информации об исключениях в Java - PullRequest
4 голосов
/ 28 октября 2011

Я работаю над большим Java-веб-приложением с Spring, Hibernate и некоторыми другими библиотеками, включая Apache log4j для ведения журналов.Один из моих текущих проектов - переписать большое количество исключений в унаследованных областях (которые я не писал!) Кода, чтобы дать более разумную информацию.Типичный блок исключений выглядит так:

try {
  //Some Hibernate business here
}
catch (Exception e) {   //Yes, Exception. That's not just me being general. I find this especially frustrating.
  log4j.error("Fail to XXXXXX");   //again, real
  throw new MyException();
}

Как вы можете догадаться, это делает некоторые сложные журналы.Я ищу стандартный способ получить лучшую информацию из этих исключений.Большинство из них переносят вызовы Hibernate, если это помогает.Вот типичный блок, похожий на тот, который я только что написал:

try {
    myList.add( ((myClass) commonService.getRecordByTableId(myClass.class, ID)).toString() );
} catch (ServiceException e) {
    log4j.error("Failed to retrieve record from table myClass for id " + ID);
    e.printStackTrace();
}

Здесь я извлекаю запись из базы данных и добавляю ее в список.В блоке catch я записываю то, что я считаю разумным сообщением о том, что делает блок try, и печатаю трассировку стека.Итак, мой вопрос: есть ли что-нибудь еще, что я мог / должен делать, в общем, чтобы получить лучшую информацию для диагностики ошибок?

Ответы [ 4 ]

10 голосов
/ 28 октября 2011

В обработке исключений, Ведение журнала и перебрасывание является популярным анти-паттерном .Ты не должен этого делать.Вам нужно решить, поймать ли исключение, затем правильно обработать его (включая ведение журнала) или не перехватить его и позволить перейти на более высокий уровень (или перебросить его / обернуть в исключение времени выполнения, если оно было проверенным исключением).

Если вы сделаете это (log + rethrow), то вышестоящий код не сможет узнать, что вы уже зарегистрировали исключение, и поэтому одно и то же исключение может быть зарегистрировано дважды или более, в зависимости от количества слоев.исключение должно пройти, и какой уровень произвольно решит зарегистрировать и повторно выбросить его.Это сделает чтение журналов и их непонимание полным кошмаром.

Также вы можете утверждать, что выбрасывание и перехват исключений являются дорогостоящими операциями, все эти перехват и перебрасывание не помогают вашей производительности во время выполнения.1008 * Так что, если вы решите обработать исключение, то его проглатывание будет неправильным (даже если вы регистрируете какое-то сообщение).По крайней мере, вам нужно записать трассировку:

log4j.error("Failed to retrieve record from table myClass for id " + ID, e);
4 голосов
/ 28 октября 2011

printStackTrace() не добавляет след в ваш журнал. Предоставление исключения для log4j напечатает его в ваш файл журнала, где контекст имеет смысл:

log4j.error("Failed to retrieve record from table myClass for id " + ID, e);
2 голосов
/ 28 октября 2011

Пара вещей в дополнение к тому, что упомянули другие:

  1. Использование различных уровней ведения журнала: информация;предупредить;и т. д.
  2. Исходя из # 1, я бы отбросил эти вызовы printStackTrace ().Если вы хотите регистрировать ошибки в консоли, делайте это через регистратор.Таким образом, вы получаете преимущества фильтрации уровней даже для консоли.
2 голосов
/ 28 октября 2011

Да, в самом первом блоке это должно быть так:

try {
  //Some Hibernate business here
}
catch (Exception e) {   //Yes, Exception.  That's not just me being general
  log4j.error("Fail to XXXXXX", e);   //again, real
  throw new MyException(e);
}

Java позволяет вам связывать исключения, поэтому вы должны это делать.Кроме того, при использовании Log4J вы также можете отправить исключение, чтобы оно также печатало трассировку стека исключений в ваших журналах.

...