Перенаправить PrintStackTrace на мою собственную функцию

Поэтому я разрабатываю Stacktrace inerpreter, поэтому я хочу знать, есть ли способ перенаправить все e.printStackTrace () вызывает my printTrace ()?

2 ответа

  1. Вы не можете заменить то, что e.printStackTrace()делает для всех исключений. Он не является окончательным, что означает, что он может быть переопределен в подклассах, но реализация по умолчанию просто:

    printStackTrace(System.err);
    

    Таким образом, единственное, что вы можете надеяться зацепиться там System.err.

    Вы можете заменить System.errс PrintStreamвашим собственным выбором.

    System.setErr(somePrintStream);
    

    Но это получает все отправлено System.err. Вам придется либо разобраться со всем, либо каким-то образом извлечь только следы стека ( некоторые идеи здесь ).

    Возможно, вам лучше как-то заменить все ваши e.printStackTrace()вызовы вызовами вашего метода (они имеют сомнительную ценность, в любом случае).

    Я не знаю, как лучше предложить вам сделать это; но вы могли бы, например, запретить вызовы Throwable.printStackTrace()через инструмент компилятора, такой как errorprone Google .

    Вы также можете найти инструменты для замены, основанные на выводах errorprone.

  2. Если это для удовольствия, хорошо, но если это для чего-то профессионального, вы в основном изобретаете что-то вроде Sentry, поэтому вам лучше просто заплатить за готовый инструмент.

    Как предлагает Энди Тернер , вы могли бы заменитьprintStackTrace(), но это очень грязно, а не ненадежно. Такие языки, как Javascript и Python, делают это довольно легко, но в Java это трудно, потому что это идет вразрез с философией объектно-ориентированного программирования (и бьет по ограничениям старых реализаций Java). Существует инструмент под названием Powermock, который может заменить методы. Может, стоит взглянуть.

    Помните, как я упомянул часового? Он делает это через структуру ведения журнала. printStackTrack()считается небрежным, так или иначе, поэтому люди обычно мигрируют на что-то вроде slf4j, чтобы сделать правильный журнал. Вместо печати трассировки стека, они делают LOGGER.warn("Error communicating with client {}", ipAddr, e);. На другом конце регистратора находится приложение, которое настроено для регистрации различных уровней (error, warn, info, debug, trace) и различных классов. Способ, которым Sentry делает это, это прикрепляет аппендер. Если бы вы сделали то же самое, у вас был бы крюк, чтобы просто получить e.

    Последнее: в любом случае, вы можете посмотреть в uncaughtExceptionHandler . Если вы не ловите все метательные, вы можете пропустить что-то интересное и никогда не регистрировать его.