Динамические журнальные точки

В ABAP довольно таки давно существует функционал журнальных точек, который позволяет активировать запись в журнал (в тр. SAAB) определённых данных из программы. Для этого необходимо завести ключ (ID группы контрольных точек) и в коде использовать оператор LOG-POINT.

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

Для этих целей начиная с ABAP 7.5 ввели так называемые динамические журнальные точки, которые позволяют:

  • Сохранять значения переменных по определённым условиям
  • Записывать стек вызовов, чтобы понять откуда происходит вызов того или иного кода
  • Выполнять анализ выполнения отдельного SQL выражения
  • Активировать запись SQL трассировки для заданного выражения оп указанному условию
  • Активировать трассировку использования табличного буфера заданного SQL выражения для анализа потребляемой памяти

Создавать или модифицировать журнальные точки можно либо через ADT (Eclipse), либо через транзакцию SDLP.

Далее на простых примерах рассмотрим вариант использования.

Полномочия

Для работы с динамическими точками нужно иметь соответствующие полномочия — объект S_DYNLGPTS.

Логирование простых переменных

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

Рассмотрим пример кода:

Каждый раз запуская отчёт генерируется произвольное значение. Зайдём в Eclipse и создадим точку, для этого перейдём на нужную нам строку кода и правой кнопкой по столбцу с номерами строк вызовем контекстное меню:

Откроется экран создания (по умолчанию логирование простых переменных):

Основные настройки

  • В разделе Location можно убедиться в корректности определения места вызова.
  • В разделе Activity нас интересует тип точки: Log Simple Variable Values.
  • В разделе Variable(s) можно определить набор переменных значения которых нужно записать в журнал. Имена переменных можно перечислить через запятую.
  • В разделе Conditions определяются условия запуска.
  • В разделе Description определяется имя журнальной точки.
  • В разделе Activation определяется:
    • Статус — по умолчанию активно
    • Для какого пользователя должна срабатывать точка
    • На каких серверах
    • Предел по времени, после которого точка деактивируется
    • Время хранения журналов
    • Максимальное число срабатывания на сессию

В разделе Optional Conditions можно задать простые условия для срабатывания точек:

  • Стандартные операторы сравнения: EQ,=,NE,<>,><,<,LT,>,GT,<=,=<,LE,>=,=<,GE
  • Операторы для анализа строк: CO,CN,CA,NA,CS,NS,CP,NP
  • Унарные операторы: IS INITIAL, IS BOUND, IS ASSIGNED

Примеры:

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

Созданная активная точка сразу же отображается (по аналогии с точкой прерывания) в редакторе кода:

Так же во View Logpoints:

И там и там она может быть удалена/активирована/изменена/деактивирована. Там же можно сбросить/очистить журнал.

Посмотреть журнал после выполнения отчёта можно в том же View, нажав на столбец Log Events предварительно обновив (по кнопке или нажав F5):

В качестве ключа журнальной точки у нас выступает значение переменной, как видно на картинке, значение 74 у нас было присвоено переменной два раза. Если в журнальной точке будет несколько переменных, в качестве ключа уже будет составной ключ из их значений:

Сохранение стека вызовов

Иногда полезно узнать откуда был вызван тот или иной код, например: когда статически это выявить невозможно (динамические вызовы ФМ-ов или методов). Для этих целей служит следующий тип журнальных точек — Log Call Stack.

В качестве примера выставим такую точку в конструкторе ALV cl_gui_alv_grid:

И откроем несколько раз SE16 и SE11 с просмотром данных в ALV. Журнал будет выглядеть примерно следующим образом:

Я вызывал просмотр из SE16 и SE11 — два вызова, но запись одна.

Обратите внимание на ключ — в данном случае для каждого уникального стека вызовов генерируется хэш стека (функция STACK_HASH) и записывается в качестве ключа. Несмотря на запуск просмотра данных из SE16 и SE11 обе транзакции стартуют внутри себя просмотр через одну и ту же сгенерированную программу, именно её internal session стек и будет записан в журнал.

Определяемые пользователем журнальные точки

Наиболее гибким вариантом журнальных точек являются — User Defined Logging.

Основные отличия:

  • Возможность определения ключа для журнала (при одинаковом значении ключа в журнале отображается последняя запись)
  • Возможность записи в журнал не только элементарных типов, но и структур и таблиц (не полностью).

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

Допустим мы захотели записать в журнал данные по всем отображаемым в ALV таблицам, для этого перейдём в ФМ REUSE_ALV_GRID_DISPLAY и сразу на входе создадим следующую журнальную точку:

Запустим например в SE11 на просмотр таблицу SBOOK и SFLIGHT, после чего в журнале обнаружим следующий результат:

В данной точке мы использовали встроенные функции для формирования ключа:

  • REQ_TYPE — позволяет определить тип входной точки (RFC, SUBMIT, HTTP запрос и т.п.)
  • REQ_ENTRYPOINT — имя входной точки (отчёт, RFC модуль и т.п.)
  • LINES — подсчёт количества строк в таблице

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

SQL трассировка

Для того чтобы снять трассировку нужного запроса с возможностью определения условий можно воспользоваться отдельным типом журнальных точек — SQL Trace For Current Statement.

Как понятно из названия, необходимо выставить данный тип точки на SQL запросе и в момент его обработки будет включена трассировка в транзакции ST05 после выполнения автоматически отключена.

После формирования журнала двойной щелчок по нему приведёт к открытию транзакции ST05.

Встроенные функции

Ранее мы уже рассмотрели ряд встроенных функций в управление журнальными точками, рассмотрим кратко другие:

  • INEXACT_DF() — предоставляет информацию о точности выполнения арифметической операции с типами DECFLOAT16/34 (Не представляю чтобы мне это понадобилось 😁)
  • SQL_TRACE( StackOn|StackOff ) — позволяет активировать в указанной точке SQL трассировку либо с записью ABAP стека, либо без. После прохода выражения на котором выставляется трейс (SQL запроса) запись трассировки отключается. Результат можно посмотреть в транзакции ST05.
  • STACK( ) — получает стек в виде строки
  • STACK_HASH( ) — получает base64 от стека в виде строки
  • STRLEN( <arg> ) — размер строки
  • SYSTEM_INFO( ) — получение системной информации. В качестве аргументов могут быть:
    • ‘A’ : Имя текущего сервера приложений
    • ‘T’ : Полный UTC Time stamp
    • ‘t’ : Сокращённый UTS Time stamp
  • TABLEBUF_TRACE( StackOn|StackOff ) — Аналогичен SQL_TRACE но для трассировки использования табличного буфера
  • XSTRLEN( <arg> ) — размер строки для XSTRING и X
  • _DEBUG_INFO() — для внутреннего использования SAP-ом, выдаёт всякую интересную информацию:
  • _SET_DEVTRACE(<trace_activation>) — опять же для внутреннего использования, управляет параметрами rdisp/TRACE и rdisp/TRACE_COMPS

Более подробную документацию по каждой функции вы можете найти в документации к ADT (Eclipse).

Дополнительно

  • Отчёт RS_DLP_ANALYZE_CONDITION_LOAD — позволяет проверить условия на ошибки (если в ADT не ясно с чем связана ошибка проверки условия), проанализировать LOAD существующего в БД или введенного вручную условия.
  • Проверка на авторизацию осуществляется в классе CL_DLP_AUTHORITY, на случай если хотите пропустить.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *