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

Как получить Java Call Stack работающего приложения

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

Я долго искал его в сети, но не смог прийти к конкретному решению. Пожалуйста, предложите мне, если что-то есть для этого. Благодаря

4b9b3361

Ответ 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 [] в ваш совет.