директор по Технологиям, ОАО СберТех, РФ, г. Москва
РЕАЛИЗАЦИЯ AI-АГЕНТА ДЛЯ УПРАВЛЕНИЯ ОБЪЕМОМ ЛОГИРОВАНИЯ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ
АННОТАЦИЯ
Характер расстановки инструкций логирования в программном коде с одной стороны определяет то, насколько прозрачны будут источники инцидентов с ПО, с другой стороны — насколько затратной будет эксплуатация приложения в части потребляемых подсистемой логирования ресурсов. Поэтому оптимизация объема логирования в исходном коде ПО является важной задачей обслуживания исходного кода, поручаемой квалифицированному инженеру-разработчику. В статье рассматривается возможность автоматизации задачи с помощью AI-агента, оптимизирующего характер расстановки логов с помощью предиктивной модели, определяющей, где добавить / удалить инструкции сбора логов, и генеративной модели, участвующей в генерации инструкций сбора логов. В качестве среды выполнения агента использовалась интегрированная среда разработки GIGA IDE, а поставщиком сервиса языковой модели, оптимизированной для работы с кодом, выступала GIGA CODE.
ABSTRACT
The arrangement of logging instructions in software code determines, on the one hand, how transparent the origins of software incidents will be, and on the other, how expensive the application's operation will be in terms of resources consumed by the logging subsystem. Therefore, optimizing the amount of logging in software source code is an important source code maintenance task assigned to a qualified software developer. This article examines the possibility of automating this task using an AI agent that optimizes the arrangement of logs using a predictive model that determines where to add/remove log collection instructions and a generative model that generates log collection instructions. The integrated development environment GIGA IDE was used as the agent runtime, and GIGA CODE was used as the provider of LLM, optimized for working with code.
Ключевые слова: AI-агенты, предиктивные модели, генеративные модели, логирование, GIGA IDE, GIGA CODE.
Keywords: AI agents, predictive models, generative models, logging, GIGA IDE, GIGA CODE.
Введение
Одним из самых распространенных способов наблюдения за работой программного обеспечения (ПО) является использование подсистем логирования [1]. Инструкции сбора логов расставляются в коде с момента написания, и часто количество точек логирования только растет, когда в код вносятся изменения [2]. При этом точки логирования будут добавляться:
- на этапах начальной отладки кода, чтобы отследить фактический характер работы алгоритма;
- на этапе стабилизации, чтобы понять источники исключений;
- на этапе интеграции, чтобы видеть входящие данные и данные получаемые из внешних источников;
- на последующих этапах миграции на новые источники данных, чтобы дополнительно учесть специфику новых источников.
Вопросы потребления ресурсов по причинам избыточного логирования недостаточно раскрыты в научной литературе. Однако, по мнению ряда практиков, например [3; 4; 5] в высоконагруженных системах вычислительные ресурсы, потребляемые для сбора логов могут значительно превышать 50 % от общего потребления со стороны ПО.
При этом, для Enterprise-решений, создаваемых параллельно несколькими командами, характерна ситуация, что в зоне передачи ответственности от одной команды другой инструкции логирования будут фактически находиться с нескольких сторон от точки взаимодействия. Как итог, по цепочке вызова в конечном приложении точек сбора логов может быть больше, чем логических функций / методов, обрабатывающих вызов.
В подобных случаях, чаще всего сам код ПО разрабатывает одна группа, а поддерживает другая — дежурная группа инженеров-разработчиков с жестким SLA на сроки исправления критических ошибок, породивших инцидент. Для последних детальные логи часто являются единственным знанием о коде, в котором должна быть исправлена ошибка.
Сама по себе процедура оптимизации расстановок точек логирования является трудоемкой и предполагает как знание собственных исходных кодов, которые легко могут достигать 1 млн строк кода, так и кода библиотек, которые также будут иметь собственный объем инструкций логирования. Чаще всего в командах разработки эта задача отводится техлиду, поскольку через процедуру ревью он скорее всего знаком со значительной частью кода. Также важно помнить, что на разных этапах жизненного цикла ПО, объем логирования должен быть разным. Чем больше собирается логов, тем быстрее выявляются проблемы и происходит стабилизация кода.
Для численной оценки связи по кодовой базе Сбера был проведен выборочный анализ (back-end приложения на Java) связи плотности инструкций логирования с количеством ошибок. Результат его приведен на рисунке 1.
/Slekenichs.files/image001.png)
Рисунок 1. a) Относительная зависимость DD (Defect Density) от плотности расстановок инструкци логирования. b) Относительная зависимость стоимости эксплуатации от плотности расстановки инструкции логирования
Плотность расстановки логов рассчитывалась как относительная доля публичных методов, значимых с точки зрения используемого framework (Spring, Jakarta), в которых есть хоть одна точка логирования. Примеры значимых методов:
- любой публичный метод в классе, помеченном аннотацией @Controller (Spring);
- публичный метод, помеченный аннотациями спецификации Jax-Rs (JSR 370);
- публичный метод, помеченный аннотацией @Bean (Spring) в типе, помеченном аннотацией @Configuration (Spring).
Как видно из рисунка 1 a), при плотности расстановки инструкций логирования более 70 %, начинается быстрая стабилизация ПО, что приводит к резкому сокращению дефектов. При плотности расстановки инструкций логирования менее 30 %, дефекты не идентифицируются активно по логам. В то же время разница в потреблении вычислительных ресурсов между плотностью покрытия логами в 30 % и 70 % покрытием логов достигает более чем в 3 раза.
Похожая зависимость наблюдается по количеству инструкций логирования по цепочке вызова. Соответствующие графики приведены на рисунке 2.
/Slekenichs.files/image002.png)
Рисунок 2. a) Относительная зависимость DD (Defect Density) от среднего кол-ва инструкций логирования по одной цепочке вызова в рамках layered architecture. b) Относительная зависимость стоимости эксплуатации от плотности расстановки инструкции логирования
Количество инструкций по цепочке вызова считалось как отношение суммы всех инструкций логирования последовательно по методам исходного кода проекта от методов, выполняющих роль API (Jax-Rs, Jax-Ws, Spring Web) до методов, вызывающих уже только библиотечные методы к количеству уникальных приемов в цепочке.
Пороговый характер поведения функций на рисунке 1 a) и 2 a) указывает на возможности оптимизации характера расстановки инструкция логирования для решения задач:
- на этапе интенсивного функционального развития: минимизация потребляемых ресурсов на логирование при условии быстрой стабилизации добавляемого функционала;
- на этапе эксплуатации легаси-решения: максимальная возможная прозрачность проведения при условии минимальных потребляемых ресурсов.
Соответствующие задачи удалось решить алгоритмическим путем создания предиктивной модели, предсказывающей точки, где необходимо добавлять инструкции логирования, а где они будут бесполезны. Предиктивная модель легла в основу AI-агента, который самостоятельно выполняет анализ и модификацию кода с целью оптимизации расстановки логирования.
Материалы и методы
На основе зависимостей на рисунках 1a) и 2a) была выдвинута гипотеза, что для любого ограниченного количества точек логирования можно таким образом оптимизировать их расстановку, чтобы сократить значение DD для данного ПО. Под оптимизацией понимается изменение состава точек логирования по методам за счет:
- добавления инструкций логирования framework SLF4J определенного типа в тело метода;
- изменения уровня логирования framework SLF4J с одного типа на другой;
- удаления всех инструкций логирования framework SLF4J из тела конкретного метода.
При этом добавление выполняется для увеличения количества собираемых логов, удаление — для экономии ресурсов, изменение уровня логирования — как и для увеличения количества собираемых логов, так и для экономии ресурсов. Рассматривалась возможность расстановки точек логирования для языка Java:
- в качестве первой инструкции в теле метода;
- в качестве последней инструкции перед инструкцией return для не void методов;
- в качестве первой инструкции блока catch.
Для ограничения количества метода, где рассматривается возможность оптимизации, общий код каждого проекта был редуцирован на основании следующих предположений.
- Код реализует слоистую архитектуру (layered architecture) вне зависимости от схемы компоновки по доменам: монолитная или микросервисная. Выделяются слои: API, Business Logic, Data access. Допустимо смешивание 2-х из трех смежных слоев.
- Код анализируемого проекта разработан на Java/Kotlin с использованием frameworks Spring и/или Jakarta (JavaX), которые имеют маркирующие аннотации и интерфейсы для слоев, приведенных в предыдущем допущении.
- Значимым для логирования является только код маркированных методов (функций) или публичные методы маркированных типов.
- Код приватных методов, декомпозирующих публичные методы, учет через цикломатическую сложность публичных методов по цепочкам вызова.
Предварительно целевая функция строилась для следующих уровней логирования: INFO, WARN, ERROR, DEBUG методом Random Forest [6]. Удалось построить функцию c R2 = 0.96. В качестве вектора параметров рассматривался суммарный индекс сложности входящих и возвращаемых параметров, включая атрибуты комплексных типов по всем возможным вариантам комбинаций наличия или отсутствия соответствующего уровня логирования на методе с соответствующей аннотацией. Всего 64 параметра.
Далее были собраны дополнительные данные о структуре кода для увеличения прогностической силы и заменой модели на LSTM (Long short-term memory) [7]. Для достижения R2 = 0.99 были дополнительно учтены:
- цикломатическая сложность кода метода;
- количество строк кода в методе;
- количество лямбда-выражений;
- глубина вызовов (количество методов, вызываемых из данного метода);
- результирующие зависимости по DD от доли методов, покрытых логами, для разных слоев Layered architecture представлены на рисунке ниже (рисунок 3)
/Slekenichs.files/image003.png)
Рисунок 3 Зависимость DD от доли методов, включающих логирование для разных слоев Layered architecture: a) уровень логирования INFO, b) уровень логирования WARN, с) уровень логирования ERROR, d) уровень логирования DEBUG
Как видно для всех 4-х уровней логирования в среднем присутствует зависимость между плотностью расстановки логов и DD. В одних случаях зависимость более крутая. В других случаях явно видно, что независимо от плотности логирования использования логов определенного типа является явно более эффективным решением, поэтому переключение типа логирования может как увеличивать, так и уменьшать их количество.
Результаты и обсуждение
Прикладное применение модели реализовано в формате what-if анализа кода проекта, на котором работал целевой агент. В качестве среды выполнения агента используется интегрированная среда разработки GIGA IDE [8]. Рассмотрим её подробнее.
- Код проекта с помощью встроенных инструментов GIGA IDE проверяется на наличие целевых frameworks. При их отсутствии, пользователь получает уведомление, что применение агента невозможно.
- Из кода проекта по маркерам frameworks также средствами GIGA IDE строится редуцированная форма кода. Далее агент самостоятельно оценивает по модели метрику DD.
- Для каждого маркированного члена выполняется what-if анализ: как меняется целевая метрика если определенная модификация кода с точки зрения добавления / удаления логирования будет выполнена.
- Если код не является модифицированным, а модификация приведет к улучшению показателя больше чем определенный порог (TA), то модификация будет предложена пользователю либо выполнена в автоматическом режиме.
- Если код уже является модифицированным, например, в случае с логированием, пользователь добавил сам инструкции логирования, и отмена модификации приведет к ухудшению показателя меньше чем определенный порог (TR), пользователю будет предложено отменить модификацию.
Правила валидации и модификации кода, представленные в таблице ниже, были реализованы в форме отдельных инспекций (inspections) и автоматических модификаций кода (quick fix), реализованные через соответствующее API GIGA IDE. Правила, базирующиеся на использовании предиктивной модели, опираются на модельное значение DD в рамках what-if анализа до модификации (DDB) и после возможной модификации (DDM).
Таблица 1.
Варианты модификации кода с точки зрения управления логированием
|
Тип |
Описание и условие применение |
|
Предиктивный |
Добавляет логирование уровня, который покажет максимальное уменьшение DD: DDM - DDB > TA |
|
Предиктивный |
Меняет в текущей точке логирования уровень логирования на тот, который покажет максимальное уменьшение DD: DDM - DDB > TA |
|
Предиктивный |
Удаляет точку сбора логов за счет добавления символов комментария в начале строки: DDM - DDB < TR |
|
Предиктивный Эмпирический |
Дезактивирует точку сбора логов в зависимостях за счет добавления соответствующего типа конфигурации:
|
|
Эмпирический |
Выявляет точки логирования с одинаковым комментарием в одном классе, заменяет на варианты сгенерированные с помощью GIGA CODE по контексту использования точки логирования |
|
Эмпирический |
Понижает уровень логирования для точка логирования внутри циклического алгоритма с высоким уровнем логирования, избыточным для эксплуатации ПО |
Здесь важно отметить, что код по зависимостям также подлежит анализу, однако варианты модификации ограничены только возможностью отключения сбора логов через инструкции, определенные в библиотеках. Поэтому модификация кода выполняется разными способами, приводимыми автором ниже.
- Для добавления логирования непосредственно в исходный код проекта, за счет добавления вызова методов библиотеки SLF4J (Simple Logging Facade for Java). Инструкции типовые и не требует применения LLM. Однако генерация текста комментария выполнялась по сигнатуре метода и типа с помощью GIGA CODE [9], плагин, которой также предустановлен в GIGA IDE.
- Для удаления избыточных инструкций логирования в начало строки с предписанием добавлялись символы комментирования строки.
- Для удаления избыточных инструкций логирования в коде, подключаемом как зависимости, использовались конфигурации подсистемы логирования, подключаемой через SLF4J API.
Параметры TA и TR, описанные выше, требуют дополнительного конфигурирования. Причем TA < TR, что не очевидно для пользователя, если предложить возможность прямого редактирования данных параметров через пользовательский интерфейс. Поэтому некоторые рекомендуемые значения параметров могут быть вычислены на основании задачи, для которой применяется агент.
Как говорилось выше, цели оптимизации кода по составу инструкций логирования могут быть разные. Поэтому параметры конфигурации могут быть вычислены от цели, как показано в таблице 2.
Таблица 2.
Пример набора режимов работы агента с разным набором порогов
|
Цель |
Как вычислены |
|
Экономия ресурсов |
Значения TA и TR такие, что проект попадает в 20% проектов с минимальной плотностью инструкций логирования. Ожидается, что низкая плотность логов позволит максимально сэкономит на инфраструктуре для сбора и хранения логов. |
|
Развитие ПО |
Значения TA и TR такие, что проект попадает в 60% проектов со средней плотностью инструкций логирования. Ожидается, что плотность логов будет достаточной для развития проекта без ухудшения метрики. |
|
Стабилизация ПО |
Значения TA и TR такие, что проект попадает в 20% проектов с максимальной плотностью инструкций логирования. Ожидается, что высокая плотность логов позволит как можно быстрее стабилизировать работу ПО. |
В начале статьи указывалось на то, что задача логирования является достаточно комплексной и на разных стадиях жизни ПО, инженеры-разработчики преследуют разные цели, добавляя-удаляя инструкции логирования. Отдельный вопрос — это как часто и при каких обстоятельствах данная задача вообще решается.
Практика показала, что в идеальном случае контроль над тем, как расставлены инструкции сбора логов, что конкретно туда передается, осуществляется не чаще чем один раз за один релиз. К этому времени все задачи отладки отдельных алгоритмов внутри методов должны быть решены. Также является актуальной проблемой вопрос: «Является ли “копи-паст” инструкций логирования, когда разработчик копирует строку инструкций, забывая изменить текст сообщения в логах?» Для контроля возможных проблем были добавлены последние два валидатора из таблицы 1.
Частота и обстоятельства выполнения задачи оптимизации делают ведущим режим пакетной обработки кода, когда пользователь имеет возможность запускать полный анализ, провести валидацию и применить функцию “исправить все”. В качестве легкого варианта есть дополнительная настройка, отбирающая TOP N возможных модификаций, которые имеют максимальное влияние. Например, пользователь может самостоятельно ознакомиться с ограниченным списком предлагаемых модификаций и принять решение, какие именно изменения из предлагаемых вносить.
Возможна ситуация, когда значения о коде проекта крайне гранулированы среди отдельных разработчиков, пакетный режим может выглядеть для каждого участника как опасным с точки зрения модификации всего кода, так и дорогим с точки зрения просмотра рекомендаций и сортировки их по области кода, в которой разбирается конкретный разработчик. Тогда менее инвазивным выглядит: (a) режим работы с выводом in-line подсказок по методам конкретного модифицируемого класса; (b) пакетная обработка только модифицированного набора классов перед коммитом, выполняемая GIGA IDE для всех активных валидаторов.
Заключение
Проведены статистические исследования влияния плотности расстановки инструкций сбора логов на плотность дефектов. Выявлено, что количество обнаруживаемых ошибок в коде растет с ростом концентрации плотностью расстановки точек логирования, однако увеличение является нелинейным и имеет определенное насыщение.
На основании статистического исследования построена предиктивная модель, предсказывающая влияние точки логирования в конкретном коде на возможность снизить плотность ошибок в нём. Модель внедрена с использованием отдельного агента в форме плагина к среде разработки GIGA IDE с использованием AI-помощника GIGA CODE.
Список литературы:
- Rice R. E., Borgman C. L. The use of computer-monitored data in information science and communication research // Journal of the American Society for Information Science. — 1983. — Vol. 34. — No. 4. — Pp. 247–256.
- El-Masri D., Petrillo F., Guéhéneuc Y.-G., Hamou-Lhadj A., Bouziane A. A systematic literature review on automated log abstraction techniques // Information and Software Technology. — 2020. — Vol. 122. — Art. 106276. — DOI: 10.1016/j.infsof.2020.106276.
- Welch R. Scaling observability: effective logging on a budget // New Relic Blog. [Электронный ресурс]. — Режим доступа:: https://newrelic.com/blog/best-practices/logging-on-a-budget (дата обращения: 10.11.2025).
- Isaiah A. How to reduce logging costs with log sampling // Better Stack Community Guides. [Электронный ресурс]. — Режим доступа: https://betterstack.com/community/guides/logging/log-sampling/ (дата обращения: 10.11.2025).
- Sonpatki P. Logging best practices to reduce noise and improve insights // Last9 Blog. [Электронный ресурс]. — Режим доступа: https://last9.io/blog/logging-best-practices/ (дата обращения: 10.11.2025).
- Breiman L. Random forests // Machine Learning. — 2001. — Vol. 45. — No. 1. — Pp. 5–32. DOI: 10.1023/A:1010933404324.
- Hochreiter S., Schmidhuber J. Long short-term memory // Neural Computation. — 1997. — Vol. 9. — No. 8. — Pp. 1735–1780. DOI: 10.1162/neco.1997.9.8.1735.
- Интегрированная среда разработки GIGA IDE [Электронный ресурс]. — Режим доступа: https://gigaide.ru/ (дата обращения: 10.11.2025).
- AI-ассистент разработчика GIGA CODE [Электронный ресурс]. — Режим доступа: https://gigacode.ru/ (дата обращения: 10.11.2025).