В данной статье посмотрим некоторые часто встречающиеся приёмы, а также посмотрим наличие к ним стандартной документации (справка тут Auding and Logging). В данной статье будут рассмотрены прежде всего стандартные инструменты. Все код-листинги доступны на github в ZABAPFILEOS_07; видео к SLG1.
Типы логирований в SAP NetWeaver
Можно выделить 3 типа логирования (журналирования):
1) Системное: сбор информации о событиях в системе: правка под отладкой, изменение настроек, вызов HTTP и т. д.
2) Журнал приложения (application): это журнал, встроенный в приложение, куда информация пишется и читается по некоторому id‑бизнес сущности (заказ, поставка, FI‑документ и т. д.)
3) Трассировка приложений (подробный системный лог по требованию): подробный лог, который может активироваться и деактивироваться на пользователя, процесс, задание. Используется в инструментах трассировки ABAP‑кода, SQL‑запросов, RFC/HTTP‑соединений, проверок полномочий.
В первой части статьи мы рассмотрим журналы приложений, а во второй – системные логи.
Часть1. Использование журналов приложений
Рассмотрим следующие логи, используемые в бизнес-приложениях
1. Business Application Log (транзакция SLG1 / SLG0 / SLG2)
2. Change documents (транзакция SCDO)
3. SCU3 Table History Log
4. Отображение изменений при правке таблиц через SE16N
Немного затронем такие логи
1. IDOC-logs
2. Output в SD/MM (NAST-based)
3. ODATA-segw logs
4. SXI_MONITOR XI: Message Monitoring
5. Workflow Execution (транзакция SWI5)
Логи приложений ориентированы на сбор информации о действиях конкретного бизнес-объекта (заказа на закупку, финансового документа, или других действий пользователя, связанных с обработкой именно бизнес-данных).
Business Application Log (BAL) – SLG1 / SLG0 / SLG2
Лог приложений (Business Application Log) является наиболее универсальным и часто используемым в приложениях, однако не единственным. Имеет множество API и встроенные интерактивные функции. Документация к этому функционалу доступна по ссылке. Также этому функционалу посвящено множество статей и выделен отдельный пакет (SZAL) с демо-программами внутри SAP-системы (их маска SBAL_DEMO_*). Как видно, это хорошо задокументированный функционал, что повышает его привлекательность.
В системе и среди разработок энтузиастов существует множество обёрток (wrappers) над этим логом. Моя рекомендация: не делайте еще одну обёртку сверху (это трата времени) – лучше используйте существующие обёртки (их вполне достаточно и весьма достойные). Один из примеров IF_RECA_MESSAGE_LIST (на основе класса CF_RECA_MESSAGE_LIST); пример описан по ссылке, а также множество примеров в системе. Давайте рассмотрим несколько важных достоинств BAL-функционала. В примерах я буду ссылаться на стандартные DEMO-программы, поэтому Вы всегда можете посмотреть реализацию той или иной опции и реализовать её в своем решении.
Возможность иерархичного накапливания и представления сообщений. Лог дает возможность накапливать и отображать данные не в одной куче, а к какому-либо признаку (сущности), в которой в свою очередь могут быть под-сущности, у которой тоже под-сущности. Это позволяет не запутаться в сообщениях; кроме того, мы можем фильтровать сообщения по степени критичности, что тоже улучшает понимание логов. Для показа этой возможности запустим программу SBAL_DEMO_04_DETLEVEL в режиме ALV.
Мы можем отображать логи в виде дерева и отображать (фильтровать) сообщения только те, которые относятся к нужной «ветке-сущности». Также можем отображать лог по степени критичности сообщений.
![Рис. 1 Возможность иерархичного накапливания и представления сообщений в просмотре BAL (Business Appl Log) Рис. 1 Возможность иерархичного накапливания и представления сообщений в просмотре BAL (Business Appl Log)](https://habrastorage.org/getpro/habr/upload_files/261/02b/694/26102b69451e832e175eae3ca419dfdf.png)
Отображение в различных форматах.
ApplicationLog можно отобразить отдельным окном, встроенное окном, в качестве POPUP, а также custom-окно (как модальное, которое блокирует родительские окно), так и немодальное (которое не блокирует). Для просмотра этих возможностей запустим программу SBAL_DEMO_04.
![Рис. 2 Различные форматы отображения лога Рис. 2 Различные форматы отображения лога](https://habrastorage.org/getpro/habr/upload_files/e45/641/462/e45641462f504b7c66f061cd0791b9f4.png)
![Рис. 3 Древовидное отображение лога (опция Display Logs) Рис. 3 Древовидное отображение лога (опция Display Logs)](https://habrastorage.org/getpro/habr/upload_files/773/b33/076/773b330769f3caef798b9a3dfbeee3cb.png)
![Рис. 4 Встроенное через подэкран отображение лога (опция In Subscreen) Рис. 4 Встроенное через подэкран отображение лога (опция In Subscreen)](https://habrastorage.org/getpro/habr/upload_files/a10/0fc/89c/a100fc89c4a75d178da61f5f3fd27f19.png)
![Рис. 5 Модальное отображение лога (POPUP) с блокировкой родительского окна Рис. 5 Модальное отображение лога (POPUP) с блокировкой родительского окна](https://habrastorage.org/getpro/habr/upload_files/cfe/de1/150/cfede1150bfc07dabae0a01b5a8c1d11.png)
Возможность сохранения в базу в том числе с доп.данными любой структуры.
В демо-программе SBAL_DEMO_05 и SBAL_DEMO_06 показано, как можно сохранять лог в базу данных с последующим отображением в SLG1. В программе SBAL_DEMO_06 показано, как можно сохранять доп.данные к логу.
![Рис. 6 Сохранение доп.данных к логу и последующее отображение в базе данных Рис. 6 Сохранение доп.данных к логу и последующее отображение в базе данных](https://habrastorage.org/getpro/habr/upload_files/b0f/7df/0c7/b0f7df0c75c139ef597cd81710789db5.png)
Когда у нас сохранены к определенному сообщению данные, то появляется спец.пиктограмма, по нажатию на оной появляется доп.экран. Доп.данные сохраняются через INDX-like таблицу BAL_INDX, где ключом является номер журнала и номер сообщения внутри журнала.
![Рис. 7 Сохранение доп. данных к номеру сообщения Рис. 7 Сохранение доп. данных к номеру сообщения](https://habrastorage.org/getpro/habr/upload_files/2b7/d93/2fa/2b7d932fa6a6271e7103dc6886cb0bbf.png)
Возможность расширять экран кнопками и доп.переходами с помощью callback.
В журнал встроена возможность добавить свои callback и тем, самым мы можем: добавить custom-кнопки для отображения лога, добавить свой обработчик на функцию открытия сообщения и другие callback. Возможные callback приведены в программе SBAL_CALLBACK (там же можете найти программную реализацию).
![Рис. 8 Возможные callback для журнала Рис. 8 Возможные callback для журнала](https://habrastorage.org/getpro/habr/upload_files/bc6/7fc/a28/bc67fca28ada615ccafd363aad476dda.png)
![Рис. 9 Элементы с custom-обработчиком события Рис. 9 Элементы с custom-обработчиком события](https://habrastorage.org/getpro/habr/upload_files/859/968/12c/85996812c3bc947a8348e8370c941ebb.png)
Теперь при нажатии веток, сообщений и кнопок, у меня есть возможность перехода в другие транзакции, отображение смежных данных в более сложных структурах, а также перехода в другие логи и даже системы 😊.
В статье обозначил те, возможности, которые показались мне наиболее часто применимыми. Если хотите посмотреть и другие возможности, то откройте пакет SZAL (не SBAL, а именно SZAL) через транзакцию SE80 и посмотрите программы SBAL_DEMO*.
![Рис. 10 DEMO-примеры для Application Log, встроенные в систему Рис. 10 DEMO-примеры для Application Log, встроенные в систему](https://habrastorage.org/getpro/habr/upload_files/181/431/d24/181431d24cde358aa52b577ab59f9496.png)
Удаление логов
При работе с журналом SBAL нужно иметь ввиду, что они периодически должны очищаться. Очистку также можно настроить по разным параметрам. Делается это через транзакцию SLG2. При использовании лога в приложениях у нас есть возможность указания expired time (время актуальности) той или иной записи. Задание может работать в фоновом режиме.
![Рис. 11 Экран стандартной программы (транзакция SLG2) для удаление просроченных логов Рис. 11 Экран стандартной программы (транзакция SLG2) для удаление просроченных логов](https://habrastorage.org/getpro/habr/upload_files/695/933/dbe/695933dbe763563309b013dd2d373bf6.png)
Пример сustom-объекта в BAL.
Рассмотрим простой пример настройки и использования лога по шагам. Пусть у нас есть некая программа, которая запрашивает данные в системе ABFOS по HTTP-протоколу (Advanced Business Flexible Operational Server – это учебный сервер на основе nginx, созданный специально для целей демонстрации, прототипирования и тестирования ERP-задач). Система SAP ERP отправляет запрос по HTTP-протоколу с параметром (для текущего примера: ОЗМ/продукт и дата) и получает прогноз продаж на этот материал. Наша задача с помощью Application Log сделать объект и залогировать request-response в понятном виде, а также отобразить это пользователю.
Создадим основной объект: пусть в нашем случае он будет называться ZABFOS– Advanced Business Flex Operational System, и подобъект: ZFORECAST (вычисления прогноза с помощью AI / ИИ). Для этого запустим транзакцию SLG0 и нажмем New Entry (Создать).
![Рис. 12 Создание объекта для логирования в SLG0 Рис. 12 Создание объекта для логирования в SLG0](https://habrastorage.org/getpro/habr/upload_files/e59/6d7/525/e596d7525b73d6039c1b2b6ba35f369f.png)
Затем, выделив строку с ZABFOS дважды, кликнем на под-папке Sub-Objects.
![Рис. 13 Переходим к подобъектам Рис. 13 Переходим к подобъектам](https://habrastorage.org/getpro/habr/upload_files/cec/cba/270/ceccba270d3ba9201d125c31fda9ca27.png)
С помощью кнопки New Entry (Создать). В качестве подобъекта указываем ZFORECAST и текст: вычисления прогноза с помощью AI / ИИ, как на скриншоте ниже.
![Рис. 14 Указываем параметры подобъекта Рис. 14 Указываем параметры подобъекта](https://habrastorage.org/getpro/habr/upload_files/2ef/67f/ba9/2ef67fba99c694ac0b4d9b7f7cf773cb.png)
Для логирования будем использовать класс на базе интерфейса IF_RECA_MESSAGE_LIST (замечательная статья про это тут), а для сохранения составных данных (complex data) будем использовать таблицу BAL_INDX. Метод по сохранению complex data будет выглядеть как на код-листинге ниже, а полный код программы доступен здесь.
METHOD save_complex.
DATA lv_json_http_info TYPE string.
DATA lv_lognumb_ext TYPE balognr.
lv_lognumb_ext = mo_msg_list->md_extnumber && mv_complex_counter.
mv_complex_counter = mv_complex_counter + 1.
lv_json_http_info =
/ui2/cl_json=>serialize(
EXPORTING
data = iv
).
EXPORT http_call_json = lv_json_http_info
TO DATABASE bal_indx(al)
" ID g_lognumber. "
ID lv_lognumb_ext.
MESSAGE s004(zabfos_msg) WITH lv_lognumb_ext INTO sy-msgli.
me->add_prev_msg( ).
ENDMETHOD.
При http-вызове сохраняется запрос, код ответа, и полное сообщение ответа. Показано в код-листинге (инклюд, который содержит вызовы для ABFOS).
METHOD _log_httpcall.
MESSAGE s002(zabfos_msg)
WITH ms_http_call-req_method ms_http_call-req_path
INTO sy-msgli.
mo_log->add_prev_msg( ).
MESSAGE s003(zabfos_msg) WITH
ms_http_call-resp_code ms_http_call-resp_reason
INTO sy-msgli.
mo_log->add_prev_msg( ).
mo_log->save_complex( ms_http_call ).
ENDMETHOD.
А для отображения составного типа данных мы «прикрутим» callback при просмотре сообщения. Для этого в профиле просмотра укажем функциональный модуль в качестве callback. Это нам даст возможность «перехватить» обработку при двойном клике по сообщению. Полный текст программы доступен здесь для log.
ls_display_profile-clbk_ucbf-userexitp = ''.
ls_display_profile-clbk_ucbf-userexitf = 'Z_AF07_SBAL_CALLBACK_BEFORE'.
ls_display_profile-clbk_ucbf-userexitt = const_callback_function.
ls_display_profile-clbk_ucaf-userexitp = ''.
ls_display_profile-clbk_ucaf-userexitf = 'Z_AF07_SBAL_CALLBACK_AFTER'.
ls_display_profile-clbk_ucaf-userexitt = const_callback_function.
В самом функциональном модуле может быть любая обработка (в зависимости от потребности и ситуации). В нашем случае мы просто читаем из INDX-таблицы http-запрос-ответ и отображаем в HTML-браузере.
FUNCTION z_af07_sbal_callback_before.
*"----------------------------------------------------------------------
*"*"Local Interface:
" CHANGING "
" REFERENCE(C_S_USER_COMMAND_DATA) TYPE BAL_S_CBUC"
*"----------------------------------------------------------------------
DATA lc_complex_data_mark TYPE string VALUE 'Complex save id:'.
DATA lv_trg_id TYPE string.
DATA lv_log_id_indx TYPE balognr.
DATA lv_http_info_json TYPE string.
DATA html_xstring TYPE xstring.
IF c_s_user_command_data-ucomm EQ '&IC1'.
IF c_s_user_command_data-list_msgh-log_handle IS NOT INITIAL
AND c_s_user_command_data-list_msgh-msgnumber IS NOT INITIAL.
IF c_s_user_command_data-list_value CS lc_complex_data_mark.
lv_trg_id = c_s_user_command_data-list_value.
REPLACE ALL OCCURRENCES OF lc_complex_data_mark IN lv_trg_id WITH ''.
CONDENSE lv_trg_id NO-GAPS.
lv_log_id_indx = lv_trg_id.
IMPORT http_call_json = lv_http_info_json
FROM DATABASE bal_indx(al)
ID lv_log_id_indx
IGNORING STRUCTURE BOUNDARIES
.
TRY .
CALL TRANSFORMATION sjson2html SOURCE XML lv_http_info_json
RESULT XML html_xstring.
cl_abap_browser=>show_html(
html_string = cl_abap_codepage=>convert_from( html_xstring )
).
c_s_user_command_data-ucomm_exec = abap_true.
CATCH cx_root.
ENDTRY.
ENDIF.
ENDIF.
ENDIF.
ENDFUNCTION.
Обращаю внимание, что для логирования и отображения мы используем полностью концепцию и хранилище SLG1.
Теперь, когда мы щелкнем дважды по сообщению, то у нас будет открываться HTML-браузер c подробным логом (столько данных, сколько мы хотели). Пакет с демонстрационными данными (включая конфигурацию nginx, rust-реализацию ABFOS) опубликован в репозитарии на github.
![Рис. 15 Application Log может быть дополненин своим экраном просмотра и колбэками. Рис. 15 Application Log может быть дополненин своим экраном просмотра и колбэками.](https://habrastorage.org/getpro/habr/upload_files/b9b/805/7b5/b9b8057b52ffc97bb93ea88713d0eeb2.png)
При работе с логами (тем более с подробными) нужно помнить про их чистку и длительность хранения. Это делается через транзакцию SLG2. HTTP-вызовы можно также смотреть через трассировку SMICM, но об этом в части системных логов.
Change documents (транзакция SCDO)
В системе есть мощный функционал Change Document Objects (транзакция SCDO {последний символ - буква, а не цифра; от слова Objects}), который использует таблицы CDHDR и CDPOS. Этот функционал записывает изменения к полям транзакционных таблиц и зачастую привязан к стандартным транзакциям. Его удобство заключается в структурированности и чёткой технической привязкой к конкретным полям бизнес-сущностей. Для просмотра журнала изменений можно использовать программу RSSCD200 (для стандартных объектов, как правило, выведено в пункт меню).
Пример из FB02/FB03.
![Рис. 16 переход к Document Changes Рис. 16 переход к Document Changes](https://habrastorage.org/getpro/habr/upload_files/41b/3eb/54b/41b3eb54baa637b45b7adf315fc7f8ac.png)
Мы можем посмотреть в разрезе технических данных какие поля и как изменились.
![Рис. 17 Отображение данных в Document Changes Рис. 17 Отображение данных в Document Changes](https://habrastorage.org/getpro/habr/upload_files/56d/312/48e/56d31248ea71c6fd98785e872ffbe311.png)
Чтобы узнать идентификатор стандартного объекта – нужно поставить точку останова в ФМ CHANGEDOCUMENT_READ_HEADERS и посмотреть переменную OBJECTCLASS. Видим, что для FI-документа объект для change documents = BELEG.
![Рис. 18 Точка останова в ФМе CHANGEDOCUMENT_READ_HEADERS, чтобы узнать id стандартного объекта Рис. 18 Точка останова в ФМе CHANGEDOCUMENT_READ_HEADERS, чтобы узнать id стандартного объекта](https://habrastorage.org/getpro/habr/upload_files/6b7/5a0/c3f/6b75a0c3f0ac2b43bf91053512882fae.png)
А теперь через программу RSSCD200.
![Рис. 20 Просмотр данных изменения через программу Рис. 20 Просмотр данных изменения через программу](https://habrastorage.org/getpro/habr/upload_files/c15/8b8/49c/c158b849cb731459896d8d28b0c41385.png)
Давайте посмотрим, как использовать этот способ логирования, пошагово создав свой бизнес-объект.
Создадим объект «прототип продукта», который состоит из 4х таблиц (для целей демонстрации). Одна таблица заголовочная, 3 таблицы раскрывают аспект прототипа: какие характеристики у прототипа могут быть, какие материалы нужны и какие услуги нужны для создания определенного количества прототипа. Поля описаны в таблицах ниже. Для целей демонстрации важно, что таблиц несколько и есть различные поля, которые могут обновляться в разное время. Но всё это составляет единый бизнес-объект, который мы и используем для change documents. Демо-программа для обновления составлена так, что часть данных будет меняться, часть добавляться, а часть удаляться, и какая-то часть не будет меняться. Её можно использовать как опору для своих ТЗ или разработок (если есть замечание – прошу дать знать через комментарий или issue).
Чтобы поле отражалось в change documents – на элементе данных должно быть установлено значение Change Documents. В моем custom-примере эта галочка стоит на каждом элементе данных.
![Рис. 21 Чтобы поле отразилось в change documents - на элементе данных должна стоять галочка Change Documents. Рис. 21 Чтобы поле отразилось в change documents - на элементе данных должна стоять галочка Change Documents.](https://habrastorage.org/getpro/habr/upload_files/d2a/046/f42/d2a046f4209c42564413a7d8cfa420e2.png)
Заголовок прототипа продукта (Prototype Header ) ZTAF07_PROTO_H | ||
Поле | Комментарий | Техн.тип |
PROTO_PRODUCT_ID | Id-прототипа | CHAR(10) |
PROTO_PRODUCT_TXT | Краткое текстовое описание прототипа | CHAR(80) |
BEGIN_WORK_DATE | Дата начала работ на прототипом (самая ранняя) | DATS(8) |
ANALYSIS_DATE | Дата представления | DATS(8) |
ESTIMATE_DATE | Дата оценки Ближайшая дата, когда оценивается затраты на прототип (цена-затраты-качество) | DATS(8) |
MARKET_DATE | Дата выхода на рынок Возможная ближайшая дата вывода прототипа на рынок (хотя на фокус-группу); показ с целью продажи внешним потребителям | DATS(8) |
RESPONSIBLE_TEAM | Ответственная команда | CHAR(20) |
PRODUCT_OWNER | Ответственный руководитель | CHAR(20) |
QA_TEAM | Команда Контроля качества | CHAR(20) |
TARGET_CONSUMER_GRP | Целевая группа пользователей/потребителей | CHAR(25) |
Характеристики продукта (Prototype Features (Plan/Actual)): ZTAF07_FEATURES | ||
Поле | Комментарий | Техн.тип |
PROTO_PRODUCT_ID | Id-прототипа, ключевое поле | CHAR(10) |
PROTO_FEATURE | Характеристика/свойство прототипа, ключевое поле | CHAR(30) |
PLAN_FEATURE_VAL | Плановое значение характеристики | CHAR(10) |
ACT_FEATURE_VAL | Фактическое значение характеристики (на дату анализа) | CHAR(10) |
COMPLEXITY_LVL | Сложность достижения целевого значения характеристики (от 1 до 100) | INT1(3) |
CONSUMER_YES_LVL | Вероятность покупки потребителем, когда это свойство с целевым значением есть (от 1 до 100) | INT1(3) |
CONSUMER_NO_LVL | Вероятность отказа от покупки, если этого свойства с этим значением нет (от 1 до 100) | INT1(3) |
Компоненты, необходимые для продукта (Prototype Material Components): ZTAF07_COMPNENTS | ||
Поле | Комментарий | Техн.тип |
PROTO_PRODUCT_ID | Id-прототипа, ключевое поле | CHAR(10) |
COMP_POSNR | Номер позиции, ключевое поле | NUMC(6) |
PROTO_QUAN | Результирующее количество прототипируемого продукта | QUAN(15.3) |
PROTO_UOM | Единица измерения продукта-прототипа | UNIT(3) |
COMPONENT | Обозначение компонента (~matnr + free text) | CHAR(20) |
COMPONENT_QUAN_UOM | Единица измерения компонента | UNIT(3) |
COMPONENT_QUAN_PLAN | Плановая потребность в компоненте для результирующего количества | QUAN(15.3) |
COMPONENT_QUAN_ACT | Фактическая потребность в компоненте для результирующего количества | QUAN(15.3) |
COMP_UNIT_PRICE_MIN | Минимальная рыночная цена на компонент | CURR(15.2) |
COMP_UNIT_PRICE_MAX | Максимальная рыночная цена на компонент | CURR(15.2) |
COMP_UNIT_PRICE_AVG | Средняя рыночная цена на компонент | CURR(15.2) |
COMP_WAERS | Валюта цены компонента | CUKY(5) |
Услуги, необходимые для прототипа продукта (Prototype Services): ZTAF07_SERVICES | ||
Поле | Комментарий | Техн.тип |
PROTO_PRODUCT_ID | Id-прототипа, ключевое поле | CHAR(10) |
SERV_POSNR | Номер позиции, ключевое поле | NUMC(6) |
PROTO_QUAN | Результирующее количество прототипируемого продукта | QUAN(15.3) |
PROTO_UOM | Единица измерения продукта-прототипа | UNIT(3) |
SERVICE | Обозначение услуги | INT4(10) |
SERVICE_HOURS_PLAN | Плановая продолжительность услуги в часах | INT4(10) |
SERVICE_HOURS_ACT | Фактическая продолжительность услуги в часах | INT4(10) |
SERVICE_AMOUNT_PLAN | Плановая стоимость за услугу | CURR(15.2) |
SERVICE_AMOUNT_ACT | Фактическая стоимость за услугу | CURR(15.2) |
SERVICE_WAERS | Валюта стоимости услуги | CUKY(5) |
Для наглядности на каждую таблицу сделаем свой тип таблицы; а если не хотите создавать на каждую таблицу отдельный тип, то AnyTabpUpdateTask поможет Вам 😊. У нас будет такой набор объектов: таблица БД и на каждую БД свой тип таблицы.
![Рис. 22 Набор объектов после начального создания таблиц Рис. 22 Набор объектов после начального создания таблиц](https://habrastorage.org/getpro/habr/upload_files/88c/390/ac7/88c390ac7bf37786f61d5092bc1da81b.png)
Также создадим простой функциональный модуль обновления для этих таблиц баз данных.
FUNCTION z_af07_proto_upd_bustabs.
*"----------------------------------------------------------------------
*"*"Update Function Module:
*"
" Local Interface: "
" IMPORTING "
" VALUE(IT_PROTO_H) TYPE ZTTAF07_PROTO_H OPTIONAL "
" VALUE(IT_FEATURES) TYPE ZTTAF07_FEATURES OPTIONAL "
" VALUE(IT_COMPONENTS) TYPE ZTTAF07_COMPNENTS OPTIONAL "
" VALUE(IT_SERVICES) TYPE ZTTAF07_SERVICES OPTIONAL "
" VALUE(IV_MODE) TYPE UPDKZ_D DEFAULT 'A' "
"---------------------------------------------------------------------- "
CONSTANTS lc_all_reload TYPE updkz_d VALUE 'A'.
CONSTANTS lc_modify TYPE updkz_d VALUE 'M'.
CONSTANTS lc_delete TYPE updkz_d VALUE 'D'.
FIELD-SYMBOLS <fs_prot_h> TYPE ztaf07_proto_h.
CASE iv_mode.
WHEN lc_all_reload.
LOOP AT it_proto_h ASSIGNING <fs_prot_h>.
DELETE FROM ztaf07_proto_h WHERE proto_product_id = <fs_prot_h>.
DELETE FROM ztaf07_features WHERE proto_product_id = <fs_prot_h>.
DELETE FROM ztaf07_compnents WHERE proto_product_id = <fs_prot_h>.
DELETE FROM ztaf07_services WHERE proto_product_id = <fs_prot_h>.
ENDLOOP.
MODIFY ztaf07_proto_h FROM TABLE it_proto_h.
MODIFY ztaf07_features FROM TABLE it_features.
MODIFY ztaf07_compnents FROM TABLE it_components.
MODIFY ztaf07_services FROM TABLE it_services.
WHEN lc_modify.
MODIFY ztaf07_proto_h FROM TABLE it_proto_h.
MODIFY ztaf07_features FROM TABLE it_features.
MODIFY ztaf07_compnents FROM TABLE it_components.
MODIFY ztaf07_services FROM TABLE it_services.
WHEN lc_delete.
DELETE ztaf07_proto_h FROM TABLE it_proto_h.
DELETE ztaf07_features FROM TABLE it_features.
DELETE ztaf07_compnents FROM TABLE it_components.
DELETE ztaf07_services FROM TABLE it_services.
WHEN OTHERS.
ENDCASE.
ENDFUNCTION.
Сделаем программу, которая будет заполнять таблицы начальными сгенерированными данными (доступна по ссылке). А теперь создадим CHANGE DOCUMENT для фиксации изменений в данных бизнес-сущности Прототип. Запускаем транзакцию SCDO; указываем имя объекта (в нашем случае ZPROTOTYPE) и нажимаем «Создать».
![Рис. 23 Начинаем созданием Change Document Рис. 23 Начинаем созданием Change Document](https://habrastorage.org/getpro/habr/upload_files/88f/62a/9b8/88f62a9b80c9d3f63678565ae86e25ea.png)
Вводим название объекта и отмечаем нужные галочки (пояснения даны в таблице).
![Рис. 24 Устанавливаем нужные свойста change document (документ изменений) Рис. 24 Устанавливаем нужные свойста change document (документ изменений)](https://habrastorage.org/getpro/habr/upload_files/412/bf2/5a1/412bf25a1a1db324282eb7617b951173.png)
Int.Table | Возможность передавать множественные значения (то есть во внутренней таблице). |
Delete Documentation | Логирование удаления записей. Система будет анализировать и удаление в том числе.
Если отмечена эта галочка Single Field, то значит удаление будет отображено по каждому полю. Если галочки не будет, то система в логах отобразит факт удаления записи по ключу, а значения полей отображать не будет. Чем детальнее записывается, тем быстрее растет база. |
Insert / Single Field | Логирование вставки записи: либо по каждому полю (если галка отмечена), либо указание факта вставки с указанием только ключа. |
![Рис. 25 Пример, чем отличается наличие и отсутствие галочки Single Field для Insert и Delete Рис. 25 Пример, чем отличается наличие и отсутствие галочки Single Field для Insert и Delete](https://habrastorage.org/getpro/habr/upload_files/dc9/dcd/fe5/dc9dcdfe558a52247f01eac65b21fe29.png)
Затем нажимаем Generate. Цель этого действия сгенерировать (или обновить) функциональный модуль, который будет обновлять CDHDR и CDPOS (лучше для этого действия выделять отдельную группу функцию; генерация отдельной группы функций – будет предложена дальше).
![Рис. 26 Нажимаем кнопку Generate Рис. 26 Нажимаем кнопку Generate](https://habrastorage.org/getpro/habr/upload_files/0a4/09e/644/0a409e64430d94136a921615171586a1.png)
Затем подтверждаем ввод
![Рис. 27 Подтверждаем ввод Рис. 27 Подтверждаем ввод](https://habrastorage.org/getpro/habr/upload_files/fc3/83e/545/fc383e54565d43163f940485e442d07c.png)
Указываем нужные параметры или подтверждаем предлагаемые по умолчанию. Жмем Generate.
![Рис. 28 Указываем параметры новой группы функций/функционального модуля Рис. 28 Указываем параметры новой группы функций/функционального модуля](https://habrastorage.org/getpro/habr/upload_files/4e9/fe4/591/4e9fe4591b03d5d32148b8226d400c7d.png)
Система предварительно покажет, что будет сгенерировано; если всё ок – нажимаем Активировать.
![Рис. 29 Запускаем формирование объектов через кнопку Активировать Рис. 29 Запускаем формирование объектов через кнопку Активировать](https://habrastorage.org/getpro/habr/upload_files/474/e0e/a31/474e0ea3117fde266235d4086bd4b308.png)
После нажатия на активировать система начнет генерировать нужные объекты: группу функций, функциональные модули и типы данных для них. Чем больше таблиц – тем дольше генерация 😊 По завершению (если всё успешно завершено), то будет примерно подобное сообщение.
![Рис. 30 Сообщение об успешной генерации объектов (и да, язык космополита 😊) Рис. 30 Сообщение об успешной генерации объектов (и да, язык космополита 😊)](https://habrastorage.org/getpro/habr/upload_files/abf/885/ad2/abf885ad2a7fb414d485010771f63a68.png)
Выходим по зеленой галочке в начальное меню; теперь мы можем использовать ФМ ZPROTOTYPE_WRITE_DOCUMENT, но в режиме update task (так как мы это указали на этапе генерации; очередь будет V2 – то есть после обновления таблиц бизнес-сущности).
![Рис. 31 Сгенерированный функциональный модуль Рис. 31 Сгенерированный функциональный модуль](https://habrastorage.org/getpro/habr/upload_files/d0a/39b/852/d0a39b852ba6b41315f3f6aa1b9644f3.png)
Посмотрим на его параметры и прокомментируем.
Import | Id-объекта, которые мы сохраняем. В нашем случае = ZPROTOTYPE |
TCODE | Код транзакции: мы можем указать любой код. И этот код будет записан в CDHDR и CDPOS |
UTIME | Время записи. Как правило, до процедуры сохранения можно вызвать оператор GET TIME. |
UDATE | Дата записи. |
USERNAME | Имя пользователя, от которого будут записаны данные. Не обязательно должен совпадать с тем пользователем, под кем выполняется программа. |
… |
|
UPD_ZTAF07_COMPNENTS | Признак, что та или иная таблица объекта будет обновляться. Если данные в таблице как-то изменены, то нужно поставить букву ‘U’; а если нет – оставить поле пустым (SPACE). |
UPD_ZTAF07_FEATURES | |
UPD_ZTAF07_PROTO_H | |
UPD_ZTAF07_SERVICES | |
UPD_* | |
Tables | |
XZTAF07_COMPNENTS | X-данные (новые данные, иногда N_*): внутренняя таблица или структура с новыми данными (для обновления или вставки). В этой структуре должно быть поле KZ, в котором проставлен индикатор обновления. |
YZTAF07_COMPNENTS | Y-данные (старые данные, иногда O_*): внутренняя таблица или структура с данными, которые были ДО запуска программы. Предполагается, что перед началом работы программы мы либо прочитали данные из таблицы, либо перед сохранением в БД прочитали, что было сохранено в БД до наших изменений. Y-данные также должны содержать KZ-поле, в котором стоит индикатор обновления: I-insert, D-delete, U-update. |
XZTAF07_FEATURES | X-данные для целевой таблицы базы данных ZTAF07_FEATURES |
YZTAF07_FEATURES | Y-данные для целевой таблицы базы данных ZTAF07_FEATURES |
XZTAF07_PROTO_H | X-данные для целевой таблицы базы данных ZTAF07_PROTO_H |
YZTAF07_PROTO_H | Y-данные для целевой таблицы базы данных ZTAF07_PROTO_H |
XZTAF07_SERVICES | X-данные для целевой таблицы базы данных ZTAF07_SERVICES |
YZTAF07_SERVICES | Y-данные для целевой таблицы базы данных ZTAF07_SERVICES |
Глядя на эти параметры, можно подумать, что все индикаторы нужно подготавливать полностью вручную, но это не так. Есть функциональный модуль CHANGEDOCUMENT_PREPARE_TABLES, который позволяет подготовить данные для WRITE_CHANGEDOCUMENTS. Посмотрим, как можно использовать этот ФМ и что в итоге будет. Вот пример для подготовки одной таблицы.
DATA lv_tabname_proto_h TYPE tabname VALUE 'ZTAF07_PROTO_H'.
DATA lv_if_equal TYPE char1.
ms_chngdocs_tabs-s_proto-ch_ind = 'U'.
MOVE-CORRESPONDING mt_proto_h_old TO ms_chngdocs_tabs-s_proto-old_y.
MOVE-CORRESPONDING mt_proto_h_new TO ms_chngdocs_tabs-s_proto-new_x.
SORT ms_chngdocs_tabs-s_proto-old_y.
SORT ms_chngdocs_tabs-s_proto-new_x.
" cf_reca_storable=>get_change_indicator <- можно и этот способ использовать "
" , но prepare - уже классика и лежит в пакете SCDO "
CALL FUNCTION 'CHANGEDOCUMENT_PREPARE_TABLES'
EXPORTING
tablename = lv_tabname_proto_h
IMPORTING
result = lv_if_equal
TABLES
table_new = ms_chngdocs_tabs-s_proto-new_x
table_old = ms_chngdocs_tabs-s_proto-old_y
EXCEPTIONS
nametab_error = 1
wrong_structure_length = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO sy-msgli.
EXIT.
ENDIF.
IF lv_if_equal NE mc_tables_not_equal.
MESSAGE s000(cl) WITH 'no changes was done'.
CLEAR ms_chngdocs_tabs-s_proto-ch_ind.
ENDIF.
IF 1 = 2.
" если ФМ вызвать нескольо раз, то будет разный номер документа изменения "
CALL FUNCTION 'ZPROTOTYPE_WRITE_DOCUMENT'
IN UPDATE TASK
EXPORTING
objectid = ms_write_doc_hdr-v_objectid
tcode = ms_write_doc_hdr-v_tcode
utime = ms_write_doc_hdr-v_hdr_utime
udate = ms_write_doc_hdr-v_hdr_udate
username = ms_write_doc_hdr-v_hdr_username
upd_ztaf07_proto_h = ms_chngdocs_tabs-s_proto-ch_ind
TABLES
icdtxt_zprototype = ms_write_doc_hdr-t_cdtxt_tab
xztaf07_proto_h = ms_chngdocs_tabs-s_proto-new_x
yztaf07_proto_h = ms_chngdocs_tabs-s_proto-old_y.
ENDIF.
Полный пример программы доступен по ссылке. Что же мы получаем? В таблицах CDHDR / CDPOS фиксируются данные, которые были изменены.
![Рис. 32 Результат фиксации изменений. Рис. 32 Результат фиксации изменений.](https://habrastorage.org/getpro/habr/upload_files/0bc/7be/048/0bc7be0485f594054a7fa2e430582012.png)
Мы видим, какие значения полей были изменение, добавлены, удалены; когда и кем это было сделано. Более того, у нас есть возможность табличного (SQL-совместимого) поиска по этим данным. И стоит добавить, что в нашем случае (так как мы указали отложенное обновление) – это не нагружает сам бизнес-объект. Те же самые данные мы можем посмотреть и через программу RSSCD200.
![Рис. 33 Запуск просмотра данных change documents Рис. 33 Запуск просмотра данных change documents](https://habrastorage.org/getpro/habr/upload_files/c07/e6c/240/c07e6c240467f9114d4a262bd6b8defe.png)
А это значит, что мы можем подключить change documents к любой custom-транзакции.
Транзакция SCU3 – Table History
Этот лог также требует доп.активации (выполняется базисом и, как правило, включена). В профиле сервера в параметре rec/client нужно установить мандант для логирования (можно перечислить все). Справка по этому типу лога в Logging Changes to Table Data.
При создании таблицы (как правило, настроечной) можно указать отметку о необходимости логировать изменения. Проверить наличие этой функции для таблицы можно через транзакцию SE11 -> Технические параметры настройки (либо через транзакцию SE13).
![Рис. 34 Транзакция SE11 (ABAP-словарь) – нажимаем Просмотр Рис. 34 Транзакция SE11 (ABAP-словарь) – нажимаем Просмотр](https://habrastorage.org/getpro/habr/upload_files/f69/a55/19c/f69a5519c1c0bdcf18341c3744919ddd.png)
Затем переходим в Технические параметры настройки
![Рис. 35 Переходим к техническим параметрам настройки в SE11 (по сути переходим в транзакцию SE13) Рис. 35 Переходим к техническим параметрам настройки в SE11 (по сути переходим в транзакцию SE13)](https://habrastorage.org/getpro/habr/upload_files/f53/eff/58e/f53eff58e2117a0253d1be04bb16e749.png)
В блоке изменения данных должна стоить опция «Записать изменения данных в журнал», чтобы происходило логирование
![Рис. 36 Опция "Записать изменения данных в журнал" Рис. 36 Опция "Записать изменения данных в журнал"](https://habrastorage.org/getpro/habr/upload_files/690/d6c/3f8/690d6c3f8c48dc7a5bda24ad1e67beed.png)
Тогда мы сможем просмотреть изменения через транзакцию SCU3 следующим способом. Запускаем SCU3 и нажимаем Анализ журналов.
![Рис. 37 Транзакция SCU3 - Анализ журналов Рис. 37 Транзакция SCU3 - Анализ журналов](https://habrastorage.org/getpro/habr/upload_files/0a5/4e6/9d1/0a54e69d118e8ceb2470515fb2165f03.png)
Затем указываем нужную таблицу (или несколько); отмечаем галочку просмотр ALV Grid для более удобного просмотра и запускаем.
![Рис. 38 Запуск просмотра журнала изменений Рис. 38 Запуск просмотра журнала изменений](https://habrastorage.org/getpro/habr/upload_files/e3b/e6e/5ac/e3be6e5ac7b78c248aa9b364c57f7b4f.png)
В результате увидим информацию о пользователе, дате, времени, ключе таблицы и значения, привязанные к этому ключу. Это довольно информативно и наглядно.
![Рис. 39 Результат логирования в SCU3 Рис. 39 Результат логирования в SCU3](https://habrastorage.org/getpro/habr/upload_files/ddb/f37/20d/ddbf3720d5bd902f1c8bee6341ec9eb3.png)
Данные по логированию для этой транзакции уже хранятся в неструктурированном виде в таблице, а не в файлах, а именно в таблице DBTABLOG (пожалуй тот редкий случай, когда справка чуть ошибается 😊, в справке указано DBTABPRT ).
Вывод: эти подходы (application log (SLG1), change documents (SCDO) и table changes (SCU3)) к логированию позволяют получить информацию об изменениях в стандартных объектах, а также разрабатывать свои приложения, логируя нужную информацию и вовремя её архивируя. Использование этих инструментов сократит временные затраты на разработку, повысит понимание приложений и разбор на случай «что-то пошло не так».
Отображение изменений при правке данных через SE16N
Иногда данные в таблице могут быть исправлены через транзакцию SE16N. Подобные изменения также можно посмотреть через программу RKSE16N_CD_DISPLAY (она же встроена в SE16N, что неудивительно).
В транзакции SE16N переходим по пути Extras -> Display Change Documents (Дополнительная информация -> Просмотр документов изменений).
![Рис. 40 SE16N - переход к просмотру документов изменений Рис. 40 SE16N - переход к просмотру документов изменений](https://habrastorage.org/getpro/habr/upload_files/f10/74e/6d4/f1074e6d476bbad7716710a45b440eb5.png)
Указываем нужную таблицу(ы) и запускаем просмотр (если требуется – ограничиваем также по дате).
![Рис. 41 Указываем параметры и запускаем отчет Рис. 41 Указываем параметры и запускаем отчет](https://habrastorage.org/getpro/habr/upload_files/293/309/3c8/2933093c87b16b32db675c7289f45c75.png)
Сначала у нас будет срез в формате: таблица-пользователь. Сделав по нему double-click (двойной клик) – получим подробную информацию: что было вставлено/изменено/удалено и когда.
![Рис. 42 Просмотр изменений, сделанных в SE16N Рис. 42 Просмотр изменений, сделанных в SE16N](https://habrastorage.org/getpro/habr/upload_files/30c/db6/4f6/30cdb64f617a7560fd163ca469fa5507.png)
А теперь посмотрим подходы к логированию, которые специфичны для конкретного типа бизнес-приложения.
IDOC-list (WE02)
IDoc – это документ для обмена между системами. Его набор полей зависит от определенного типа сообщений. Здесь не будем расписывать детали про IDOC. А скажем, что сообщения, которые возникают в процессе обработки IDOC могут быть просмотрены в транзакции WE02.
![Рис. 43 Параметры для поиска idoc по статусу Рис. 43 Параметры для поиска idoc по статусу](https://habrastorage.org/getpro/habr/upload_files/1ac/bac/975/1acbac9754f2314539ecc4384bc73b92.png)
Открыв конкретный idoc, мы можем видеть сообщения, связанные с обработкой idoc. Для IDOC важность имеет статус. На основе статуса можно принимать решения о повторной обработке, или корректировке данных со стороны внешней системы.
![Рис. 44 Журнал обработки IDOC Рис. 44 Журнал обработки IDOC](https://habrastorage.org/getpro/habr/upload_files/509/cd7/68b/509cd768b2622f1bfd266431d4ff326b.png)
Каждый тип сообщения IDOC обрабатывается каким-то функциональным модулем, в параметрах у которого есть IDOC_STATUS. И именно в эту таблицу нужно добавлять то или иное сообщение, если мы хотим, чтобы оно отобразилось в журнале обработке IDOC.
![Рис. 45 Параметр IDOC_STATUS для добавления сообщения в журнал IDOC Рис. 45 Параметр IDOC_STATUS для добавления сообщения в журнал IDOC](https://habrastorage.org/getpro/habr/upload_files/ee5/1fd/1d7/ee51fd1d783aabf447a72d8b7d0fc0a8.png)
![Рис. 46 Пример добавления сообщения в журнал IDOC Рис. 46 Пример добавления сообщения в журнал IDOC](https://habrastorage.org/getpro/habr/upload_files/d8d/0df/3bc/d8d0df3bcdfa7a5821d2d5faa621d083.png)
Подробнее об администрировании и разработке IDOC (если нужно) – можно почитать по ссылке. Для себя же делаем вывод, что сам по себе журнал нужен не столько для детального понимания, как и что происходило, а скорее для фиксации ошибки (если она есть) и понимании «на чем споткнулась» обработка.
Output in Logistics (NAST-based protocol)
В логистике (SD/MM) с IDOC и пост-обработчиками связан функционал выходных документов. Обработка зачастую происходит в фоне или в отдельном процессе. И для целей логирования в стандарте предполагается своё отдельное логирования.
С точки зрения пользователя для его просмотра можно использовать интерфейс выходных документов. Выделяем нужный выходной документ и смотрим «Processing Log».
![Рис. 47 Отображение логов для выходного документа Рис. 47 Отображение логов для выходного документа](https://habrastorage.org/getpro/habr/upload_files/f4e/bc7/16e/f4ebc716e8b205266617477fa646a59f.png)
В сам интерфейс выходных документов можно попасть по-разному (зависит от исходного документа). Для сбытового заказа VA03->[указываем номер заказа]->Открываем заказ через ENTER и из обзорного экрана переходим по пути: Extras -> Output -> Header -> Output.
![Рис. 48 Переход к выходным документам сбытового заказа Рис. 48 Переход к выходным документам сбытового заказа](https://habrastorage.org/getpro/habr/upload_files/f81/464/baa/f81464baa0bdac0192d1787a21cd02d2.png)
С точки зрения разработчика работа с логом ведётся при помощи функциональных модулей группы функции WMCP (для каждого ФМа в системе можно найти примеры с использованием).
![Рис. 49 Пример работы с NAST-based логом Рис. 49 Пример работы с NAST-based логом](https://habrastorage.org/getpro/habr/upload_files/f73/db4/247/f73db4247eac41b85cd3f496fef84778.png)
Output (выходные документы) предназначены в том числе для печати, отправке по почте и в электронном виде документов, поэтому справка к этому функционалу находится в Printing Guide.
Работа с логами в OData-сервисах
OData-сервисы имеют разделение на два вида логов: логи бизнес-приложений и системные логи (анализ ошибок).
Для анализа ошибок: используют транзакции /IWFND/ERROR_LOG (SAP Gateway Error Log) и /IWBEP/ERROR_LOG (SAP GW Backend Error Log). Их принцип работы одинаков с точки зрения пользовательского интерфейса, но логируют они сообщения, которые возникают в разных местах (Gateway vs Backend), поэтому две транзакции и есть. А также есть транзакция для Application Log Viewer /IWFND/APPS_LOG (SAP Gateway Application Log Viewer).
В транзакции /IWFND/ERROR_LOG (SAP Gateway Error Log) имеются следующие полезные возможности:
1) Выборка сообщений с учетом различных параметров (время, тип сообщения и т.д.)
![Рис. 50 Выборка сообщения для отображения в OData-error-log Рис. 50 Выборка сообщения для отображения в OData-error-log](https://habrastorage.org/getpro/habr/upload_files/05d/1ae/a56/05d1aea568eea449a36a91a1fcf8f5a1.png)
2) Возможность повтора сообщений на тех параметрах, которые пришли в сервис. Когда случается Exception в рамках работы сервиса, то параметры его сохраняются, что облегчает последующий разбор.
![Рис. 51 Можем повторить сообщение и посмотреть параметры, на которых был вызван сервис Рис. 51 Можем повторить сообщение и посмотреть параметры, на которых был вызван сервис](https://habrastorage.org/getpro/habr/upload_files/7a5/22d/b7e/7a522db7e2727f0cfb6076d8be59e214.png)
В тестовом окружении мы можем увидеть параметры и, если нужно, скорректировать их.
![Рис. 52 Параметры вызова сервиса, перенесенные в тестовое окружение для последующего моделирования запроса Рис. 52 Параметры вызова сервиса, перенесенные в тестовое окружение для последующего моделирования запроса](https://habrastorage.org/getpro/habr/upload_files/4ed/986/42f/4ed98642feb7985909cccc2baa76f91b.png)
Далее мы можем тестировать сервис стандартными средствами OData (видео и прошедший вебинар на этот счет).
3) Переход в Application Log. OData-сервисы по умолчанию используют SLG1, в качестве стандартного лога для сообщений. И тогда мы можем использовать функционал BAL для работы с сообщениями.
![Рис. 53 Application Log для SAP Gateway Рис. 53 Application Log для SAP Gateway](https://habrastorage.org/getpro/habr/upload_files/269/d78/042/269d780429c026e7a32d557400af171e.png)
С точки зрения разработчика, чтобы сообщения добавлялись в этот журнал, нужно их отправлять через Exception через специальный объект.
METHOD varheadset_update_entity.
" *TRY. "
"*CALL METHOD SUPER->VARHEADSET_UPDATE_ENTITY "
"* EXPORTING "
"* IV_ENTITY_NAME = "
"* IV_ENTITY_SET_NAME = "
"* IV_SOURCE_NAME = "
"* IT_KEY_TAB = "
"** io_tech_request_context = "
"* IT_NAVIGATION_PATH = "
"** io_data_provider = "
"** IMPORTING "
"** er_entity = "
"* . "
"** CATCH /iwbep/cx_mgw_busi_exception . "
"** CATCH /iwbep/cx_mgw_tech_exception . "
"**ENDTRY. "
DATA lo_msg_cont TYPE REF TO /iwbep/if_message_container.
DATA ls_srv_in TYPE zcl_zweb_abap_demo1_mpc=>ts_varhead.
io_data_provider->read_entry_data( IMPORTING es_data = ls_srv_in ).
lo_msg_cont = mo_context->get_message_container( ).
""""""""""""""""""""""""""
IF ls_srv_in-num_of_files IS INITIAL.
MESSAGE s000(cl) WITH 'Поле NUM_OF_FILES является обязательным' INTO sy-msgli.
lo_msg_cont->add_message(
EXPORTING
iv_msg_type = sy-msgty
iv_msg_id = sy-msgid
iv_msg_number = sy-msgno
iv_msg_text = CONV #( sy-msgli )
iv_msg_v1 = sy-msgv1
iv_msg_v2 = sy-msgv2
iv_msg_v3 = sy-msgv3
iv_msg_v4 = sy-msgv4
).
MESSAGE s000(cl) WITH 'и еще одно сообещние в лог' INTO sy-msgli.
lo_msg_cont->add_message(
EXPORTING
iv_msg_type = sy-msgty
iv_msg_id = sy-msgid
iv_msg_number = sy-msgno
iv_msg_text = CONV #( sy-msgli )
iv_msg_v1 = sy-msgv1
iv_msg_v2 = sy-msgv2
iv_msg_v3 = sy-msgv3
iv_msg_v4 = sy-msgv4
).
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
message_container = lo_msg_cont
http_status_code = /iwbep/cx_mgw_busi_exception=>gcs_http_status_codes-not_acceptable.
ENDIF.
MOVE-CORRESPONDING ls_srv_in TO er_entity.
ENDMETHOD.
В журнал приложений OData мы можем попасть и через транзакцию /IWFND/APPS_LOG (SAP Gateway Application Log Viewer). В справке также есть информация по трассировке и логам в SAP Gateway. Если обратим внимание, то функционал OData-логов содержит переходы и в другие инструменты по логированию, как бы намекая, что для эффективного анализа ситуации нужно использовать все виды логов (собственно, про это и текущая заметка 😊).
SXI_MONITOR (интеграционное взаимодействие через PI/XI)
При интеграционном взаимодействии через шину XI/PI для логирования запросов и ответов (как синхронных, так и асинхронных) используется транзакцию SXI_MONITOR. Она позволяет показать тело сообщения (сами данные), а также доп.информацию о интеграционном взаимодействии (время, система получатель/отправитель). Подробнее про эту транзакцию, а также требуемых полномочиях можно почитать в справке ( HelpPortal: SAP NetWeaver -> Integration Engine -> Monitor for Processed XML Messages ). Полезно иметь ввиду транзакцию-меню: SXMB_MONI.
Workflow Logs (транзакция SWI5)
Workflow – это еще один функционал, который использует свои внутренние логи (связано с историческими причинами). Доступны эти логи через транзакции SWI5. Подробнее об этом можно почитать в справке по ссылке. Можно посмотреть незавершённые WF-задачи или завершенные на конкретный день в разрезе агента (исполнителя задачи).
![Рис. 54 Транзакция SWI5 для просмотра WF-задач (как в работе так и завершенных) Рис. 54 Транзакция SWI5 для просмотра WF-задач (как в работе так и завершенных)](https://habrastorage.org/getpro/habr/upload_files/4dd/70d/f3a/4dd70df3a72d9b7a887538da374e4f1d.png)
Мы рассмотрели основные логи приложений, но не все. Во многих бизнес-решениях и интеграциях могут использоваться свои подходы к логам, но полезно понимать, что могут уже стандартные логи, чтобы не тратить время на переизобретение в рамках одной системы. Кроме того, в системе APO, EWM, CRM, SRM есть свои специфичные инструменты для мониторинга и логирования.
Часть2. Использование системных логов
Рассмотрим следующие системные логи (это не полный список, но полезный):
1. System Log (транзакция SM21)
2. Audit Log (транзакция RSAU_READ_LOG)
3. ST22 ABAP Runtime Error
4. Лог при работе с транспортной системой
5. Изменение основных данных и полномочий пользователя
В системные логи консультанту/разработчику по прикладному модулю полезно периодически поглядывать и анализировать их. Системные журналы конфигурируются, как правило, на этапе запуска системы и НЕ предполагают никакой бизнес-информации, а только системную. Однако системная информация, может помочь в анализе как улучшить бизнес-приложение.
Транзакция SM21 – System Log
Логирует: Системные ошибки, некорректные попытки подключения, изменения переменных под отладкой, завершение сессий через SM51, «красные» и «желтые» ответы от базы данных и некоторые другие события системы. Сам журнал предполагает определенную конфигурацию (подробнее об этом в справке ).
Журнал в основном служит для контроля системы со стороны базиса, однако бизнес-консультанту тоже периодически приходится поглядывать в этот журнал (как и во все системные). Если полномочий на этот сист.журнал нет, то стоит знать, что он существует (или даже запросить полномочия хотя бы на время – в зависимости от исполняемых обязанностей на проекте).
Отчет запускается через транзакцию SM21 (один из путей: SAP Menu -> Tools -> Administration -> Monitor -> System Log (SM21), в этой же папке и другие полезные системные логи-журналы).
![Рис. 55 Запуск отчет через меню Рис. 55 Запуск отчет через меню](https://habrastorage.org/getpro/habr/upload_files/fe9/ba4/e95/fe9ba4e95cf1df4d5be67d99b0a2ee1d.png)
Про принцип работы отчета, важно знать:
1) на каждом application server есть свой файл логирования (то есть этот отчет собирает информацию именно в определенный файл). Целевой файл настраивает базис (подробнее в справке по Monitoring and Administration Tool, а также в Syslog Monitor).
Транзакция SM51 – это список имеющихся серверов приложений с возможностью переключаться между ними. Транзакция SM50 – список всех процессов на текущем сервере. SM66 – полный перечень процессов по всем application server.
2) запись в этот файл делается по принципу ring buffer (распространённый перевод: кольцевой буфер) – достигнув конца файла, система начнет писать в файл сначала. Таким образом: размер файла такой, какой выделен изначально.
3) каждую запись в файле сопровождает метка времени, поэтому на экране в SM21 данные отображаются в хронологическом порядке (хотя ALV позволяет задать любой фильтр и сортировку)
С учётом этих пунктов – заполняем селекционный экран: указываем период времени для анализа, сервер (или несколько), и другие параметры; затем запускаем по F8 / Выполнить.
![Рис. 56 Селекционный экран SM21 Рис. 56 Селекционный экран SM21](https://habrastorage.org/getpro/habr/upload_files/a08/8f1/cb3/a088f1cb3b7f22af75a0a372ea8a6258.png)
Примеры отображений показы на скриншотах.
![Рис. 57 Пример сообщения об изменении поля под отладкой: Fields Content Changed Рис. 57 Пример сообщения об изменении поля под отладкой: Fields Content Changed](https://habrastorage.org/getpro/habr/upload_files/4ba/826/8af/4ba8268afbad044124c48ac6e628e121.png)
![Рис. 58 Неудачный логон при выполнении фонового задания: Logon of Jobstep User Failed Рис. 58 Неудачный логон при выполнении фонового задания: Logon of Jobstep User Failed](https://habrastorage.org/getpro/habr/upload_files/e08/5c5/2b8/e085c52b85f9bb2b72b9482f71b9bdbd.png)
![Рис. 59 Критичный ответ от базы данных: Database error – feature not supported. Рис. 59 Критичный ответ от базы данных: Database error – feature not supported.](https://habrastorage.org/getpro/habr/upload_files/01d/708/1cf/01d7081cfb18a2545f146d9837b264b2.png)
Частое появление красных сообщений в этом журнале – не очень хороший знак.
Подробнее о журнале (конфигурировании, администрировании) в справке The System Log, а также в статьях Вячеслава Шиболова, а также в других блогах.
Транзакция RSAU_READ_LOG – Security Audit Log
Журнал проверки безопасности собирает более детальные события о действиях системы с целью аудирования. Информация об аудите собирается в отдельные файлы (они не имеют отношения к SM21). В журнале могут отображаться: успешные/неуспешные подключения в диалоге, через RFC/HTTP, запуски транзакций (как успешные, так и неуспешные), изменения основных данных пользователя и другие события, обозначения в справке к Security Audit Log.
![Рис. 60 Селекционный экран транзакции RSAU_READ_LOG (Secutiry Audit Log) Рис. 60 Селекционный экран транзакции RSAU_READ_LOG (Secutiry Audit Log)](https://habrastorage.org/getpro/habr/upload_files/3bf/5b6/f88/3bf5b6f88f8db9720b1e37a13bfb7453.png)
Журнал отображает множество информации в том числе имя ПК (или адрес), с которого было совершенно событие.
![Рис. 61 Пример записи из Security Audit Log Рис. 61 Пример записи из Security Audit Log](https://habrastorage.org/getpro/habr/upload_files/8f3/2dc/53d/8f32dc53dac3401cfd61fca1d649cc12.png)
Этот журнал требует отдельной активации и выделения пространства для файлов логирования. Журнал можно активировать временно через транзакцию SM19, а также на постоянной основе (параметр rsau/enable=1). Удаление логов выполняется через транзакцию SM18.
![Рис. 62 Настройка фильтра (те события, которые необходимо логировать) для Security Log Рис. 62 Настройка фильтра (те события, которые необходимо логировать) для Security Log](https://habrastorage.org/getpro/habr/upload_files/cc5/bb5/d0d/cc5bb5d0d3ef6b40b9239271473af836.png)
Транзакция ST22 – ABAP Dump Analysis / Runtime Error Log
Транзакция ST22 представляет собой отчет по динамическим ошибкам, возникшим в системе. Количество динамических ошибок является одним из показателей (количество дампов), которые можно применять к оценке стабильности системы. Справка sap help ABAP Dump Analysis (ST22).
![Рис. 63 Начальный экран выборки в ST22 Рис. 63 Начальный экран выборки в ST22](https://habrastorage.org/getpro/habr/upload_files/a13/b71/80d/a13b7180db818dad2071f8e4f495725e.png)
Перечень содержит информацию по всем пользователям системы. Таблица SNAP (а именно в ней хранятся данные по дампам) обычно очищается через каждый период времени (настраивается базисом); но если Вам нужно сохранить дамп, и чтобы он не исчез из системы, то нужно нажать кнопку «Keep/Release»
![Рис. 64 Кнопка Keep/Release для сохранения дампа от удаления Рис. 64 Кнопка Keep/Release для сохранения дампа от удаления](https://habrastorage.org/getpro/habr/upload_files/84a/e9c/2f5/84ae9c2f5ba498f54b16467b5b55d8fe.png)
Возникновение дампа в системе, может быть, по разным причинам и исправление дампа тоже может быть различное. При двойном щелчке на дампе – мы можем увидеть подробную информацию о нем. Мы можем увидеть краткое описание, а также перейти к место кода, где случилась проблема.
![Рис. 65 Базовая информация в дампе о RunTime Error Рис. 65 Базовая информация в дампе о RunTime Error](https://habrastorage.org/getpro/habr/upload_files/a79/9d8/6d0/a799d86d095b89021f56e13defeecec2.png)
И мы можем посмотреть значения переменных, в момент дампа, а также стэк вызовов.
![Рис. 66 Стэк вызовов в дампе о Runtime Error Рис. 66 Стэк вызовов в дампе о Runtime Error](https://habrastorage.org/getpro/habr/upload_files/b2b/253/606/b2b2536064521adc091c0aa04b325372.png)
![Рис. 67 Просмотр значений переменных в дампе о Runtime Error Рис. 67 Просмотр значений переменных в дампе о Runtime Error](https://habrastorage.org/getpro/habr/upload_files/b2a/8cd/4e1/b2a8cd4e116835c578909c5d80335c0e.png)
Популярные дампы и пояснения к ним в таблице
SYSTEM_NO_ROLL TSV_TNEW_PAGE_ALLOC_FAILED SQL_CAUGHT_RABAX | Нехватка внутренней памяти: либо нет проверка на for all entries в выборках на больших таблицах (Типа VBRK/VBRP, LIKP, LIPS и т.д.), либо программа просто неоптимально выбирает (либо вообще без ограничений).
Если в описании дампа идет описание о программе ??????? (символы вопросики) – это может быть SUBMIT на пустой программе. |
SYNTAX_ERROR | Синтаксическая ошибка в коде. Классический случай 😊 , когда что-то забыли перенести; перенесли частично; или перенесли то, что не стоит переносить. Например, в программе идет обращение к элементу структуры, которого не существует. |
CONVERT_NO_NUMBER | В программе идет попытка преобразовать нечисло к числовому типу данных |
DYNPRO_MSG_IN_HELP | Программа выдает сообщение такого типа, что не соответствует месту в программе. Например, Warning в модулях обновления. Исправляется через корректировку кода (либо силами внутренней поддержки, либо SAP-поддержки). |
GETWA_NOT_ASSIGNED | Обращение к неприсвоенной переменной (field symbol). Если это код клиента, то нужно исправлять код и/или не использовать программу с таким набором данных, что он приводит к такой ситуации. Если это стандартная программа, то нужно проанализировать данные – все ли правильно и корректно? «Нет ли попытки продать несуществующий материал?» «Или провести документ в неизвестной валюте?». Таким образом, дамп может быть связан либо с ошибочными данными, либо с кодом, который явно в дампе не фигурирует, но влияет на данные. Для стандартных программ нужно посмотреть ноты и/или выставить сообщение в SAP SUPPORT. |
CALL_FUNCTION_CONFLICT_LENG | Вызов ФМ с неправильными параметрами (либо с отсутствующими, либо несоответствующими по типу). |
MESSAGE_TYPE_X / RAISE_EXCEPTION | Возникла исключительная необрабатываемая ситуация. Если программа стандартная – то нужно искать ноту или выставлять сообщение в SAP. При этом нужно иметь ввиду, что возникшая ситуация не обрабатывается стандартом и значит, возможно, дело в том, что бизнес данные так сложились, что для SAP ERP это неприемлемо. Например, в таблице вариантов для конфигурации (транзакция CU60 неприемлемо ведение дублированных значений) (это логично, так как в случае дублирования вариант не может быть однозначно определен), однако в самой транзакции проверки на это нет; а вот при конфигурации сбытового заказа может возникнуть дамп. Для стандартных программе нужно посмотреть ноты и/или выставить сообщение в SAP SUPPORT. |
CALL_FUNCTION_NOT_REMOTE | Вызов ФМ для RFC-обновления (BACKGROUND task), который не предназначен для таких операций. |
DYNPRO_FIELD_CONVERSION | Попытка показать отрицательные значения в полях экрана без знака. |
LOAD_PROGRAM_NOT_FOUND | Попытка вызвать несуществующую программу. Возможно, через SUBMIT. |
LOAD_PROGRAM_MISMATCH | Идет перенос программы (или связанных технических объектов с программой). При этом в процессе переноса (генерации) кто-то работал в этой программе. По этой причине запрещено переносить юзер-экзиты и другие расширения в течение рабочего дня. (только в исключительных ситуациях). |
Как было сказано при анализе дампов обращать внимание на тип runtime error, стэк, актуальность дампа, корректность подаваемых данных, а также использовать справку и SAP-ноты при анализе (например, 1699048 (Unexpected short dumps in ST22), 2200714 (Dumps in ST22 show ?????? in ALV list))
Журнал при работе с транспортной системой.
При работе с переносами изменений в продуктив с помощью транспортных запросов полезно иметь ввиду соответствующие логи. Они пишутся в файл и могут отображаться по-разному. Список объектов записывается в таблицы: E070, E071 и E071K. Один из способов – это через транзакцию SE09: поставить курсор на нужный транспортный запрос и нажать логи. Подробнее в справке Logging in Transport System.
![Рис. 68 Логи в транспортной системе Рис. 68 Логи в транспортной системе](https://habrastorage.org/getpro/habr/upload_files/355/46d/efe/35546defe705f7af3fc8e773705b7dd3.png)
Изменение полномочий пользователя (основных данных пользователя).
При анализе возможных проблем с полномочиями полезно иметь ввиду журнал изменения полномочий пользователя. Запускаем транзакцию SU01D или SU01. Переходим по пути: Information -> Change Documents for Users.
![Рис. 69 Переход к журналу изменений пользователя Рис. 69 Переход к журналу изменений пользователя](https://habrastorage.org/getpro/habr/upload_files/f2c/39f/6bf/f2c39f6bf5ba80f61e419aa6ea18d076.png)
Указываем галочками те атрибуты, по которым нужно проконтролировать изменения: основные данные, роли и т.д. (можно отметить всё, но ждать долго).
![Рис. 70 Указываем параметры для выборки изменений по основным данным пользователя и запускаем отчет. Рис. 70 Указываем параметры для выборки изменений по основным данным пользователя и запускаем отчет.](https://habrastorage.org/getpro/habr/upload_files/a0b/ee5/1bb/a0bee51bb7da43157c702d50fdd04fd3.png)
Результат отчета довольно понятный и поможет установить, когда и что было скорректировано у пользователя.
![Рис. 71 Изменение по основным данным пользователя Рис. 71 Изменение по основным данным пользователя](https://habrastorage.org/getpro/habr/upload_files/9f2/34f/f80/9f234ff80aaff090ce6a82ac649247e4.png)
Другие системные логи
Журналы выше – это неисчерпывающий список системных журналов. Существуют и другие системные логи, в том числе специально разработанные для какой-либо отрасли/компании. Поэтому периодически полезно проверять появление новых логов: в документации (а также в alerting), в нотах или другими способами. Кроме того, в статье мы не затронули тему alerting (оперативное оповещение при наступлении какого-либо события), так как это отдельная тема (одна из документаций).
Использование трассировок
Трассировки от обычного логирования отличаются тем, что включаются на какой-то период времени и направлены на фиксирование каких-то конкретных действий. То есть они работают не принципу «включено всегда или включено по исполнению», а покрывают какой-то ограниченный период наблюдения и конкретный набор информации (метрик). В этой части мы рассмотрим 2 транзакции, а некоторые другие просто обозначим с указанием лишь их возможностей. Цель и приёмы у каждого инструмента трассировки различные.
STAD – statistics display
С помощью транзакции STAD мы можем посмотреть статистику системы за последние несколько часов (по умолчанию 48). В SAP NetWeaver каждый час записывается файл статистики, а через каждый 48 часов он удаляется. Что представляет из себя файл статистики? Представляет из себя перечень программ, и пользователей, которые их запускали, с временем работы; таким образом, файл статистики показывает, кто что запускал и как это что-то отработало. Файл статистики не покажет точное место кода, а только представит общую картину. Этот инструмент – прежде всего для анализа загрузки системы; то есть мы можем заранее найти узкие места системы, не дожидаясь того, как возникнет ситуация. Кроме того, мы можем быстро посмотреть, что именно запускал пользователь и как долго «это что-то» выполнялось (потенциально, мы можем сделать вывод: что требует улучшения, чтобы конкретный пользователь получал более быстрый отклик системы).
![Рис. 72 Экран запуска транзакции STAD - указываем период и параметры для отбора Рис. 72 Экран запуска транзакции STAD - указываем период и параметры для отбора](https://habrastorage.org/getpro/habr/upload_files/0a0/cf3/8fb/0a0cf38fbb32bebf2b88254bd6cd78c0.png)
В разделе Display Mode мы укажем опцию группировки (сделаем все записи, сортированные по времени). В статистике мы найдем информацию о запускаемых транзакциях, пользователе, времени отклика.
![Рис. 73 Пример списка в транзакции STAD Рис. 73 Пример списка в транзакции STAD](https://habrastorage.org/getpro/habr/upload_files/12d/494/3d1/12d4943d1cc67c27f101ecfd143cda36.png)
Двойным кликом на строчке – получаем более детальную информацию. Эта информацию разбита на 4 блока: Время выполнения рабочего процесса (Time), DB (время на работу с базой данных), Task/memory (затраченное время) и информация по клиенте. В случае, если были RFC вызовы – будет информация по ним. Для нас важно обратить внимание на Time – характеризует работу ABAP-кода, и DB – характеризует время по выборке из базы данных.
![Рис. 74 Кнопки Time/DB Рис. 74 Кнопки Time/DB](https://habrastorage.org/getpro/habr/upload_files/d03/d6f/e49/d03d6fe4926f62e3adf2422819600ece.png)
В Wait смотрим на показатель Processing time – это то, сколько времени программа обрабатывалась на Application Server.
![Рис. 75 Показатель Processing Time Рис. 75 Показатель Processing Time](https://habrastorage.org/getpro/habr/upload_files/b02/f3e/981/b02f3e981aad636d35cdd2d4bf123ec5.png)
В блоке DB – смотрим на все столбцы и в особенности на Avg.time / row (ms) – от каждой базы данных можно требовать своего результата. На современных Oracle и HANA – менее 1 ms – Это норма; если продолжительнее, то стоит задуматься. Для старых БД – менее 10 ms – это норма.
![Рис. 76 Пример блока DB Рис. 76 Пример блока DB](https://habrastorage.org/getpro/habr/upload_files/f4a/0ff/71a/f4a0ff71ad59afc3b80303feef43055b.png)
Данные по статистике хранятся в системе по умолчанию 48 часов; время хранения может изменить базис. Система каждый час накапливает данные в файл и сохраняет его; при достижении конечного значения, система не создает новый файл, а «перезатирает» имеющийся (ring buffer). Чтобы не плодить количество файлов, можно поставить программу RSSTAT26 в фоновое выполнение и анализировать результат по данным фонового задания. Полезные заметки на эту тему: read_stad, inside_stad. Ноты: 579462 - Runtime parameter of the statistics collection, 552845 - FAQ: RFC Statistics in Transactions ST03/ST03N and STAD, 8963 - Definition of SAP response time/processing time/CPU time.
SMICM – Internet Communication Monitor (ICM)
Транзакция SMICM даёт множество возможностей и инструментов, но мы рассмотрим включение трассировки для логирования HTTP-запросов. Для включения трассировки запускаем транзакцию SMICM и идем по пути Goto -> Trace Level -> Set.
![Рис. 77 Установка уровня трассировки в SMICM Рис. 77 Установка уровня трассировки в SMICM](https://habrastorage.org/getpro/habr/upload_files/b60/e64/093/b60e64093ec82f7eb52a9bc0e82e274e.png)
На время запуска можем указать самый подробный способ трассировки
![Рис. 78 Устанавливаем самый подробный уровень трассировки Рис. 78 Устанавливаем самый подробный уровень трассировки](https://habrastorage.org/getpro/habr/upload_files/ed5/55a/906/ed555a9060de716712ffbbaca22fe38c.png)
Затем запускаем HTTP-вызов. В нашем случае это будет интеграция с сервером ABFOS по протоколу HTTP. После прогона HTTP-вызовов, нам нужно посмотреть файл трассировки (путь: Goto -> Trace File -> Display All ( или Display End, чтобы посмотреть окончание файла)).
![Рис. 79 Просмотр файла трассировки Рис. 79 Просмотр файла трассировки](https://habrastorage.org/getpro/habr/upload_files/d70/3ee/8da/d703ee8dac038fb61910c7a28a518ceb.png)
Затем по поиску через Ctrl + F находим примерные строки и уже точно видим, что, как и куда отправлялось.
![Рис. 80 HTTP-Трассировка из транзакции SMICM Рис. 80 HTTP-Трассировка из транзакции SMICM](https://habrastorage.org/getpro/habr/upload_files/f20/119/69d/f2011969dcda16368c46552d1e82120d.png)
После завершения трассировки – не забываем устанавливать уровень трассировки в наименее подробный уровень.
Прочие инструменты трассировки
OData-трассировка инструмент используемый в SAP Gateway. Транзакция /IWFND/TRACES (SAP Gateway Traces). Позволяет фиксировать входящие запросы и ответы, делать трассировку производительности запросов, можно активировать трассировку для любого пользователя (при наличии полномочий), позволяет выполнять повтор запросов.
Транзакции ST12 и SAT – два мощнейших инструмента, позволяющие быстро искать узкие места в программе, контролировать стэк, размер данных, скорость доступа. Используются для анализа и оптимизации программ. Позволяют делать трассировку фоновых процессов, update-процессов, трассировку по событию, дают возможность проводить «top-down analysis». Могут запускаться как из специальных транзакций, так и из инструмента отладки.
Трассировка полномочий ST01 – используется, прежде всего, для анализа нехватки полномочий для какого-либо действия в течение исполнения процесса от любого пользователя. Материал1 и материал2.
ST03N – Workload Monitor – инструмент, предоставляющий информацию о загрузке системе: что, когда, кем, сколько раз запускалось/вызывалось и сколько вычислительных ресурсов было потрачено. Мощный статистический инструмент – справка доступна по ссылка.
SFP trace utility - трассировка печатных форм Adobe Document Services. Позволяет получить составные части формируемого pdf-документа.
Выводы
Мы видим, что имеются различные типы логов и подходы к логам. При создании/корректировке приложений наличие удобочитаемых логов, которые не загружают систему, даст Вам «почёт и уважение, а также сэкономит время 😊». Вот для этого мы и рассмотрели стандартные подходы к логированию. Если какой-то журнал остался вне рамок статьи, то прошу прокомментировать/дополнить.