Подтвердить что ты не робот

Исключение журнала в Exception в Java с использованием log4j

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

Заранее благодарю вас за помощь!

4b9b3361

Ответ 1

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

По умолчанию "обработчик исключенных исключений" просто вызывает printStackTrace() в Throwable для печати трассировки стека на System.err. Однако вы можете заменить своим собственным 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, который предотвращает доступ исключений к обработчику неперехваченных исключений. Если вы хотите поймать исключения Runtime там, один способ сделать это - обернуть каждую задачу в обертки журнала, например:

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));

Ответ 2

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

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());

к вашему коду.

Ответ 3

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

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

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