Как получить Java Call Stack работающего приложения
Я работаю над очень мощным веб-приложением на основе Java. Поскольку во время разработки нет правильного ведения журнала, поэтому мне очень сложно установить точку останова и отладить приложение, поскольку я не знаю порядок выполнения. Есть ли какой-либо механизм, чтобы получить полный стек вызовов из работающего java-приложения после выполнения некоторых действий.
Я долго искал его в сети, но не смог прийти к конкретному решению. Пожалуйста, предложите мне, если что-то есть для этого. Благодаря
Ответы
Ответ 1
Способ 1. Используйте утилиту jstack из командной строки (часть дистрибутива JDK).
Способ 2: отправить сигнал 3 в процесс java, он будет выгружать трассировки стека на stdout.
Способ 3. Вызов Thread.getAllStackTraces() из приложения:
public class StackTraceDumper
{
public static dumpAllStackTraces ()
{
for (Map.Entry <Thread, StackTraceElement []> entry:
Thread.getAllStackTraces().entrySet ())
{
System.out.println (entry.getKey ().getName () + ":");
for (StackTraceElement element: entry.getValue ())
System.out.println ("\t" + element);
}
}
}
Затем используйте StackTraceDumper.dumpAllStackTraces()
, где вам нужно сбросить трассировки стека.
Ответ 2
Thread.dumpStack()
Распечатывает трассировку стека текущего потока в стандартный поток ошибок.
Thread.getAllStackTraces()
Возвращает карту трассировки стека для всех живых потоков.
Thread.getStackTrace()
Возвращает массив элементов трассировки стека, представляющих дамп стека этого потока.
Ответ 3
Посмотрите Throwable.getStackTrace()
. Просто создайте новый Throwable
; вам действительно не нужно его throw
.
Ответ 4
Вы можете вызвать дамп стека, нажав Ctrl + Break или отправить сигнал 3 (в системах на базе Unix). Обратите внимание, что вы получите трассировку стека за потоки. Это приведет к стандартной ошибке, поэтому убедитесь, что ваш журнал регистрирует это.
Вы можете сделать это программно с помощью
Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();
Здесь подробнее о получении и анализе трассировок стека.
Как вы уже отметили, BTrace - еще одна возможность. Здесь ответ SO.
Ответ 5
Есть несколько вариантов:
- Запустите его в отладчике и приостановите все потоки, затем вы можете проверить их
- Используйте VisualVM для подключения к запущенным процессам и запускает дамп потока. Он поставляется с JDK.
- Используйте jstack в командной строке, чтобы сбрасывать потоки.
Добавьте в свой код базовое ведение журнала:
new RuntimeException().printStackTrace();
Это приведет к статической трассировке для stderr
Ответ 6
Почему бы вам не использовать какой-либо инструмент AOP, такой как AspectJ, для захвата этих значений и журнала? Вы можете использовать точку выполнения execute() вместе с рекомендацией after(). Для не производственного развертывания вы можете записывать все вызовы методов вместе с переданными значениями и возвращаемым значением. Это будет слишком много накладных расходов для производства. Для этого вы можете просто сохранить переданные значения (Object args [], как вы получаете в совете AspectJ) в локальной переменной и только зарегистрировать его в случае исключения. Но даже в этом случае будет некоторая оценка производительности, поскольку примитивные значения будут помещены в бокс для передачи как Object [] в ваш совет.