Как сбросить трассировку стека, когда вызывается определенный метод Java? - PullRequest
3 голосов
/ 11 марта 2011

Нам нужно отладить Java-приложение, которое случайным образом выполняет то, чего не должно делать.

Чтобы понять основную причину проблемы, нам нужно было бы получать трассировку стека при каждом вызове определенного метода. Это звучит просто (добавьте Thread.dumpStack() в этом конкретном методе), однако это класс кода из JDK, поэтому мы не хотим возиться с ним (даже если бы мы могли).

Кто-нибудь знает, сможем ли мы реализовать какой-нибудь "слушатель" в JVM, который бы определял, когда вызывается определенный метод, и выводил бы трассировку стека?

Это производственная система, поэтому, если решение представляет собой отладчик, нам нужно что-то, что оказывает очень ограниченное влияние на производительность.

Спасибо за ваш вклад.

Ответы [ 7 ]

3 голосов
/ 11 марта 2011

Используйте Byteman. Он может легко внедрить код трассировки в работающий сервер. Наша команда поддержки любит это. http://www.jboss.org/byteman

1 голос
/ 11 марта 2011

"Кто-нибудь знает, можем ли мы внедрить в JVM своего рода« слушателя », который бы определял, когда вызывается определенный метод, и выводил бы трассировку стека?

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

Эти требования противоречивы.Сброс стека стоит дорого, независимо от того, как вы это делаете.ИМО, что вам действительно нужно сделать, это настроить тестовый сервер и провести там свои расследования.

FWIW, самый простой и, вероятно, наименее затратный способ сделать это - вставить один из них в качестве первого.Постановка метода:

    log.info("Method called", new Throwable());

    new Throwable("method called").printStackTrace(System.out);
0 голосов
/ 11 марта 2011

Я использовал для этой цели Java Instrumentation API .

С помощью API Java-инструментария вы можете изменять байт-код любого класса во время выполнения и добавлять некоторый код (например, AOP). Пример использования инструментов java-классов и методов во время выполнения с использованием javassist приведен на моем github.

https://github.com/kreyssel/maven-examples/tree/master/javaagent

Вы можете просто изменить LoggerAgent.java , удалить операторы регистрации и добавить свой Thread.dumpStack().

Единственное, что вы изменяете в своей рабочей среде, - это добавление jar агента в командную строку java.

-javaagent:jarpath[=options]

Еще один пост в блоге, который вы можете прочитать здесь .

0 голосов
/ 11 марта 2011

Использование Thread.currentThread().getStackTrace()

0 голосов
/ 11 марта 2011

Вместо экземпляра рассматриваемого класса используйте экземпляр java.lang.reflect.Proxy.Это позволяет вам перехватывать все вызовы методов и что-то делать, прежде чем перенаправлять их в экземпляр.

Я думаю, что это сердце как минимум 1 AOP Framework.

0 голосов
/ 11 марта 2011

Для простоты я добавляю следующую строку в мой код

log.info("Method called", new Throwable("HERE"));
0 голосов
/ 11 марта 2011

В зависимости от того, из скольких разных мест вызывается метод, вы можете поместить оболочку вокруг него и сделать дамп стека из оболочки.

...