Зарегистрируйте исключения на этапе выполнения в Java с помощью log4j

Я в настоящее время создаю приложение с помощью Tomcat, Spring и JAVA. Я использую Log4J как моя библиотека входа. Я в настоящее время регистрирую все к текстовому файлу. Одна из проблем, которые я имею, является этим RuntimeExceptions не регистрируются ни в какие файлы. Я задавался вопросом, существует ли способ зарегистрировать все RuntimeExceptions это, возможно, брошенное в мой файл журнала приложения. Если не действительно ли возможно иметь его журнал к другому файлу журнала? Существует ли стандартный способ сделать это? Раз так есть ли стандартный способ сделать это при запуске приложения в Tomcat?

Заранее спасибо за помощь!

20
задан Bilesh Ganguly 28 April 2016 в 09:33
поделиться

3 ответа

Я не уверен, что это то, что вы ищете, но есть обработчик исключений, завершающих потоки. Это обработчик любого исключения, которое явно не перехватывается целью потока.

По умолчанию «обработчик неперехваченных исключений» просто вызывает printStackTrace () в Throwable , чтобы распечатать трассировку стека в System.err . Однако вы можете заменить this своим собственным UncaughtExceptionHandler , который вместо этого регистрирует исключение в log4j:

class Log4jBackstop implements Thread.UncaughtExceptionHandler {

  private static Logger log = Logger.getLogger(Log4jBackstop.class);

  public void uncaughtException(Thread t, Throwable ex) {
    log.error("Uncaught exception in thread: " + t.getName(), ex);
  }

}

Если вы используете среду исполнителя, в которую вы передаете Runnable , его потоки, вероятно, имеют собственный блок catch , который предотвращает попадание исключений в обработчик неперехваченных исключений. Если вы хотите перехватить исключения времени выполнения , один из способов сделать это - заключить каждую задачу в оболочку ведения журнала, например:

class Log4jWrapper {

  private final Logger log;

  private final Runnable target;

  Log4jWrapper(Logger log, Runnable target) { 
    this.log = Objects.requireNonNull(log);
    this.target = Objects.requireNonNull(target); 
  }

  public void run() {
    try {
      target.run();
    } catch(RuntimeException ex) {
      log.error("Uncaught exception.", ex);
      throw ex;
    }
  }

}

...

Runnable realTask = ...;
executor.submit(new Log4jWrapper(Logger.getLogger(Whatever.class), realTask));
22
ответ дан 30 November 2019 в 00:00
поделиться

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

Это сообщение блога дает хорошее краткое изложение того, как сделать перенаправление в FileHandler, который является отдельным от вашего регистратора.

https://blogs.oracle.com/nickstephen/entry/java_redirecting_system_out_and

2
ответ дан 30 November 2019 в 00:00
поделиться

Один из способов регистрации неперехваченных исключений RuntimeExceptions (или любых неперехваченных Throwables в этом отношении) - создать класс, реализующий Thread.UncaughtExceptionHandler . Метод этого класса uncaughtException () просто записывает сведения об исключении в журнал. Вы можете заставить JVM вызывать этот обработчик исключений всякий раз, когда неперехваченное исключение RuntimeException завершает поток, добавляя строку

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

в ваш код.

14
ответ дан 30 November 2019 в 00:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: