Когда система «падает», а времени на вдумчивый разбор логов нет, на помощь может прийти не еще один разработчик, а LLM. Нейросеть показала достойный результат вКогда система «падает», а времени на вдумчивый разбор логов нет, на помощь может прийти не еще один разработчик, а LLM. Нейросеть показала достойный результат в

LLM для «ремонта» 1С: как ИИ помогает анализировать логи

33c3d3c216697f1f2218569dafdd5170.png

Когда система «падает», а времени на вдумчивый разбор логов нет, на помощь может прийти не еще один разработчик, а LLM. Нейросеть показала достойный результат в качестве ассистента при диагностике ошибок 1С.

Привет, Хабр! Меня зовут Евгений Филиппов, я эксперт департамента корпоративных решений IBS. Поговорим о том, как можно использовать ИИ для разбора логов 1С при возникновении некоторых характерных ошибок параллельной работы.

Идея этого подхода родилась в цейтноте. Ручной разбор логов требует свежей головы, а очередная проблема заказчика появилась, когда я был в отъезде, да еще и под конец рабочего дня. Полноценно разобрать ее вручную просто не было возможности. Поскольку поиск решения нельзя было откладывать, я провел подготовку: отфильтровал и обезличил логи и скормил выжимку нескольким LLM. Получившийся результат перепроверил, и он оказался вполне хорош.

Спойлер: LLM не сделают из джуна эксперта по 1С, но вполне помогут сэкономить этому эксперту время и силы.

Вместо предисловия

Мы в компании сопровождаем проекты, в которых есть базы 1С. Как и в любых ИТ-решениях, в них порой возникают проблемы. Единственный способ найти их реальный источник, а не подкрутить что-то по наитию — это разобрать логи, технологический журнал 1С, он же ТЖ, представленный, как правило, в виде текстового файла с запятой в качестве разделителя. В более современных версиях встречается лог в формате JSON, но это не так важно с точки зрения описываемого подхода.

Обращаясь за решением своей проблемы, заказчик пересылает собранный лог партнеру 1С, тот его изучает и находит причину возникновения ошибки. По итогам дает рекомендации по исправлению.

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

  • разобрать ТЖ с помощью Центра управления производительностью — ЦУП, из состава 1С:КИП8. Он может анализировать чужие журналы, но для этого в нем должна быть актуальная структура метаданных, то есть нужна дополнительная информация из исследуемой базы;

  • использовать локальные средства автоматизации: либо самописные парсеры, работающие с текстами, либо некую СУБД, куда можно загрузить журнал и получить данные с помощью запросов. К сожалению, такие инструменты зачастую работают только в рамках собственной инфраструктуры;

  • работать полностью вручную, используя Notepad++ в Windows или консольные утилиты, типа grep в Linux/WSL.

ЦУП и каких-то собственных подходящих скриптов под рукой в поездке не оказалось, поэтому оставался только ручной разбор. Это очень много рутины, которую я попробовал автоматизировать при помощи бесплатных ИИ — в моем примере Qwen и DeepSeek.

Разберем, как это происходит, на примере двух реальных задач:

  • анализа плохих запросов (длинные DBPOSTGRS);

  • разбора взаимной блокировки (TDEADLOCK).

Дисклеймер. ИИ не решает задачу полностью. Логи необходимо собрать вручную. Перед тем как передавать их нейросети, рекомендую отфильтровать из них интересующие события, поместив в отдельный файл, а потом обезличить данные. И только потом вопрос можно передавать на анализ ИИ. Ответ ни в коем случае нельзя напрямую пересылать заказчику. Его надо проанализировать и перепроверить.

Анализ плохих запросов

Рассмотрим использование LLM при разборе ситуации с «подвисающими» транзакциями.

Предварительные настройки

Чтобы анализировать долгие запросы, в logcfg.xml необходимо заранее включить их запись в лог. У наших заказчиков обычно в файл включена подобная секция:

<log location="C:\Logs\Long_DB" history="168"> <event> <eq property="name" value="dbpostgrs"/> <eq property="p:processName" value="имя_базы"/> <ge property="durationus" value="5000000"/> </event> <property name="all"/> </log>

Так включается логирование запросов, которые выполняются более 5 секунд. Но будьте готовы к тому, что вам пришлют сотни мегабайт логов.

Можно настроить другой порог или уже после инцидента из готовых логов выделить нужное — допустим, запросы длиннее 100 секунд. Для этого выполняем поиск по всем подпапкам полученного ТЖ и выводим их в отдельный текстовый файл:

cat rphost*/*.log | awk -vORS= '{if(match($0, "^[0-9][0-9]\:[0-9][0-9]\.[0-9]+\-")) print "\n"$0; else print $0;}' | grep -P '\d{9},dbpostgrs' -i | sed -e "s/\xef\xbb\xbf/ /g" > analiz_longest_db.txt

Фильтрация файла логов

Как отметил выше, не обязательно анализировать все присланные сотни мегабайт. Я отфильтровал запросы длиннее 100 секунд. Чтобы использовать команды Linux для работы с логами, у меня стоит Windows Subsystem for Linux, так что это чисто техническая работа. На выходе — небольшой файл с самыми плохими запросами.

Готовый файл можно просмотреть глазами и выбрать интересующие события.

36:29.287000-22967951,DBPOSTGRS,5,level=DEBUG,process=rphost,p:processName= XXXX, ,OSThread=12248,t:clientID=55,t:applicationName=1CV8C,t:computerName= XXXX,t:connectID=6828,SessionID=485659,Usr= XXXX,AppID=1CV8C,DBMS=DBPOSTGRS,DataBase=XXXX,Trans=0,dbpid=680855,Sql="INSERT INTO pg_temp.tt184 (_Q_001_F_000, Q001_F_001RRef, Q001_F_002RRef) SELECTSUM(T2.Fld23454Turnover_),T2.Fld23443RRef,T2.Fld23451RRefFROM pg_temp.tt175 T1LEFT OUTER JOIN (SELECTT3._Fld23443RRef AS Fld23443RRef,T3._Fld23451RRef AS Fld23451RRef,SUM(T3._Fld23454) AS Fld23454Turnover_FROM AccumRg23441 T3WHERE ((T3.Fld1016 = CAST(0 AS NUMERIC))) AND (T3._Period >= '2025-01-01 00:00:00'::timestamp AND T3._Period <= '2025-08-15 00:00:00'::timestamp AND T3._Active = TRUE AND (T3._Fld23443RRef IN(SELECTT4._Q_001_F_000RRef AS Q_001_F_000RRefFROM pg_temp.tt175 T4) AND (NOT (((T3._Fld23447RRef IN ('\\263\\033\\255\\036ap\\264mB\\301\\306\\251\\007;0\\017'::bytea, '\\217MZ\\337e\\357(\\201@~\\211\\245Q\\015\\000\\200'::bytea)))))))GROUP BY T3._Fld23443RRef,T3._Fld23451RRefHAVING (SUM(T3._Fld23454)) <> CAST(0 AS NUMERIC)) T2ON (T1._Q_001_F_000RRef = T2.Fld23443RRef)GROUP BY T2.Fld23443RRef,T2.Fld23451RRef",RowsAffected=2138,Result=PGRES_COMMAND_OK,Context='Форма.Вызов : ВнешняяОбработка. XXXX.Форма.Форма1.Модуль.ЗаполнитьНаСервере
ВнешняяОбработка. XXXX.Форма.Форма1.Форма : 555 : СоответствиеДоходов = Справочники. НастройкиРасчетаНДФЛ.ПолучитьДоходыДоДатыСобытияБезДетализацииПоРегистраторуФизическиеЛица(Объект.ДатаКон, Объект.ТабЧасть.Выгрузить(, "ИД"));
Справочник. НастройкиРасчетаНДФЛ.МодульМенеджера : 777 : Выборка = Запрос.Выполнить().Выбрать();'

Здесь я уже вижу два плохих момента. Они выделены в тексте:

  • первое выделенное условие — проверка, что поле входит в некую таблицу. Этот поиск сработает быстро, только если нам повезет — если поможет индекс;

  • самое плохое условие — второе. Это поиск поля, которое не должно входить в таблицу. Для этого таблицу необходимо просканировать целиком — если она большая, выполняться запрос будет очень долго.

Текст лога надо обезличить — убрать имена базы, пользователей и тому подобное. После этого его можно скормить ИИ, чтобы выяснить, не пропустил ли я что-то еще.

Промпт и ответ

При отправке ИИ текст запроса надо сопроводить правильным промптом: «что в тексте запроса может привести к его медленной работе».

Если ответ LLM вас не устроил, потому что, допустим, не содержит того, что вы нашли глазами, можно уточнить, спросив: «AND (NOT (((T3._Fld23447RRef IN не вошло в результат вашего разбора. Оно проблематично или нет?»

Если вы правы, ИИ даст уточнение, если нет, опровержение.

Рекомендую полностью не полагаться на результаты и использовать более одной ИИ-модели. Я перепроверяю одну LLM другой. Использую QWEN и DeepSeek, поскольку они решают задачи немного по-разному.

Фрагмент ответа QWEN

Вот фрагмент ответа нейросети, которая, на мой взгляд, лучше справилась с этой задачей. Текст от нейросети дополню своими комментариями.

Прежде чем советовать заказчику добавить индекс, надо убедиться, что в его случае он поможет. На сегодняшний день для баз 1С рекомендации «добавить индексы» редко бывают полезными, потому что платформа и так создает наиболее ходовые индексы. Просчеты архитектора или разработчика, когда требуется индекс, а его нет, случаются, но, судя по моей практике, это редкость. Позже я отмечал, что «добавить индексы» — это то, что LLM предлагают делать по умолчанию. Но на других задачах я с целью проверки пытался создавать все те индексы, что рекомендовали LLM, в том числе составные, и это никак не помогало. Тезис о том, что при не полностью подходящем индексе случится Seq Scan, — это сильное упрощение со стороны LLM.

На это я тоже обратил внимание. Попробовать заменить НЕ В () на ЛЕВОЕ СОЕДИНЕНИЕ ... ГДЕ ... ЕСТЬ NULL — это хорошая гипотеза для проверки.

Когда я наткнулся на этот пример, август 2025 года был уже в прошлом. Но оговорка про будущую дату для ИИ — нормальное явление.

Честно скажу, при первом визуальном анализе это я пропустил. Можно рассмотреть как еще одну хорошую гипотезу.

При отправке запроса в LLM именно это и было для меня важно — получить более широкий взгляд и не упустить детали. В примере запрос один и не такой уж большой. Но даже в нем глазами удалось обнаружить не все. В большом запросе или при разборе целого пула запросов гарантированно будет пропущено что-то важное, а скорость «ручной» обработки этих данных может сильно падать.

Далее в рекомендациях от LLM идет предложение дать результат EXPLAIN (ANALYZE), но это в условиях командировки технически невыполнимо.

Разбор взаимной блокировки

Рассмотрим теперь разбор взаимной блокировки двух транзакций.

Для тех, кто не в курсе, что такое взаимная блокировка, объясню «на пальцах».

Предположим, в магазине есть две кассы: одна продает алкоголь, другая — сигареты. Напомню, что при продаже этих товаров кассы должны обращаться к соответствующим государственным базам.

Обе кассы открылись на обслуживание: к первой подошел покупатель с бутылкой вина, на второй клиент покупает сигареты. Но покупателю из первой кассы внезапно потребовались сигареты, а покупателю со второй — банка пива. Не прерывая работу с кем-то из клиентов, кассы не могут обслужить одновременные запросы. Это и называется взаимной блокировкой. В транзакционных системах подобные блокировки решаются отказом в обслуживании одному из клиентов, выбранному по определенному алгоритму или случайным образом.

Предварительные настройки

Как и в случае с предыдущей задачей, необходимо включить запись соответствующих событий (управляемых блокировок) в logcfg.xml.

<log location="C:\Logs\TLOCKS" history="168"> <event> <eq property="name" value="tlock"/> <eq property="p:processName" value="имя_базы"/> </event> <event> <eq property="name" value="tdeadlock"/> <eq property="p:processName" value="имя_базы"/> </event> <event> <eq property="name" value="ttimeout"/> <eq property="p:processName" value="имя_базы"/> </event> <property name="all"/> </log>

Фильтрация файла логов

Получаем логи, выбираем оттуда TDEADLOCK

cat /.log | grep 'tdeadlock' -i > tdeadlocks.txt

Выбираем интересный нам TDEADLOCK, например

24:52.003002-0,TDEADLOCK,5,p:processName=ХХХХХ,t:connectID=2067058,DeadlockConnectionIntersections='2067058 2065308 InfoRg63347.DIMS Exclusive Fld10045=228 Fld63348="a76c0382-8823-11f0-9ef6-fa163e696ce9",2065308 2067058 InfoRg41351.DIMS Exclusive Fld2302=228 Fld41352=329:9b00fa163e037b5d11eeab93b4f4ecf8 Fld41353=1019:934cfa163ecb6e9b11f09f74351321e0',Context='

Здесь есть информация, кто с кем пересекся и кто был выбран «жертвой» для прекращения обслуживания.

В этой блокировке два t:connectID и два InfoRg. Пишем скрипт, выясняющий, что делал каждый из участников взаимоблокировки до этого. tid — правая часть от t:connectID.

cat rphost*/*.log | awk -vORS= '{if(match($0, "^[0-9][0-9]\:[0-9][0-9]\.[0-9]+\-")) print "\n"$0; else print $0;}' | grep -P '(tid=2067058|tid=2065308).+(InfoRg63347|InfoRg41351)' -i | sed -e "s/\xef\xbb\xbf/ /g" > analiz.txt

По файлу analiz.txt можно вручную построить граф взаимоблокировки. Из него будет видно, что причина — захват ресурсов в разном порядке. Но в экспериментальных целях отдаем файл ИИ-модели с промптом «найди причину tdeadlock».

Отдаем, естественно, обезличенный файл — analiz2.txt. Он может быть относительно большим, поэтому, чтобы не обезличивать вручную, вырезаем имя базы и другие чувствительные поля, используя sed:

sed 's/p:processName=ХХХХХ//g' analiz.txt > analiz2.txt

Фрагмент ответа QWEN

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

Абсолютно правильная, можно сказать, классическая рекомендация, которая полностью устранит взаимную блокировку.

Это решение уменьшит вероятность взаимной блокировки. Правда, при большой нагрузке мы все равно будем на нее натыкаться.

Здесь у ИИ пошли галлюцинации в терминологии.

Логировать начало и конец транзакций полезно для диагностики, но накладно. Годится для поимки конфликта на коротком интервале, но не для дежурного мониторинга.

Заключение

На двух классических и сложных задачах — поиске причин медленных запросов и диагностике взаимоблокировок — анализ технологического журнала 1С с привлечением публичных LLM-моделей показал свою эффективность.

Вначале я упоминал, что использовал две LLM, но привел ответы только одной. На мой взгляд, с данными проблемами она справилась лучше. Но я не ставил себе задачу сравнить ИИ-модели. Эксперименты показали, что наилучшая тактика — использование именно множественных моделей для взаимной проверки их рекомендаций.

Как я и говорил в начале, использование LLM не сделает из джуна эксперта, способного решать любые кейсы. ИИ действует как мощный ассистент — обрабатывает рутину и генерирует гипотезы, которые эксперт затем проверяет и верифицирует. Его ключевые преимущества:

  • скорость. ИИ-ассистент за секунды обрабатывает объемы данных, на ручной разбор которых могли бы уйти десятки минут;

  • глубина: модель замечает неочевидные для человеческого глаза паттерны и генерирует множество гипотез, расширяя круг поиска эксперта;

  • доступность: для использования метода не требуется развертывание дополнительной инфраструктуры у заказчика или доступа к его продуктивной среде, что часто является критическим ограничением.

Но и недостатки присутствуют:

  • ложные и бесполезные рекомендации, как в первом примере с индексами;

  • дополнительная работа по обезличиванию данных, передаваемых LLM;

  • необходимость глубокой проверки рекомендаций.

Хочется закончить предостережением. За рекомендации, переданные заказчику, отвечаете вы, а не ИИ. Если просто скопировать все пункты, у заказчика появятся вполне логичные замечания, что предложенные варианты не работают. Их необходимо перепроверять самому, и делать это внимательно.

Источник

Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу [email protected] для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.