Метод ЗаписьЖурналаРегистрации: как фиксировать свои события в 1С 8.3
Содержание
Чтобы создать запись в журнале регистрации 1С программно, вызовите глобальный метод ЗаписьЖурналаРегистрации("ИмяСобытия", УровеньЖурналаРегистрации.Информация, , Ссылка, "Комментарий") в серверном коде. Запись появится в журнале сразу, её видно через Администрирование → Обслуживание → Журнал регистрации с отбором по имени события.
Типичная ситуация: обмен с сайтом ночью «молча» не выгрузил часть заказов, а утром никто не может сказать, что произошло. Свои записи в журнал регистрации решают это: код сам оставляет след, кто, когда и с каким объектом работал и где упал. Метод общий для платформы 8.3 и не зависит от конфигурации: одинаково работает в БП 3.0, ЗУП 3.1, УТ 11 и самописных базах.
Синтаксис метода ЗаписьЖурналаРегистрации
Полная форма вызова:
ЗаписьЖурналаРегистрации(
ИмяСобытия, // Строка — обязательный
Уровень, // УровеньЖурналаРегистрации — необязательный
ОбъектМетаданных, // ОбъектМетаданных или массив — необязательный
Данные, // ссылка или примитивное значение — необязательный
Комментарий, // Строка — необязательный
РежимТранзакции // РежимТранзакцииЗаписиЖурналаРегистрации — необязательный
);
Что передавать в каждый параметр:
| Параметр | Тип | Что пишем | Колонка в журнале |
|---|---|---|---|
| ИмяСобытия | Строка | Своё имя вида «Подсистема.Действие» | Событие |
| Уровень | УровеньЖурналаРегистрации | Информация, Примечание, Предупреждение, Ошибка | Уровень (значок) |
| ОбъектМетаданных | ОбъектМетаданных | Метаданные.Документы.РеализацияТоваровУслуг | Метаданные |
| Данные | Ссылка, число, строка, дата | Ссылка на документ или элемент | Данные |
| Комментарий | Строка | Текст ошибки, суммы, детали | Комментарий |
| РежимТранзакции | Перечисление | Независимая (по умолчанию) или Транзакционная | Транзакция, статус |
Минимальный рабочий вызов — только имя события. Уровень по умолчанию — «Информация».
ЗаписьЖурналаРегистрации("ОбменССайтом.Старт");
Где метод доступен
Метод работает на сервере, в толстом клиенте и во внешнем соединении. В тонком клиенте и веб-клиенте его нет. Из формы вызывайте серверную процедуру:
&НаСервереБезКонтекста
Процедура ЗаписатьСобытиеНаСервере(ТекстСобытия)
ЗаписьЖурналаРегистрации("МояОбработка.Действие",
УровеньЖурналаРегистрации.Информация, , , ТекстСобытия);
КонецПроцедуры
В типовых конфигурациях на БСП для клиента есть общий модуль ЖурналРегистрацииКлиент. Его процедура ДобавитьСообщениеДляЖурналаРегистрации копит сообщения на клиенте и отправляет их на сервер пачкой. Это экономит серверные вызовы, если событий много.
Имена событий и уровни важности записей
Как назвать своё событие
Имя события — обычная строка, но от неё зависит, сможете ли вы потом найти записи. Платформенные события начинаются с _$ (например, _$Data$.Update). Свои имена так начинать нельзя: смешаются с системными.
Рекомендованная схема — через точку, от общего к частному:
- 📦
ОбменССайтом.ВыгрузкаЗаказов - 🧾
ЗагрузкаВыписки.РазборСтроки - 🔐
ПроверкаЛимита.ПревышениеКредита
В типовых конфигурациях имя оборачивают в НСтр с кодом основного языка:
ИмяСобытия = НСтр("ru = 'Обмен с сайтом.Выгрузка заказов'",
ОбщегоНазначения.КодОсновногоЯзыка());
Так имя одинаково на любом языке интерфейса пользователя, и отбор в журнале не «разъезжается». Если БСП в базе нет, пишите имя строкой без НСтр.
Заведите имена событий константами в общем модуле (функция ИмяСобытияОбмена() и т. п.). Опечатка в имени — и половина записей не попадёт в отбор.
Четыре уровня важности
Перечисление УровеньЖурналаРегистрации содержит четыре рабочих значения:
| Уровень | Когда использовать | Пример |
|---|---|---|
| Ошибка | Операция не выполнена | Документ не провёлся из-за исключения |
| Предупреждение | Выполнено, но с отклонением | Строка выписки пропущена: не найден контрагент |
| Информация | Обычный факт | Обмен завершён, выгружено 148 заказов |
| Примечание | Отладочные детали | Время каждого этапа обмена |
Есть ещё значение Нет — оно используется для настройки, а не для записи событий.
Уровень влияет на то, сохранится ли запись вообще. В Конфигураторе, меню Администрирование → Настройка журнала регистрации, задаётся, какие уровни база пишет. Если там выбрано «Регистрировать ошибки», ваши «Информации» и «Примечания» в журнал не попадут. Проверить настройку из кода можно через ПолучитьИспользованиеЖурналаРегистрации().
Привязка записи к объекту, данным и пользователю
Три параметра делают запись «адресной». Без них журнал превращается в поток строк, где не понять, к чему что относится.
ОбъектМетаданных
Сюда передают объект из дерева метаданных, а не ссылку:
// правильно
Метаданные.Документы.ПоступлениеТоваровУслуг
// тоже правильно — из ссылки
ДокументСсылка.Метаданные()
Можно передать массив объектов метаданных, если событие касается нескольких. В журнале это колонка «Метаданные» — по ней удобно фильтровать: «все события по документу Поступление».
Данные
Сюда кладут конкретную ссылку: документ, элемент справочника. Журнал покажет её представление, а двойной щелчок по колонке «Данные» открывает объект. Это главное отличие от записи ссылки в комментарий строкой: строку открыть нельзя, а по ссылке можно отфильтровать все события объекта.
Структуры, таблицы значений и объекты (не ссылки) в «Данные» не передавайте. Сложные детали сериализуйте в текст и отправьте в комментарий.
Пользователь и компьютер
Пользователя, компьютер, приложение клиента, сеанс и время платформа добавляет сама. Передавать их не нужно — и нельзя: таких параметров у метода нет.
Нюанс для фоновых и регламентных заданий: в журнале будет пользователь, от имени которого запущено задание. Если задание работает без пользователя, колонка «Пользователь» пустая. Когда важно знать инициатора, допишите его в комментарий:
Комментарий = СтрШаблон("Инициатор: %1; заказов: %2",
Строка(ПараметрыЗадания.Инициатор),
Формат(КоличествоЗаказов, "ЧН=0; ЧГ=0"));
Пример кода: журналирование в модуле документа
Задача: в документе «Реализация товаров и услуг» фиксировать попытки провести продажу сверх кредитного лимита. Сам документ не блокируем, но оставляем предупреждение. Ошибки проведения — пишем с уровнем «Ошибка».
Код в модуле объекта документа:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
ИмяСобытия = "ПроверкаЛимита.Реализация";
Попытка
Лимит = ПолучитьКредитныйЛимит(Контрагент); // своя функция
Если Лимит > 0 И СуммаДокумента > Лимит Тогда
ЗаписьЖурналаРегистрации(ИмяСобытия,
УровеньЖурналаРегистрации.Предупреждение,
Метаданные(),
Ссылка,
СтрШаблон("Превышен лимит: сумма %1, лимит %2, контрагент %3",
Формат(СуммаДокумента, "ЧДЦ=2; ЧГ=0"),
Формат(Лимит, "ЧДЦ=2; ЧГ=0"),
Строка(Контрагент)));
КонецЕсли;
// ... формирование движений ...
Исключение
ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации(ИмяСобытия,
УровеньЖурналаРегистрации.Ошибка,
Метаданные(),
Ссылка,
ТекстОшибки);
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры
Разберём, почему код написан именно так:
Метаданные()внутри модуля объекта возвращает метаданные текущего документа — не нужно писать путь вручную.Ссылкав «Данных» даёт переход к документу прямо из журнала. У нового, ещё не записанного документа ссылка пустая, поэтому журналировать лучше вОбработкаПроведенияилиПриЗаписи, а не вПередЗаписьюнового объекта.- Числа идут через
ФорматсЧГ=0, иначе в комментарии будут неразрывные пробелы между разрядами, и поиск по сумме не сработает. - В блоке
Исключениесначала пишем в журнал, потомВызватьИсключениебез параметров. Ошибка не «глотается», пользователь её видит, а в журнале остаётся полный стек. ПодробноеПредставлениеОшибкидаёт текст со стеком вызовов и номерами строк модуля.КраткоеПредставлениеОшибки— только сообщение, его показывают пользователю.
Режим записи по умолчанию — Независимая. Запись попадает в журнал сразу и остаётся, даже если транзакция проведения откатится. Для ошибок это ровно то, что нужно: иначе след упавшего проведения исчез бы вместе с откатом.
Режим «Транзакционная»
Иногда нужно обратное: событие имеет смысл, только если транзакция зафиксирована. Например, «документ отправлен в ЭДО» не должно висеть в журнале как свершившийся факт, если запись документа откатилась.
ЗаписьЖурналаРегистрации("ОтправкаЭДО.Поставлен",
УровеньЖурналаРегистрации.Информация,
Метаданные(), Ссылка, ,
РежимТранзакцииЗаписиЖурналаРегистрации.Транзакционная);
В этом режиме запись привязывается к текущей транзакции. В журнале у неё будет статус транзакции: зафиксирована или отменена. При анализе фильтруйте по колонке «Статус транзакции».
Нагрузка на базу и ограничения журнала
Журнал регистрации — файлы на диске, а не таблицы базы. В файловой базе они лежат в каталоге 1Cv8Log рядом с 1Cv8.1CD. В клиент-серверной — на сервере 1С, в каталоге кластера srvinfo\reg_1541\<GUID базы>\1Cv8Log. Формат задаётся в настройке журнала: старый текстовый (файлы .lgf и .lgp) или SQLite (файл .lgd).
Что из этого следует для программиста:
- 🐢 Каждая запись — операция ввода-вывода. Вызов в цикле по 50 000 строкам загрузки заметно замедлит обработку. Пишите итог: «загружено 49 812, пропущено 188», а пропущенные строки — одной записью с перечнем в комментарии.
- 📈 Журнал растёт. Уровень «Примечание» на каждую строку обмена за месяц даёт гигабайты. Отладочный уровень включайте флагом в константе или параметре обработки, а не постоянно.
- 🔎 Чтение медленное на больших объёмах. Отбор по событию на журнале в десятки гигабайт идёт минутами. Помогает разбиение журнала по периодам в той же настройке и регулярное сокращение.
- 🔒 Записи нельзя изменить из кода. Метода «исправить» или «удалить одну запись» нет. Сократить журнал можно только целиком по дате — в настройке журнала регистрации в Конфигураторе.
- 📏 Длинный комментарий читается плохо. Стек на 200 строк в окне журнала неудобен. Пишите в комментарий суть и стек, а большие дампы данных — в файл или регистр сведений .
Если нужно хранить события годами и строить по ним отчёты, журнал регистрации — не лучшее место. Сделайте свой регистр сведений «Протокол обмена»: он в базе, попадает в резервную копию .dt и обрабатывается запросами.
| Задача | Журнал регистрации | Свой регистр сведений |
|---|---|---|
| Разовая диагностика ошибки | ✅ Удобно | Избыточно |
| Аудит действий пользователей | ✅ Есть автоматически | Нужно писать код |
| Отчёт по событиям за год | Медленно | ✅ Запрос за секунды |
Перенос в другую базу через .dt | Не переносится | ✅ Переносится |
| Запись при откате транзакции | ✅ В режиме «Независимая» | Откатится вместе с транзакцией |
Чтение журнала регистрации программно
Для выборки событий из кода есть метод ВыгрузитьЖурналРегистрации. Он заполняет таблицу значений или пишет в XML-файл.
&НаСервере
Функция ОшибкиОбменаЗаСутки()
УстановитьПривилегированныйРежим(Истина);
Отбор = Новый Структура;
Отбор.Вставить("ДатаНачала", НачалоДня(ТекущаяДатаСеанса()));
Отбор.Вставить("ДатаОкончания", КонецДня(ТекущаяДатаСеанса()));
Отбор.Вставить("Событие", "ОбменССайтом.ВыгрузкаЗаказов");
Отбор.Вставить("Уровень", УровеньЖурналаРегистрации.Ошибка);
Результат = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(Результат, Отбор,
"Дата,ИмяПользователя,Данные,Комментарий", , 500);
Возврат Результат;
КонецФункции
Пояснения:
- Чтение журнала требует права «Администрирование». У обычного пользователя метод упадёт с ошибкой прав, поэтому в серверном коде включаем привилегированный режим.
- В отборе «Событие» и «Уровень» можно передать массив значений, если нужно несколько событий или уровней сразу.
- Третий параметр — список колонок через запятую. Выгружайте только нужные: так быстрее и меньше памяти.
- Пятый параметр ограничивает число записей. Без него на большом журнале легко выгрузить миллион строк.
- Другие полезные поля отбора: «Пользователь», «Данные» (ссылка), «Метаданные», «Комментарий», «Сеанс», «Компьютер».
Чтобы проверить, какие уровни база сейчас пишет, используйте ПолучитьИспользованиеЖурналаРегистрации(). Включить запись всех уровней из кода можно через УстановитьИспользованиеЖурналаРегистрации — но это меняет настройку для всей базы, делайте так только по согласованию с администратором.
Практичный приём — регламентное задание раз в час читает ошибки своих событий за прошедший час и шлёт письмо ответственному. Так о сбое обмена узнают не утром, а через час.
Почему запись не появилась: разбор ошибок
Администрирование → Настройка журнала регистрации: возможно, выбран режим записи только ошибок или журнал выключен. Уровни «Информация» и «Примечание» в этом случае не пишутся.&НаКлиенте в тонком клиенте. Перенесите вызов в процедуру &НаСервере или &НаСервереБезКонтекста.Метаданные() или Ссылка.Метаданные(), в «Данные» передавайте ссылку.Транзакционная, а транзакция откатилась. Для ошибок оставляйте режим по умолчанию Независимая.ПередЗаписью нового объекта — ссылки ещё нет. Перенесите вызов в ПриЗаписи или ОбработкаПроведения.Частые вопросы
Можно ли записать в журнал регистрации из внешней обработки?
Нужно ли снимать конфигурацию с поддержки, чтобы добавить запись в журнал?
ЗаписьЖурналаРегистрации, не трогая основную конфигурацию.Как записать в журнал из регламентного задания с понятным пользователем?
Попадают ли мои записи в выгрузку .dt?
.dt не входит. Для переноса журнала копируют каталог 1Cv8Log или выгружают журнал в XML.