При анализе сложных алгоритмов или разборе «запутанного» чужого кода стандартного замера производительности часто бывает недостаточно. Основная проблема штатного замера заключается в том, что он агрегирует данные: мы видим суммарное время выполнения строки, но не видим последовательности, в которой вызывались процедуры и функции. Если один и тот же метод вызывается из десяти разных мест, замер покажет общую статистику, а нам важна хронология. Рассмотрим подробнее, как решить задачу получения детального листинга исполняемого кода.
Проанализируем самый гибкий, хотя и требующий подготовки метод — массовое внедрение кода логирования в конфигурацию. Если методов в системе сотни или тысячи, вставлять вызовы вручную невозможно. Разберем по шагам, как автоматизировать этот процесс.
Во-первых, выполним выгрузку конфигурации в файлы. Это позволит нам работать с кодом как с обычным текстом. В конфигураторе выберем пункт «Конфигурация — Выгрузить конфигурацию в файлы». После завершения процесса мы получим набор папок с модулями в формате .bsl.
Во-вторых, воспользуемся текстовым редактором, поддерживающим регулярные выражения (например, VS Code, Notepad++ или специализированные скрипты). Нам нужно найти начало каждой процедуры и функции и вставить сразу после заголовка строку, которая будет записывать факт вызова в лог. Разберем пример регулярного выражения для поиска:
// Шаблон поиска (поиск заголовков методов)
(?i)(Процедура|Функция)\s+([\w\d_]+)\(
// Шаблон замены (вставка вызова логирования)
$1 $2(\n\tЗафиксироватьВызовМетода("$2");
При использовании этого подхода мы автоматически добавим вызов нашей собственной процедуры ЗафиксироватьВызовМетода в начало каждого метода. В этой процедуре мы можем реализовать запись в текстовый файл или в ЖурналРегистрации. Проанализируем пример такой процедуры:
Процедура ЗафиксироватьВызовМетода(ИмяМетода) Экспорт
ТекстЛога = Формат(ТекущаяДатаСеанса(), "ДФ=HH:mm:ss") + " | Вызов: " + ИмяМетода;
// Запись в текстовый файл для максимальной производительности
Файл = Новый ЗаписьТекста("C:\logs\trace.log", КодировкаТекста.UTF8, , Истина);
Файл.ЗаписатьСтроку(ТекстЛога);
Файл.Закрыть();
КонецПроцедуры
После внесения изменений загрузим файлы обратно в конфигурацию. Теперь при выполнении кода мы получим текстовый файл с полной хронологией вызовов.
Выясним причину, по которой профессиональные разработчики предпочитают Технологический журнал. Это штатный механизм платформы 1С, который не требует изменения программного кода и работает на уровне ядра. Для настройки трассировки вызовов нам необходимо создать файл конфигурации logcfg.xml в каталоге настроек платформы.
Рассмотрим пример настройки, которая будет фиксировать все вызовы процедур и функций (событие CALL):
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\1C_Logs\Trace" history="24">
<event query="true">
<eq property="Name" value="CALL"/>
</event>
<property name="AllProperties"/>
</log>
</config>
Важный момент: событие CALL генерирует огромный объем данных. Рекомендуется включать такую настройку только на время воспроизведения конкретной операции. После завершения работы мы получим файлы логов, где будет указано точное время начала каждого вызова, его длительность и контекст (стек вызовов). Для анализа этих файлов удобно использовать скрипты на Python или специализированные парсеры логов ТЖ. Для организации сбора и хранения больших объемов логов подойдёт утилита для переноса данных технологического журнала в ClickHouse.
Посмотрим на ситуацию под другим углом. Стандартный замер производительности сохраняет данные в файлы с расширением .pff. Хотя штатное окно замера показывает только сводную таблицу, внутри файла данные хранятся в хронологическом порядке.
Для извлечения этой информации можно использовать следующие подходы:
.pff и выстраивать «дерево вызовов».Это позволит увидеть последовательность строк кода так, как они выполнялись на самом деле, без необходимости модифицировать конфигурацию.
Если вы используете 1C:Enterprise Development Tools (EDT), задача трассировки упрощается. В среде EDT на базе Eclipse существуют механизмы рефакторинга и плагины, которые позволяют выполнять массовые изменения кода гораздо безопаснее, чем простые регулярные выражения.
Кроме того, современные версии платформы поддерживают Debug Adapter Protocol (DAP). Это открывает возможность подключения внешних инструментов анализа. Проанализируем преимущества этого подхода: сторонние утилиты могут подключаться к сессии отладки и «подписываться» на события перехода по строкам. Таким образом, можно получить полный листинг исполнения в реальном времени, записывая каждое действие отладчика в базу данных или структурированный JSON-файл.
Для очень объемных трасс (десятки тысяч строк) даже текстовый листинг становится нечитаемым. В этом случае разберем методику построения Flame Graphs. Это графическое представление стека вызовов, где:
Для 1С существуют инструменты, которые конвертируют логи Технологического журнала или данные замера производительности в формат, понятный для визуализаторов Flame Graph. Это идеальный способ быстро найти «узкие места» в логике или понять, на каком этапе рекурсия или цикличные вызовы начинают перегружать систему.
Подводя итог, выбор метода зависит от ваших целей. Если нужно быстро разобрать небольшой алгоритм — используйте Технологический журнал. Если задача стоит в постоянном документировании или отрисовке схем (как в исходном вопросе) — лучше всего подойдет автоматизированное логирование через регулярные выражения или современные средства EDT. Для предварительного анализа связей между процедурами по выгрузке конфигурации без выполнения кода также подойдёт инструмент для статического анализа и визуализации кода конфигураций 1С.