AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
DAX
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 03.06.2018, 09:15   #1  
sukhanchik is offline
sukhanchik
Moderator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,632 / 2128 (76) +++++++++
Регистрация: 13.06.2004
Адрес: Москва
Стек вызовов в инфологе в D365FO
Всем добрый день!
На этом форуме уже несколько раз пролетала мысль про добавлении стека вызовов в инфолог (об этом упоминали разные авторы, и даже когда-то я в древности), но до версии D365FO еще не доходили. Я помню, как стек вызовов прикрутил к инфологу еще в 3.0, затем пришлось модификацию немного поменять, т.к. в 4.0 ввели упаковку данных инфолога в контейнер. Но зато в 2009 и особенно в 2012 модификация перетекла достаточно легко. Главной ее сложностью (в моем исполнении) была необходимость правки формы инфолога и класса Info, в результате чего при неаккуратной правке могло поломаться приложение. Это в общем-то основная причина, по которой я не выкладывал (и не выкладываю) ее на форум. Однако в версии D365FO, в связи с появлением понятия модели и пакета (Package), в котором создается модель – стало возможно эту модификацию сделать достаточно безопасной для инсталляции, хотя, к сожалению и пришлось немного пожертвовать удобством использования (в связи с запретом оверлеинга).

Соответственно, получилось нечто, что в целом (лично для меня) приносит больше пользы, чем вреда ). Ее еще можно дошлифовывать, но в неком «грубом представлении» вполне уже можно использовать в работе. Вполне вероятно – ошибки будут – поэтому просьба сообщать – буду править по мере сил и возможностей. Сразу скажу – разработка по времени еще не много обкатывалась, поэтому возможны какие-то недочеты, соответственно, тех, кто будут пользоваться прошу выдавать замечания – будем исследовать что можно будет сделать в разных ситуациях.

Для начала хочу сказать, что Microsoft решил «развести» уровни отображения сообщений и поэтому часть сообщений выводится на полоске при форме (в контексте формы), а часть – в верхнем меню системы. И даже об этом целых 2 странички написал в документации https://docs.microsoft.com/en-us/dyn...er-bar-details
https://docs.microsoft.com/en-us/dyn...messaging-user

Microsoft всем рекомендует использовать функции класса Message со словами, что старые добрые методы info/warning/error «Все еще поддерживаются». Логично – эти методы чуть ли не в каждом объекте, содержащем X++ написаны. Памятуя историю с устареванием RunBase в 2012 и его «возрождением» в D365FO )) – надеюсь, что в ближайшее время метод \Info\add (ну или любой его аналог, как центр сбора сообщений) не исчезнет, метод xSession::xppCallStack (или любой его аналог) тоже пока останется – ну и значит какое-то время мы сможем воспользоваться их интеграцией.
Чтобы было понятно - приведу текст класса Message (он небольшой)
X++:
public static class Message
{
    static int64 Add(MessageSeverity severity, SysInfoLogStr txt)
    {
        return infolog.insertMessage(severity, txt);
    }

    static int64 Remove(int64 messageId)
    {
        return infolog.removeMessage(messageId);
    }
}
И метод insertMessage (я пока вырезал закомментаренный код)
X++:
    int64 insertMessage(
        MessageSeverity severity,
        str _txt,
        str label = '')
    {
        int actionClassId;
        container packedAction;
        
        Exception exception;
        switch(severity)
        {
            case MessageSeverity::Informational:
                exception = Exception::Info;
                break;
            case MessageSeverity::Warning:
                exception = Exception::Warning;
                break;
            default:
                exception = Exception::Error;
                break;
        }

        if (!this.shouldAdd(exception))
        {
            return 0;
        }

        // Raise the message event if there are consumers and the event capturing is enabled
        if (enableMinimumLevelInfologRaiseMessageEvent && (exception >= minimumLevelInfologRaiseMessageEvent))
        {
            this.onMessageAdd(exception, _txt);
        }
        return super(severity, getprefix()+_txt, this.GetLabelContext(_txt));
    }
Ну т.е. мы видим, что класс Message хоть и обходит в явном виде \Info\add - все равно есть возможность встроиться в делегат OnMessageAdd, который также вызывается и из \Info\add.

На него можно подписаться и т.о. получить информацию о сообщении. Правда этот делегат был сделан исключительно для запуска тестов и для того, чтобы воспользоваться надо в классе Info включить режим сбора событий (можно посмотреть ссылки на этот метод). Но этот режим влияет исключительно только на возможность подписки на этот делегат (опять-таки- смотрим код), поэтому в целом мы для себя вполне можем его использовать.

Соответственно, при реализации стека вызовов в инфологе глобально была применена идея включения режима перехвата событий, перехват событий и запись их с добавлением информации по стеку вызовов (стек вызовов я не очищал от вызова непосредственно перехватчика – лично меня эта строчка не напрягает, а все желающие могут если захотят сами это доделать).
Заодно решилась проблема чтения длинных соообщений в инфологе, текст которых в полоске на форме был неудобочитаем (по крайней мере для меня).

Соответственно, как работает моя модификация:
1. В параметры пользователя добавлен флажок «Стек вызовов». Включение флажка включает режим логирования сообщений инфолога. Логируется только то, что проходит через \Info\add. Соответственно, бывают ситуации, когда сообщения не залогировались, -но я пока не отловил эти ситуации. Выключение флажка очищает лог текущего пользователя. В роли лога выступает обычная таблица в БД. Пользователи разделяются в ней по полю CreatedBy.
2. При помощи делегата OnMessageAdd сообщения собираются в таблицу лога (Лог чистится только при выключении флажка у пользователя. Я пытался его очищать на событии OnClear у инфолога – пока это не дало результата. Соответственно, если будут какие-нибудь предложения / мысли на эту тему – с интересом ознакомлюсь).
3. Данные таблицы лога отображаются на форме. Форма вызывается с вкладки OPTIONS (ПАРАМЕТРЫ), которая является общей для почти всех форм в D365FO (за исключением диалоговых и может еще каких-нибудь сильно специализированных). При отключенном флажке у пользователя – вызов формы стека вызовов не показывается на этой вкладке (чтобы не смущать пользователей системы), поэтому после включения флажка в параметрах пользователя – нужно открыть какую-нибудь форму с вкладкой ПАРАМЕТРЫ для вызова формы лога стека вызовов.
4. Делегат OnMessageAdd работает только для роли «Системный администратор», поэтому для возможности собрать стек вызовов для пользователя без этой роли я добавил в модификацию специальную роль CallStack, а в коде пришлось временно (в момент включения режима сбора сообщений) обмануть функцию Global::isSystemAdministrator(), заставив временно ее вернуть истину на момент включения режима и «вернуть как было» после момента включения режима.
Меточный файл не делал, хватило стандартных существующих меток.
Прикладываю .axmodel-файл и .axpp-файл

Нажмите на изображение для увеличения
Название: SNAG_Program-0058.png
Просмотров: 186
Размер:	32.8 Кб
ID:	11934

Нажмите на изображение для увеличения
Название: SNAG_Program-0054.png
Просмотров: 189
Размер:	44.1 Кб
ID:	11935

Нажмите на изображение для увеличения
Название: SNAG_Program-0056.png
Просмотров: 191
Размер:	47.1 Кб
ID:	11936

Нажмите на изображение для увеличения
Название: SNAG_Program-0057.png
Просмотров: 197
Размер:	63.2 Кб
ID:	11937

CallStack-VSUH.axmodel
CallStack.axpp
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 03.06.2018 в 13:41.
За это сообщение автора поблагодарили: skuull (2), raz (10), EVGL (10), AlexSD (4), trud (5), mazzy (10), axotnik88 (1), Logger (15), Jorj (1), gl00mie (10).
Старый 04.06.2018, 01:49   #2  
AlexSD is offline
AlexSD
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
235 / 243 (9) ++++++
Регистрация: 14.10.2003
У меня есть пара мыслей.

1. Добавить периодическую операцию по очистке старых сообщений. Что бы можно было бы включить постоянный лог для пользователей, под которыми работают интеграции
2. Добавить фильтр по типу сообщений, какие сохранять в лог, какие игнорировать.
За это сообщение автора поблагодарили: mazzy (2), sukhanchik (2).
Старый 04.06.2018, 08:04   #3  
skuull is offline
skuull
Участник
Most Valuable Professional
Лучший по профессии 2014
 
517 / 502 (18) +++++++
Регистрация: 08.03.2013
Адрес: ХЗ
Цитата:
Сообщение от AlexSD Посмотреть сообщение
У меня есть пара мыслей.

1. Добавить периодическую операцию по очистке старых сообщений. Что бы можно было бы включить постоянный лог для пользователей, под которыми работают интеграции
2. Добавить фильтр по типу сообщений, какие сохранять в лог, какие игнорировать.
Добавляйте, мы вам спасибо скажем. И на гитхаб!
За это сообщение автора поблагодарили: sukhanchik (2).
Старый 05.06.2018, 01:40   #4  
AlexSD is offline
AlexSD
Microsoft Dynamics
Сотрудники Microsoft Dynamics
 
235 / 243 (9) ++++++
Регистрация: 14.10.2003
Метод SysSystemDefinedButtonsCallStack_Extension.getFormRunExt() может вернуть null, но нигде это не проверяется.
Хотя, я смотрю в SysSystemDefinedButtons... там та же история. Код был оттуда скопирован. Не уделяют должного внимания ревью кода в Microsoft. Видимо, комитменты поменялись. "При Балмере такого не было"
За это сообщение автора поблагодарили: sukhanchik (2).
Старый 08.06.2018, 20:13   #5  
sukhanchik is offline
sukhanchik
Moderator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,632 / 2128 (76) +++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от AlexSD Посмотреть сообщение
У меня есть пара мыслей.

1. Добавить периодическую операцию по очистке старых сообщений. Что бы можно было бы включить постоянный лог для пользователей, под которыми работают интеграции
2. Добавить фильтр по типу сообщений, какие сохранять в лог, какие игнорировать.
Спасибо за идеи. Если найду окошко у себя - постараюсь реализовать. Ну или еще кто-то раньше меня сделает.

Цитата:
Сообщение от AlexSD Посмотреть сообщение
Метод SysSystemDefinedButtonsCallStack_Extension.getFormRunExt() может вернуть null, но нигде это не проверяется.
Хотя, я смотрю в SysSystemDefinedButtons... там та же история. Код был оттуда скопирован. Не уделяют должного внимания ревью кода в Microsoft. Видимо, комитменты поменялись. "При Балмере такого не было"
Верно. Код был скопирован без должного рефакторинга. Опять-таки - посмотрю по своей загруженности - получится - подправлю.

В общем - я рад, что идея нашла поддержку в сообществе. Значит - есть потребность )
Спасибо.
__________________
Возможно сделать все. Вопрос времени
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как программно получить стек вызовов? Bega DAX: Программирование 2 22.12.2010 18:46
aEremenko: Стек вызовов в DAX 2009 Blog bot DAX Blogs 3 08.05.2009 09:38
Как получить стек вызовов без изменения кода? Ilia# DAX: Программирование 2 24.01.2006 11:04
Как получить стек вызовов? bucken DAX: Программирование 6 03.08.2005 15:24
Как получить стек вызовов ? Dmitryus DAX: Программирование 1 26.07.2004 12:20
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:00.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.