18.03.2021, 18:26 | #1 |
Участник
|
Поймать стек вызова у долгой транзакции.
Привет.
Кто-нибудь решал задачу ловли стеков вызовов приведших к долгим транзакциям ? Как оказалось, кастомизации Application.ttsNotify* методов не помогают. Ядро там возвращает пустой стек. Как его еще можно было бы достать? Ax 2012 R3 |
|
18.03.2021, 20:09 | #2 |
Участник
|
Странно. Раньше вроде работало Анализатор незакрытых транзакций
|
|
18.03.2021, 22:51 | #3 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Странно. Раньше вроде работало Анализатор незакрытых транзакций
Это не то. Я попробовал в 2012 и 2009. Стек вызовов урезанный. Т. Е при вызове ttsbegin вызов в ttsnotify* приходит откуда то из ядра. |
|
18.03.2021, 23:35 | #4 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: Logger (1). |
19.03.2021, 03:10 | #5 |
Участник
|
Если транзакция работает в данный, можно запустить трейсинг на АОСе, потом его разобрать Trace парсером, соответственно он покажет кто что делает.
|
|
19.03.2021, 06:40 | #6 |
Участник
|
Цитата:
Я так и хотел. И этот способ не работает в 2009-й и 2012-й. Вызов в эти методы приходит из ядра. Ноэто геинформативно - Не видно стека, по которому произошел вызов ttsbegin. |
|
19.03.2021, 11:21 | #7 |
Участник
|
Оно не в cil исполняется? mfp: X++ Debugging Tips and Tricks #2 – xSession::xppCallStack()
|
|
19.03.2021, 11:41 | #8 |
Участник
|
Цитата:
Сообщение от belugin
Оно не в cil исполняется? mfp: X++ Debugging Tips and Tricks #2 – xSession::xppCallStack()
|
|
19.03.2021, 11:43 | #9 |
Участник
|
Нет, речь о p-code.
Запускаем такой джоб X++: static void Job144(Args _args) { void someMethod() { callStack2infolog(); } ; ttsBegin; // здесь в Application запоминается время начала someMethod(); // а здесь мы легко получаем стек вызовов и запоминаем его в глобальной переменной, которую чистим по завершении транзакции // нам же необязательно получить стек при начале или конце транзакции. Главное локализовать участки кода. // это попытка хоть как-то обойти потерю стека вызовов ядром при пересечении ttsBegin / ttsCommit ttsCommit; // здесь в Application запоминается время конца и идет запись времени в лог вместе со стеком вызовов } X++: // подняли из ax3.0 #localmacro.ClientPrefix "(C)" #endmacro #localmacro.ServerPrefix "(S)" #endmacro #define.PathPrefixLen (4) static void callStack2infolog( str _prefix = "", // "@SYS65092", Counter _skipLevels = 0, /* container stack = xSession::xppCallStack() //pkoz 18.02.2014 */ container stack = Stack_MRC::xppCallStack(0) ) { // container stack = xSession::xppCallStack(); TreeNodePath correctPath; TreeNodePath stackPath; Counter n; int line; ; setPrefix(_prefix); if (_skipLevels < 0) { _skipLevels = 0; } for (n = 3 + _skipLevels * 2; n <= conLen(stack); n += 2) { stackPath = conPeek(stack,n); line = conPeek(stack,n+1); correctPath = stackPath; if (line) { if ( subStr(stackPath, 1, #PathPrefixLen) == #ClientPrefix || subStr(stackPath, 1, #PathPrefixLen) == #ServerPrefix ) { correctPath = subStr(stackPath, #PathPrefixLen + 1, maxInt()); } info(strFmt("%1 %2", stackPath, line),'', SysInfoAction_Editor::newLineColumn(correctPath, line)); } else { info(strFmt("%1", stackPath),'', SysInfoAction_Editor::newLineColumn(correctPath, 1)); } } } Цитата:
(C)\Classes\Global\callStack2infolog 6
(C)\Jobs\Job144 5 а если запустить такой джоб X++: static void Job145(Args _args) { ttsBegin; ttsCommit; } \Classes\Application\ttsNotifyPostBegin такой код X++: public void ttsNotifyPostBegin() { ; if (curUserId() == "pkoz") { callStack2infolog(); } super(); ... } Цитата:
(S)\Classes\Global\callStack2infolog 6
(S)\Classes\Application\ttsNotifyPostBegin 11 Последний раз редактировалось Logger; 19.03.2021 в 11:46. |
|
19.03.2021, 11:52 | #10 |
Участник
|
Так, прошу прощенья, похоже меня обманули.
Если джоб 145 запустить на сервере через серверный менюитем, то стек вызовов не теряется. Цитата:
(S)\Classes\Global\callStack2infolog 6
(S)\Classes\Application\ttsNotifyPostBegin 11 (S)\Jobs\Job145 3 (S)\Classes\xMenuFunction\runServer |
|
19.03.2021, 11:56 | #11 |
Участник
|
Хотя нет.
В отладчике видно, если как советует Ace of Database включить точки останова на АОСе (ну понятно, если их не включить, то и остановки не будет). А вот из джоба Logger, действительно, программно стек не ловится. |
|
19.03.2021, 12:23 | #12 |
Участник
|
Набросал тестовую форму
потыкал по кнопкам в инфолог вывалилось Цитата:
Запустили ttsBegin на clicked кнопки
(S)\Classes\Global\callStack2infolog 6 (S)\Classes\Application\ttsNotifyPostBegin 11 Запустили ttsBegin в серверном методе класса вызванном с clicked метода кнопки на форме. (S)\Classes\Global\callStack2infolog 6 (S)\Classes\Application\ttsNotifyPostBegin 11 (S)\Classes\Jobs_MRC\testServer 3 (C)\Forms\Form20\Designs\DesignList\Button2\Methods\Clicked 5 Запустили ttsBegin в серверном методе класса вызванном с метода формы. (S)\Classes\Global\callStack2infolog 6 (S)\Classes\Application\ttsNotifyPostBegin 11 (S)\Classes\Jobs_MRC\testServer 3 (C)\Forms\Form20\Methods\test3 3 (C)\Forms\Form20\Designs\DesignList\Button3\Methods\Clicked 5 Запустили ttsBegin в методе формы вызванном с clicked кнопки. (S)\Classes\Global\callStack2infolog 6 (S)\Classes\Application\ttsNotifyPostBegin 11 |
|
19.03.2021, 12:24 | #13 |
Участник
|
Вывод:
Обсуждаемый баг имеет место когда ttsBegin или ttsCommit написан в клиентском X++ коде. Если писать на серверном то все ок. |
|
|
За это сообщение автора поблагодарили: S.Kuskov (5). |
19.03.2021, 12:30 | #14 |
Участник
|
Кстати, да.
В отлидчике та часть, которая на клиенте в стеке обычным шрифтом представлена, а начиная с Application.ttsNotifyPostBegin жирным. |
|
Теги |
stack trace, стек вызовов |
|
|