Skip to content

opentelemetry-v8-logs ​

Приложение читает технологический журнал (ТЖ) и журнал регистрации (ЖР) 1С:Предприятия и передает их в OpenTelemetry по OTLP. Получатель - любой бэкенд с поддержкой OTLP, например стек LGTM: Loki (логи), Grafana, Tempo (трассы), Mimir или Prometheus (метрики).

Как это работает ​

каталоги ТЖ и ЖР ──► читатели ──► экспортеры ──► OpenTelemetry SDK ──► OTLP ──► LGTM
        ▲                                               │
        └──── позиции чтения (autumn-data) ◄── фиксация после успешной отправки
  1. Читатель находит файлы журнала и дочитывает каждый с сохраненной байтовой позиции. Читаются только завершенные события и записи: недописанный хвост файла будет прочитан в следующем проходе. Файлы технологического журнала всех процессов читаются по порядку часа из имени файла: при первом запуске и догоне после простоя события уходят примерно в порядке времени, иначе Loki отклонил бы записи, которые больше чем на час старше уже принятых в тот же поток логов (too_far_behind). В лог приложения попадают начало чтения файла (первые новые данные с запуска приложения), полное прочтение файла, в который больше не пишут (с числом записей за этот запуск), и усечение файла, но не каждый проход по дописываемому файлу. Файлы, прочитанные до конца в прошлые запуски, не логируются.
  2. Экспортер превращает событие в запись лога, метрики и спаны.
  3. Записи передаются пакетами, после каждого пакета буферы SDK сбрасываются.
  4. Позиции сохраняются в базу только после успешной отправки. При сбое отправки они откатываются, и данные будут прочитаны повторно (доставка «хотя бы один раз»). Логи и спаны при повторе могут продублироваться; метрики записываются только после успешного сброса.

Что поддерживается ​

ИсточникФорматы
Технологический журналтекст (8.3 и 8.2), JSON (8.3.25+, format="json"); файлы <процесс>_<PID>/ГГММДДЧЧ.log и <процесс>_<PID>_ГГММДДЧЧ.log
Журнал регистрациистарый формат: словарь 1Cv8.lgf и файлы записей *.lgp

Журнал регистрации в формате SQLite (1Cv8.lgd) пока не поддерживается: для его чтения переключите базу на старый формат журнала.

Установка и запуск ​

sh
opm install opentelemetry-v8-logs
opentelemetry-v8-logs              # постоянная работа (то же, что run)
opentelemetry-v8-logs run --once   # один проход, например из планировщика
opentelemetry-v8-logs --help

Приложение запускается на сервере 1С (или там, где доступны каталоги журналов) и берет настройки из autumn-properties.json текущего каталога, см. настройку. Однократный проход можно включить и переменной окружения OTEL_V8_LOGS_ONCE=true.

Демонстрация ​

В каталоге demo репозитория:

  • docker-compose.yml - стек LGTM в одном контейнере (grafana/otel-lgtm);
  • loki-config.yaml - конфигурация Loki, в которой база (v8.infobase.name) - индексируемая метка;
  • tempo-config.yaml - конфигурация Tempo, в которой спаны накопленных журналов находятся поиском по своему времени, см. состав телеметрии;
  • autumn-properties.json - пример настроек приложения;
  • logcfg.xml - пример настройки технологического журнала с событиями для трасс.
sh
docker compose -f demo/docker-compose.yml up -d
cp demo/autumn-properties.json .   # укажите свои каталоги журналов
opentelemetry-v8-logs

Grafana: http://localhost:3000.

Производительность ​

Протокол http/protobuf SDK для OneScript сейчас кодирует данные заметно медленнее, чем http/json: на 1000 записей журнала сброс занимает около 6.5 с против 0.25 с. Рекомендуемый протокол - http/json. На этом протоколе приложение передает порядка 600 записей журнала регистрации в секунду, основное время уходит на создание записей в SDK.


Настройка ​

Настройки читаются из autumn-properties.json в текущем каталоге (или в каталоге профиля пользователя). Секция otel - настройки OpenTelemetry SDK и самого приложения (otel.v8-logs), секция data - база для позиций чтения, секция logos - логи коллектора.

Телеметрия коллектора и данные журналов отправляются под разными service.name:

  • собственные логи и метрики коллектора - под otel.service.name, с атрибутами хоста и процесса коллектора;
  • данные журналов - под otel.v8-logs.service.name (или service-name источника), с атрибутами из otel.v8-logs.resource.attributes и без атрибутов процесса коллектора.
json
{
  "otel": {
    "enabled": true,
    "service": { "name": "opentelemetry-v8-logs" },
    "entity": { "enabled": false },
    "exporter": { "otlp": { "endpoint": "http://localhost:4318", "protocol": "http/json" } },
    "traces": { "exporter": "otlp" },
    "metrics": { "exporter": "otlp" },
    "logs": { "exporter": "otlp" },
    "v8-logs": {
      "service": { "name": "1c-cluster" },
      "resource": { "attributes": "deployment.environment.name=prod" },
      "timezone": "Europe/Moscow",
      "techlog": [
        { "path": "/var/log/1c/techlog" }
      ],
      "eventlog": [
        { "path": "/home/usr1cv8/.1cv8/1C/1cv8/reg_1541/<GUID базы>/1Cv8Log", "infobase": "erp", "service-name": "erp" }
      ]
    }
  },
  "logos": {
    "logger": { "rootLogger": { "level": "INFO", "appenders": ["otel", "console"] } },
    "appender": {
      "otel": { "type": "ОтелАппендерLogos", "level": "INFO" },
      "console": { "type": "ВыводЛогаВКонсоль", "level": "INFO" }
    }
  },
  "data": {
    "ИсточникиДанных": {
      "ТипКоннектора": "КоннекторSQLite",
      "СтрокаСоединения": "Data Source=opentelemetry-v8-logs.db"
    }
  }
}

otel.enabled нужен только для отправки собственных логов коллектора через ОтелАппендерLogos (autumn-opentelemetry). Вместе с ним по умолчанию включается инструментирование autumn-data, и каждый запрос к базе позиций стал бы спаном - поэтому в примере otel.entity.enabled выключен.

otel.v8-logs ​

ПараметрПо умолчаниюОписание
service.name1cservice.name данных журналов. Должен отличаться от otel.service.name коллектора.
resource.attributes-Атрибуты ресурса данных журналов в формате OTEL_RESOURCE_ATTRIBUTES: ключ=значение через запятую. otel.resource.attributes к данным не применяется.
techlog-Массив каталогов технологического журнала (location в logcfg.xml). Элемент: path, необязательные service-name, infobase (база для событий с пустым p:processName, например у файловой базы), timezone, start-from-end, traces-mode.
eventlog-Массив каталогов журнала регистрации (1Cv8Log). Элемент: path, infobase (имя базы; по умолчанию имя родительского каталога, то есть GUID базы), необязательные service-name, timezone, start-from-end.
timezoneчасовой пояс машиныЧасовой пояс серверов 1С. Журналы пишутся в местном времени сервера, в OpenTelemetry время передается в UTC. Принимаются имена IANA (Europe/Moscow), Windows и GMT+03:00.
start-from-endfalseПри первом запуске пропустить уже накопленные данные. Файлы, появившиеся позже, читаются с начала.
languageruЯзык представлений событий журнала регистрации в теле записи и атрибуте v8.eventlog.event.presentation: ru или en. При другом значении используется идентификатор события.
interval5Пауза между проходами без новых данных, секунд. Пока журналы отстают, проходы идут без пауз.
batch-size1000Сколько записей передавать в SDK между сбросами буферов. Не больше размера очереди пакетного процессора (otel.blrp.max.queue.size, по умолчанию 2048).
traces.enabledtrueСобирать трассы вызовов из технологического журнала.
traces.root-eventsCALLСобытия - корни трасс. Корневое событие закрывает трассу потока, поэтому событие, которое в вашем журнале бывает вложено в CALL того же потока, корнем делать нельзя: оно разорвет трассу вызова.
traces.modeautoРежим сборки трасс: streaming - спаны отправляются сразу, buffered - события копятся до верхнеуровневого (для файловой базы), auto - накопление для процессов 1cv8 и 1cv8c, потоковый для остальных. См. состав телеметрии.

OpenTelemetry SDK ​

Все параметры SDK - в его документации. Основные:

ПараметрОписание
otel.service.nameИмя сервиса самого коллектора.
otel.resource.attributesДополнительные атрибуты ресурса коллектора.
otel.metric.export.intervalИнтервал экспорта метрик, мс; действует и для метрик данных. Для метрик данных используются настройки транспорта OTLP коллектора, а временная агрегация всегда кумулятивная.
otel.exporter.otlp.endpointАдрес приемника OTLP.
otel.exporter.otlp.protocolПротокол: рекомендуется http/json, см. раздел о производительности.

Параметры можно задавать и переменными окружения (OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT...).

Позиции чтения ​

Позиции хранятся в таблице ПозицииЧтения источника данных из секции data (autumn-data): подойдет файл SQLite или любой другой коннектор entity. Ключ позиции - полный путь к файлу журнала. Позиции удаленных файлов удаляются автоматически. Чтобы перечитать журналы заново, удалите базу позиций.

Настройка технологического журнала ​

Для трасс в ТЖ нужны события вызовов (CALL) и вложенные события (DBMSSQL, DBPOSTGRS, SDBL, TLOCK, EXCP...) со свойством OSThread, а для имен корневых вызовов - Context (в файловой базе код пользователя пишется без CALL, трассы строятся накоплением, см. состав телеметрии). Пример - demo/logcfg.xml.


Состав телеметрии ​

Время журналов 1С - местное время сервера, в OpenTelemetry оно передается в UTC по часовому поясу из настройки otel.v8-logs.timezone.

Ресурс ​

Данные журналов отправляются с отдельным ресурсом, не с ресурсом коллектора:

Атрибут ресурсаЗначение
service.nameotel.v8-logs.service.name или service-name источника
v8.infobase.nameинформационная база: для журнала регистрации - infobase источника; для технологического журнала - свойство события p:processName, а если оно пустое - infobase источника
атрибуты из otel.v8-logs.resource.attributesкак заданы

Loki делает индексируемыми метками только атрибуты ресурса из своего списка (service.name и другие, см. документацию Loki), остальные сохраняются как структурированные метаданные. Чтобы база стала меткой v8_infobase_name, добавьте v8.infobase.name в limits_config.otlp_config Loki - пример в demo/loki-config.yaml.

В технологическом журнале p:processName бывает и не базой: в журнале файловой базы на macOS (8.3.27) у событий отладчика оно равно RemoteDebugger и DebugControlCenter, и эти значения тоже попадают в v8.infobase.name.

Технологический журнал ​

Логи ​

Каждое событие - запись лога (область инструментирования opentelemetry-v8-logs.techlog).

ПолеЗначение
Времявремя окончания события
Телоисходный текст события
Серьезностьиз свойства события level: TRACE, DEBUG, INFO, WARNING - WARN, ERROR; без него или при другом значении - по имени события: ERROR для EXCP; WARN для ATTN, TDEADLOCK, TTIMEOUT; иначе INFO
v8.techlog.event.nameимя события (CALL, DBMSSQL...)
v8.techlog.durationдлительность, мкс
v8.techlog.depthуровень вложенности
v8.techlog.<свойство>свойства события как есть: v8.techlog.Usr, v8.techlog.t:clientID, v8.techlog.Sql...; повторяющиеся свойства - массивом
process.executable.name, process.pidпроцесс и PID из имени каталога или файла
log.file.pathпуть к файлу журнала

Метрики ​

МетрикаТипАтрибуты
v8.techlog.event.duration, сгистограммаv8.techlog.event.name, process.executable.name, v8.infobase.name

Трассы ​

Трасса - верхнеуровневое событие потока выполнения (процесс, OSThread и t:clientID, если он есть) со всеми событиями, вложенными в него по уровню и времени. Платформа пишет событие по окончании, поэтому вложенные события появляются в журнале раньше родителя. Сборщик исходит из того, что события одного уровня в одном потоке по времени не пересекаются, и тогда охват интервала [окончание - длительность, окончание] событием меньшего уровня означает, что событие - предок. В журналах автономного сервера ibsrv и файловой базы (macOS, 8.3.27) это выполняется.

Трассы собираются в одном из двух режимов (настройка otel.v8-logs.traces.mode).

Потоковый (streaming). Спан каждого события отправляется сразу при чтении. Корень трассы - событие вызова (CALL, настройка otel.v8-logs.traces.root-events) или событие уровня 0: ниже уровня 0 стека нет, и предка у такого события быть не может. Идентификатор родителя выдается заранее: событие уровня d ссылается на «слот» уровня d-1, а слот копит объединение интервалов своих потомков. Событие уровня d-1 занимает слот, только если его интервал охватывает всех потомков слота. Если уровень не пишется в журнал или следующее событие этого уровня не охватывает потомков, слот отправляется синтетическим спаном UNLOGGED с атрибутом v8.techlog.synthetic. Корень закрывает трассу потока; ожидавшие события, которые он не охватывает, закрываются отдельной трассой с синтетическим корнем. Трасса, в потоке которой больше часа не было событий, закрывается синтетическим корнем.

В журнале ibsrv код пользователя - например, запись документа - выполняется внутри CALL,0 (ib::worker::IInfoBaseWorkingContextCall.execute) того же потока, без t:clientID у вызова и его событий.

Накопление (buffered). В журнале файловой базы код пользователя выполняется в процессе клиента (1cv8c, 1cv8) без событий CALL, и верхнеуровневое событие становится известно, только когда записан его предок или стало ясно, что предка не будет. События потока копятся в памяти деревьями и отправляются: когда в потоке записано событие уровня 0 (охватить накопленные события после него не может ничто), после минуты без событий потока (по времени журнала, а после прохода, дочитавшего журналы, - по часам), при накоплении 10000 событий потока и при завершении работы. Каждое верхнеуровневое событие - например, SDBL Func=HoldConnection с транзакцией внутри или отдельный запрос - становится отдельной трассой. Записи лога отправляются сразу и со спаном не связаны: спан и его запись лога находятся по log.file.path и времени.

Режим по умолчанию auto: накопление для процессов 1cv8 и 1cv8c, потоковый для остальных. Так выбрано по наблюдению: клиент, подключенный к серверу, событий SDBL не пишет, а клиент файловой базы пишет. Режим можно задать явно для всех журналов или для источника (traces-mode).

Имена спанов ​

Имя спана состоит из имени события, операции и места вызова из последней непустой строки собственного Context. Кадр Модуль : строка : выражение сокращается до Модуль:строка, кадр без модуля — до <dynamic>:строка. Другой формат контекста сохраняется как текст. Контекст дочернего события не заменяет имя родительского вызова.

СобытиеИмяПример
CALL фонового заданияModule.Method, если Func=Background job и оба поля заполненыCALL Jobs.Run
CALL с собственным Contextместо вызоваCALL ОбщийМодуль.Обмен.Модуль:42
CALL, SCALLинтерфейс и метод (IName, MName или Method), иначе FuncSCALL ILogMngrData.writeLogEntryData, CALL Dynamic list search
CALL, SCALL без метода и контекстаFunc и, если доступны, Form.FormItemCALL Dynamic list search · Документ.Заказ.Форма.ФормаДокумента.Список
SDBLFunc, иначе вид запроса и таблицаSDBL HoldConnection, SDBL UPDATE Document54
DBMSSQL, DBPOSTGRS, DBORACLE, DB2вид запроса и таблица; для ODBC {call ...} — EXEC и имя процедуры; без запроса — FuncDBMSSQL INSERT _Document54, DBMSSQL EXEC sp_executesql
TLOCKпространства блокировок (Regions)TLOCK Document54.REFLOCK
EXCPтип исключения и место вызова; без Context — первый кадр {Модуль(строка)} из DescrEXCP RuntimeException · ОбщийМодуль.Test.Модуль:42
синтетическийUNLOGGED

У событий, кроме CALL с собственным контекстом и фоновых заданий, место вызова добавляется после операции через ·: DBMSSQL SELECT _Document54 · ОбщийМодуль.Test.Модуль:42. Операция ограничена 100 символами, модуль — 120 (сохраняется конец имени и номер строки), контекст неизвестного формата — 160. Исходные свойства остаются в атрибутах события. Значения SQL-параметров в имя из запроса не включаются.

Правила именования одинаковы для streaming, buffered и auto. В потоковом режиме спан отправляется сразу: отдельное событие Context, записанное после вызова, не меняет его имя. Для этих правил нужен Context в свойствах самого события.

СобытиеСпан
CALLвид SERVER
DBMSSQL, DBPOSTGRS, DBORACLE, DB2вид CLIENT, db.system.name
EXCPвид INTERNAL, статус ERROR, событие exception (exception.type, exception.message)
остальныевид INTERNAL

Атрибуты спанов - те же, что у записей лога. В потоковом режиме каждая запись лога события содержит trace_id и span_id спана этого события: из Loki можно перейти в трассу в Tempo и обратно.

Состояние трасс хранится в памяти. Если приложение перезапустится посреди вызова, в потоковом режиме вложенные события, отправленные до перезапуска, сошлются на родителя, который не придет; в режиме накопления при аварийном завершении накопленные спаны теряются (при штатном - отправляются).

Для трасс в журнал нужно писать свойство OSThread, а для места вызова в именах спанов — Context.

Время спана - время события в журнале. Tempo записывает в метаданные блока время поступления данных, если время спанов отстоит от него больше, чем на ingestion_time_range_slack (по умолчанию 2 минуты), а поиск по интервалу времени выбирает блоки по метаданным. Поэтому спаны, выгруженные при первом запуске по накопленным журналам или при догоне после простоя, с настройками Tempo по умолчанию поиском по своему времени не находятся; по идентификатору трассы, в том числе из записи лога в Loki, они открываются. В demo/tempo-config.yaml запас увеличен до срока хранения блоков (336h) в разделах storage.trace.wal, live_store.wal и block_builder.wal (Tempo 3).

Журнал регистрации ​

Логи ​

Каждая запись - запись лога (область инструментирования opentelemetry-v8-logs.eventlog). Пустые поля не передаются.

ПолеЗначение
Времявремя записи
Телострока как в просмотре журнала, части через |: представление события (v8.eventlog.event.presentation); у событий с объектом метаданных или данными - объект, представление данных (без него - данные) и пользователь, у остальных - приложение, пользователь и session=<номер>, значения как в журнале. Пустые части пропускаются, комментарий - с новой строки. Например, Данные. Проведение | Document.Document | Document 000000001 dated 10/20/2026 12:56:10 PM, Сеанс. Начало | 1CV8C | session=2
СерьезностьE - ERROR, W - WARN, I - INFO, N (примечание) - DEBUG
v8.eventlog.eventидентификатор события (_$Session$_.Start, _$Data$_.Post...)
v8.eventlog.event.presentationпредставление события, как в просмотре журнала, на языке из настройки otel.v8-logs.language: «Данные. Проведение» или «Data. Posting». У событий без представления (события пользователя, события, которых нет в платформе 8.3.27) - идентификатор события, поэтому атрибут заполнен у всех записей
user.name, user.idимя и идентификатор пользователя
v8.eventlog.computer, v8.eventlog.applicationкомпьютер и приложение
v8.eventlog.connection, v8.eventlog.sessionсоединение и сеанс
v8.eventlog.transaction.statuscommitted (код C), rolled_back (код R): в журналах с этими кодами записаны события _$Transaction$_.Commit и Rollback
v8.eventlog.transaction.status_codeкод статуса транзакции как есть: C, R, U (у изменений данных внутри транзакции; значение не расшифровывается)
v8.eventlog.transaction.idномер транзакции
v8.eventlog.metadata, v8.eventlog.metadata.uuidобъект метаданных
v8.eventlog.dataСтруктурированный OTLP-атрибут с полями известной формы Data; для неизвестной формы — строка JSON с исходным деревом, для скаляра — текстовое значение. Подробнее о разборе Data.
v8.eventlog.data.presentationпредставление данных
v8.eventlog.server, v8.eventlog.port, v8.eventlog.sync_portрабочий сервер и порты
v8.eventlog.data_separation.<разделитель>значения разделителей сеанса
log.file.pathпуть к файлу журнала

Метрики ​

МетрикаТипАтрибуты
v8.eventlog.recordsсчетчикv8.eventlog.event, v8.eventlog.severity, v8.infobase.name, v8.eventlog.application

Содержимое Data журнала регистрации ​

Содержимое поля Data передается в атрибуте v8.eventlog.data: для известных полей — структурированный объект OTLP (kvlistValue), для неизвестной формы — компактная строка JSON, для скаляров — прежнее текстовое значение. Пустой объект также сохраняется строкой JSON, чтобы приемник не потерял его при разворачивании. Известные поля не дублируются отдельной JSON-строкой. v8.eventlog.data.presentation, текст тела лога, ресурсы и метрики сохраняются. Включать настройку не требуется.

Правила разбора разработаны в форке OneSTools.EventLog и проверены на искусственных примерах, сопоставленных с выгрузкой платформы 8.3.27.2325. Имена из синтакс-помощника используются после подтверждения реального расположения полей: порядок перечисления в справке не совпадает с порядком значений LGP. Наличие события в таблице ниже не означает распознавание всех его вариантов. Проверяются код события, маска, количество и типы элементов. Именованные пары распознаются в русском и английском вариантах: Имя / Name, Данные / Data, Ссылка / Reference. На тестовой платформе 8.3.27.2325 язык этих ключей определялся вариантом встроенного языка конфигурации (Russian / English); переключение интерфейса и региональных настроек базы их не меняло.

События описаны декларативным OneScript-кодом в ПоляДанныхСобытийЖурналаРегистрации. Один блок объединяет поля, их типы, формы входной записи и преобразования JSON. Декодер читает готовые описания без ветвлений по кодам событий и именам полей. ИменаПолей, Биты, Способ выводятся из поддерживаемых форм; нераспознаваемые варианты в реестр не включаются. Для совместимости JSON использует AuthenticationMethod и Vendor у ConfigUpdate, как в проверенной выгрузке 8.3.27.

Добавление события ​

Пример битовой формы аутентификации:

bsl
Формы = Новый КонструкторыДанныхЖурналаРегистрации;

Реестр.Событие("_$Session$_.Authentication")
    .Аналоги("_$Session$_.AuthenticationError")
    .Поле("Name").ТипПоля("Строка").Бит(1)
    .Поле("CurrentOSUser").ТипПоля("Строка").Бит(2)
    .Поле("AuthenticationMethod").ТипПоля("Число").Бит(9)
    .Поле("OSUser").ТипПоля("Строка").Бит(0)
    .Форма(Формы.ПоМаске("P", "518"))
    .Форма(Формы.ПоМаске("P", "514"))
    .Форма(Формы.ПоМаске("P", "513"))
    .Зарегистрировать();

Поля битовой формы читаются по возрастанию номеров битов. Распознаются только перечисленные маски; новая комбинация сохраняется исходным деревом.

ТипПоля(...) принимает Строка, Число, Булево, Дата, Ссылка, МассивСсылок, МассивСтрок, Незаданное, Таблица. Имя Тип() занято встроенной функцией OneScript. Способ вывода настраивается отдельно:

bsl
.Поле("Roles").ТипПоля("МассивСсылок").Пропустить()
.Поле("Roles").ТипПоля("МассивСсылок").Как("UserRoles")
.Поле("Roles").ТипПоля("МассивСсылок").Как("RolesCount", Агрегаты.Количество())
.Поле("Roles").ТипПоля("МассивСсылок").Как("UniqueRolesCount", Агрегаты.КоличествоУникальных())

Это четыре альтернативы: исключить из JSON, переименовать с сохранением массива, заменить массив количеством всех или только различных элементов. Агрегаты — экземпляр КонструкторыДанныхЖурналаРегистрации. Пропущенное поле все равно читается и проверяется. .Значение("0", "false").Значение("3", "true") задает карту допустимых значений; неизвестный код приводит к сохранению исходного дерева.

КоличествоУникальных() применяется к массивам строк и ссылок. Строки различаются регистром и пробелами; пустая строка тоже считается значением. Ссылки сравниваются по паре UUID типа и объекта, без учета регистра UUID. Для пустого массива результат "0"; количество передается строкой, как и у Количество(). Счетчик массива и все элементы проверяются до возврата результата. Поврежденное значение сохраняется исходным деревом. Множество уникальных ключей создается только для этого агрегата; обычный подсчет обходится без хранения элементов.

Позиционные формы задаются через Формы.Позиционная("P", "65534"). Второй аргумент — необязательный точный маркер, который не обязательно является битовой маской. Состав и порядок задаются одним из способов:

  • .ВсеПоля() — порядок объявления полей события.
  • .ВсеПоляКроме("DefaultInterface") — поле физически отсутствует во входе; позиции следующих полей сдвигаются. Для нескольких имен допустим CSV или массив.
  • .Поля("Name,OSUser") — явный порядок; также принимает массив имен.
  • .Поле("Name").Поле("OSUser") — тот же явный порядок цепочкой вызовов.

Для вложенной записи используется Формы.Структура("P") с точным .Размер(...), условиями .РазмерУзла(...), .Литерал(...) и .ПолеПоПути(...). Путь "1.1" означает второй элемент второго списка тела; индексы начинаются с нуля. При регистрации проверяются типы, ссылки на поля, биты, повторные коды событий и выходные ключи JSON. Ошибочное описание не добавляется в реестр.

Подтвержденные формы ​

События (суффиксы после системной группы)Содержимое
User.AuthenticationLock, AuthenticationUnlock, AuthenticationUnlockError; Session.PasswordRequirementsViolationOnAuthenticationName, включая пустую строку
Session.Authentication, AuthenticationErrorформы 513, 514, 518: OSUser / Name, CurrentOSUser, AuthenticationMethod
User.New, Update, NewError, UpdateErrorформы 65535 и 65534: свойства пользователя, ссылки на язык/интерфейс, RolesCount, настройки второго фактора и политики паролей
User.Delete, DeleteError; Session.ConfigExtensionApplyErrorName
InfoBase.UserPasswordPolicyNew, UserPasswordPolicyNewError, UserPasswordPolicyUpdateформа 255: девять свойств политики, включая проверку компрометации и действие при нарушении требований
InfoBase.UserPasswordPolicyDelete, UserPasswordPolicyDeleteErrorName
InfoBase.ParametersUpdate, ParametersUpdateErrorподтвержденные маски параметров базы: пароли, блокировка аутентификации, ожидание блокировки и завершение неактивных сеансов
InfoBase.AdditionalAuthenticationSettingsUpdate45 отдельных масок параметров и форма 2564; методы восстановления и отправки кодов, SMTP, интервалы и проверки компрометации
InfoBase.ConfigUpdate, DBConfigUpdate, ConfigUpdateError, DBConfigUpdateErrorVendor, Version
InfoBase.ExclusiveModeChange, ExclusiveModeChangeErrorExclusiveMode
Access.Access, AccessDeniedтаблица Data, либо Right, либо Action и незаданные Data
InfoBase.SecondAuthenticationFactorTemplateNew, SecondAuthenticationFactorTemplateUpdate, SecondAuthenticationFactorTemplateDeleteName
InfoBase.EventLogSettingsUpdate, EventLogSettingsUpdateErrorLevels либо EventName, EventIsLogged
InfoBase.EventLogReduce, EventLogReduceErrorDate
InfoBase.RegionalSettingsChange11 свойств региональных установок
Session.ExternalDataProcessorConnect, ExternalDataProcessorConnectError, ExternalReportConnect, ExternalReportConnectErrorпуть, имя, безопасный режим, профиль безопасности, защита от опасных действий и язык
Session.AddInAttach, AddInAttachErrorName, Location, незаданные Type, AttachmentType
InfoBase.SessionLockChange, SessionLockChangeErrorUse, Begin, End, Message, KeyCode, Parameter
InfoBase.ConfigExtensionUpdate, DBConfigExtensionInsert, DBConfigExtensionInsertError, DBConfigExtensionDelete, DBConfigExtensionDeleteError, DBConfigExtensionUpdate, DBConfigExtensionUpdateError15 свойств расширения: имя, версия, поставщик, UUID, хэш, синоним, режимы, профиль, назначение, область и роли
Data.DataHistorySettingsUpdate, PredefinedDataInitialization, UpdatePredefinedData; InfoBase.PredefinedDataUpdateтаблица Data в подтвержденной именованной форме

Всего специальные правила охватывают 56 кодов событий. Для остальных возможен общий разбор именованных пар; неподтвержденные формы сохраняются целиком.

Представление значений ​

Числа и булевы значения в разобранных данных представлены строками ("0", "false"), как в исходном декодере. Это сохраняет точность длинных чисел и единый контракт. Даты — локальные значения 1С yyyy-MM-ddTHH:mm:ss, без добавления часового пояса. Пустая дата сохраняется как 0001-01-01T00:00:00. Пустые строки не удаляются. null означает незаданное поле подтвержденной формы; в общем разборе U сохраняется явно как {"$type":"U"}.

Например, блокировка аутентификации: {"Name":"FixtureUser"}.

Для подтвержденных форм User.New, Update, NewError, UpdateError свойства пользователя находятся прямо в корне объекта, без $format, values и nodes. Состав ролей пользователя намеренно не экспортируется; вместо списка UUID сохраняется RolesCount. Точный состав ролей из телеметрии восстановить нельзя. DefaultRoles расширения остается отдельным полем.

Для остальных позиционных форм используется конверт 1c-positional-data-v1: layout, values, unnamedFields, nodes. Для общих именованных пар — 1c-named-data-v1: values, nodes. Ссылки сохраняют идентификаторы, без попытки прочитать объект из информационной базы. Для неизвестных форм расположение ролей не угадывается: сохраняется исходное дерево. Если маска, число или типы полей неизвестны, возвращается {"$format":"1c-brackets-v1","nodes":[...]}. nodes сохраняет дерево и исходный текст листьев, включая удвоенные кавычки. Переход на новую платформу не приводит к угадыванию полей.

Поиск в Loki ​

При штатном приеме OTLP Loki разворачивает поля объекта в structured metadata: v8.eventlog.data.Name становится v8_eventlog_data_Name. Эти поля не добавляются в индексные метки и доступны без разбора JSON в запросе. Например:

logql
{service_name="erp"} | v8_eventlog_data_Name="FixtureUser"

Loki хранит значения metadata строками: незаданные значения (null) в результатах запросов не отображаются, а массив передается JSON-строкой. Сам OTLP-атрибут сохраняет вложенные объекты, массивы, пустые строки и незаданные значения. Другие приемники могут представлять их иначе. При нормализации имен точки и другие неподдерживаемые символы заменяются на _.

Неизвестные формы по-прежнему находятся в v8_eventlog_data как JSON-строка.

Подставьте service.name своего источника и период журнала. Поля Data следует оставлять атрибутами логов, не добавляя их в индексные метки Loki или в разрезы метрик.