IE2017

Формат файлов журнала регистрации 1С 8.1/8.2 - ELF/LOG/LGF/LGP

Администрирование - Журнал регистрации

В статье детально описан формат текстовых файлов журнала регистрации 1С 8.1 - ELF/LOG и 1С 8.2 - LGF/LGP

Заинтересовал меня формат файлов журнала регистрации, но поиск в интернете не дал никаких результатов. Пришлось изучать его самому. Так родилась обработка  //infostart.ru/public/181455/ - Анализ и редактирование файлов журнала регистрации 8.1/8.2 - ELF/LOG/LGF/LGP. Как и обещал, постарался написать полноценную статью о формате файлов журнала регистрации 1С 8.

В 1С 8 журнал регистрации хранится в текстовых файлах, которые находятся в подкаталоге 1Cv8Log. Для клиент-серверной ищем где-то в "C:\Program Files\1cv82\srvinfo\reg_1541\\1Cv8Log\".

Обычно журнал регистрации 1С 8 состоит из одного файла описаний (ELF в 8.1 / LGF в 8.2) и одного или нескольких файлов данных (LOG  в 8.1 / LGP в 8.2). Существуют еще так называемые архивы журнала регистрации – в этом случае описания и данные находятся в одном файле последовательно, сначала описания, затем данные, при этом расширение как у файла данных.

В первой строке файла журнала регистрации пишется маркер
"1CV8LOG_" для 8.1 и "1CV8LOG(ver 2.0)" для 8.2.

Во второй строке пишется GUID.

Для файла данных журнала регистрации пишется еще дополнительно третья пустая строка.

Дальше идут непосредственно данные, которые заключены в фигурные скобки "{}" и отделяются друг от друга запятой.

При парсинге журнала регистрации сталкиваемся с проблемой отделения друг от друга записей – ведь они имеют переменную длину и могут быть разбиты на разное число строк, которое получается из-за следующих правил, добавляющих дополнительные символы новой строки (Символы.ПС):

1) Открывающей фигурной скобке "{ "в файле всегда предшествует символ новой строки;

2) Закрывающие фигурные скобки "}" не могут идти подряд – они всегда разделены символом новой строки;

3) Символ новой строки может встретиться внутри кавычек.

Таким образом отделить запись можно по следующим критериям

1) Первый символ – открывающая фигурная скобка "{";

2) Число открывающих фигурных скобок "{" равно числу закрывающих фигурных скобок "}";

3) Последний символ – закрывающая фигурная скобка "}";

4) Так же у правильной записи всегда будет четное число кавычек.

 

Структура записей файла описаний 8.1 сильно отличаются от 8.2.

При анализе файла описаний 8.1 по приведенным выше правилам получим всего одну запись, которая будет состоять из элемента "Legend" и вложенных записей. Структура вложенных записей одинакова – это заголовок и вложенная запись. Заголовок может принимать следующие значения "Users" – GUIDы пользователей, "UserNames" – имена пользователей, "Hosts" – компьютеры,  "Apps" – приложения, "Events" – события, "MDID" - GUIDы метаданных, "MDCodes" – имена метаданных, "SrvHosts" – серверы, "MainPorts" – основные порты, "SyncPorts" – вспомогательные порты. Вложенные записи состоят по сути из массивов. Первый элемент – размер массива, дальше идут непосредственно значения. Разделитель – запятая.

 

При анализе файла описаний 8.2 увидим другую картину. Файл содержит много записей размером от обычно трех элементов до четырех, в случае если надо указать GUID – для пользователей и метаданных.

Формат записи прост – первый элемент код массива, второй – значение, третий – номер в массиве. В случае четырех записей, между первым и вторым элементом появляется GUID.

Коды массивов были обнаружены следующие:

1 – пользователи;

2 – компьютеры;

3 – приложения;

4 – события;

5 – метаданные;

6 – серверы;

7 – основные порты;

8 – вспомогательные порты.

Так же встречаются пока неопознанные коды 11, 12 и 13

 

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

 

Структура записей файлов данных 8.1 отличается от 8.2 по сути только количеством элементов. В 8.1 запись состоит жестко из 16 элементов, а в 8.2 число элементов переменно и может быть от 19 штук и до в принципе любого количества.

Далее приведу значения элементов в записи:

1) Дата и время в формате "yyyyMMddHHmmss", легко превращается в дату функцией Дата();

2) Статус транзакции – может принимать четыре значения "N" – "Отсутствует", "U" – "Зафиксирована", "R" – "Не завершена" и "C" – "Отменена";

3) Транзакция в формате записи из двух элементов преобразованных в шестнадцатеричное число – первый – число секунд с 01.01.0001 00:00:00 умноженное на 10000, второй – номер транзакции;

4) Пользователь – указывается номер в массиве пользователей;

5) Компьютер – указывается номер в массиве компьютеров;

6) Приложение – указывается номер в массиве приложений;

7) Соединение – номер соединения;

8) Событие – указывается номер в массиве событий;

9) Важность – может принимать четыре значения – "I" – "Информация", "E" – "Ошибки",

"W" – "Предупреждения" и "N" – "Примечания";

10) Комментарий – любой текст в кавычках;

11) Метаданные – указывается номер в массиве метаданных;

12) Данные – самый хитрый элемент, содержащий вложенную запись;

13) Представление данных – текст в кавычках;

14) Сервер – указывается номер в массиве серверов;

15) Основной порт – указывается номер в массиве основных портов;

16) Вспомогательный порт – указывается номер в массиве вспомогательных портов;

17) Сеанс – номер сеанса;

18) Количество дополнительных метаданных, номера которых будут перечислены в следующих элементах записи. Именно 18-й элемент определяет длину записи, т.к. дальше будут следовать столько элементов сколько указано здесь + один последний, назначение которого пока не определено и обычно там "{0}". Возможно это просто маркер окончания записи. Так же есть идея что {0} похоже на пустой массив.

 

Теперь рассмотрим вложенную запись элемента 12 (Данные), который может принимать следующие значения:

1) {"U"} – Неопределено – можно преобразовать через ЗначениеИзСтрокиВнутр();

2) {"S","Строка"} – Строка – можно преобразовать через ЗначениеИзСтрокиВнутр();

3) {"R",id:GUID} – Ссылка c GUID, где метаданные с id. Для получения id метаданных пока нашел только немного извращенный способ – ЗначениеИзСтрокиВнутр(ТипМетаданных.ИмяМетаданных.ПустаяСсылка()) и парсить полученную строку.

4) {"P",{6,{"S","Строка1"},{"S","Строка2"}}}– что-то вроде массива но пока не понятно что значит 6 –  на ее месте пока встречал только 1, 2 и 6. Возможно это разные типы - массив, структура и т. п.

 

Таким образов, в целом формат журнала регистрации как 1С 8.1, так и 1С 8.2 разобран. Есть некоторые недопонимания, которые надеюсь со временем прояснятся, но даже они не мешают парсить файлы обработке - //infostart.ru/public/181455/ - Анализ и редактирование файлов журнала регистрации 8.1/8.2 - ELF/LOG/LGF/LGP

 

Позже появилась довольно интересная публикация - Периодическая загрузка событий из журналов регистрации в базу MS SQL Server, где автор парсит файлы журнала регистрации напрямую, причем он пишет, что разбирал формат журнала регистрации сам, задолго до текущей публикации, но к сожалению пока дополнительно найденной информацией по формату с сообществом не поделился.

См. также

Вознаграждение за ответ
Показать полностью
Комментарии
1. Ak A (frc) 10.04.13 10:18 Сейчас в теме
Вау, какие темы пошли!
Отлично!
2. Ирли Бёрд (EarlyBird) 1 10.04.13 10:21 Сейчас в теме
3. Петр Петров (jONES1979) 10.04.13 11:17 Сейчас в теме
"Это ж все что нажито непосильным трудом" - теперь разжевано и разобрано! :D
Плюсую. Обработку тоже скачал, пригодится
4. Александр Удалов (higs) 10.04.13 11:53 Сейчас в теме
И мне понравилось. Хотя пока не знаю, куда применить данные знания. Переводить разработки с 7-ки по парсингу журнала и отборов данных?
5. Антон Ширяев (Антон Ширяев) 403 10.04.13 13:45 Сейчас в теме
(4) higs,
Я как раз начал с обратного - сначала обработка с уже возможным некоторым применением, а затем уж описал формат по тому что получилось в обработке.

А применение знаний формата пока основное вижу только одно - если есть понимание формата, то можно лечить некоторые виды повреждений журнала регистрации 1С 8.

Так же на Инфостарте уже есть несколько разработок, которые что-то делают с журналом регистрации, возможно им пригодится перевод на прямое чтение файлов.
6. Ak A (frc) 11.04.13 00:50 Сейчас в теме
(5) Антон Ширяев,
если есть понимание формата, то можно лечить некоторые виды повреждений журнала регистрации 1С 8.

тогда ждем через неделю обработку "Как и где лечить поврежедния журнала".
С сопроводительной статьей "Повреждения журнала и причины этого".
Можно еще приложение - "Виды повреждений на примерах". ;)
7. Il Il (Il) 38 11.04.13 10:55 Сейчас в теме
8. Антон Ширяев (Антон Ширяев) 403 11.04.13 12:37 Сейчас в теме
(6) frc,
тогда ждем через неделю обработку "Как и где лечить поврежедния журнала".
С сопроводительной статьей "Повреждения журнала и причины этого".
Можно еще приложение - "Виды повреждений на примерах". ;)


Чтобы что-то лечить, нужно видеть больного. Что-то желающих делиться проблемными журналами пока нет, а в своих архивах пока не наткнулся на проблемы.

Часто возникает проблема "Недостаточно памяти" при чтение журнала, так тут и лечить собственно нечего, нужно прочистить журнал от ненужных событий (планируется в будущих версиях обработки) или переходить на хранение копий журнала для анализа в сторонней базе.
9. Сергей (Sergoninfostarru) 2 11.04.13 23:25 Сейчас в теме
Поставил "+" за детальность и объем проделанной работы.
А какой смысл считывать 1С-ом данные из журнала регистрации 1С ?
Я как-то могу понять, когда данные считываются внешним приложением, отличным от 1С.
В 1С есть свое представление журнала регистрации с возможностью отбора. Где можна
использовать полученные знания на практике ?
10. Сергей Белов (Unicorn31) 45 12.04.13 08:42 Сейчас в теме
Журнал регистрации можно использовать для анализа изменений в базе, и выгрузки этих данных в другую ис за определенный промежуток. Это альтернатива плану обмена, но более универсальная. Плюсанул за труды.
Sergoninfostarru; +1 Ответить
11. Антон Ширяев (Антон Ширяев) 403 15.04.13 16:08 Сейчас в теме
Выяснил еще пару подробностей про журнал регистрации 1С 8.2
1) Разбивать запись на дополнительный строки необязательно, т.е. файл будет вполне читаться платформой через Файл - Открыть даже если не соблюдать правила по поводу фигурных скобок и связанных с ними переводов строк
2) Пока по моим наблюдениям в последнем элементе записей файла данных всегда содержится "{0}". Возможно это маркер окончания записи.

Просьба к тем, кто обнаружит обратное сообщить об этом здесь.
12. DAnry (DAnry) 12 24.04.13 18:20 Сейчас в теме
13. Сергей Маслов (LexSeIch) 184 26.04.13 18:02 Сейчас в теме
Мир этому дому!
В очередной раз убеждаюсь, что в сообществе много людей, которые разобравшись в вопросе или проблеме, готовы поделиться своими результатами. Спасибо за ценную информацию.
14. Антон Ширяев (Антон Ширяев) 403 05.02.14 15:42 Сейчас в теме
После долгих попыток понять почему при делении файлов журнала регистрации транзакции помечаются как незавершенные пришел к выводу, что умозаключение
"3) Транзакция в формате записи из двух элементов преобразованных в шестнадцатеричное число – первый – число секунд с 01.01.0001 00:00:00 умноженное на 10000, второй – номер транзакции"
оказалось неверным. Второй параметр это не номер транзакции, а смещение в файле данных журнала регистрации по которому начинается первая запись по этой транзакции.
danila_inf; +1 Ответить 1
15. Виталий Барилко (Diversus) 2277 18.02.14 21:08 Сейчас в теме
(0) Плюс Вам, конечно, за работу, но статья больше носит характер "академической".
Типовой журнал это неудобная вещь, медленная и не информативная.
Я пошел другим путем и не стал опираться на типовой журнал а сделал свою подсистему
16. Алексей Соловьев (Silenser) 408 30.09.14 14:01 Сейчас в теме
Так случилось, что был утерян файл словаря. Решил схитрить и подсунуть 1С файл словаря от той же базы, но с выгрузкой за другую дату. Оказалось, что файл словаря был создан заново и порядок идентификаторов в нем другой, не то что по метаданным, но даже по событиям. <сарказм> Удивительно! </сарказм>
Сейчас думаю, что делать. Больше всего похоже на то, что восстановить словарь без непотребных трудозатрат не выйдет.
17. dima_gsv (dima_gsv) 8 30.10.14 17:03 Сейчас в теме
Не подскажите, почему в 8.2 в журнал регистрации не записываются блокировки по таймауту и взаимоблокировки, возникающие при записи / проведении документов. В 8.1 вроде бы они туда попадали. А в 8.2 сообщение пользователю выводится, но в журнал не записывается. "Попыток" нет.
18. Леонид Никулин (Никулин Леонид) 4 16.11.14 17:50 Сейчас в теме
Использовал. Работает. Спасибо!
19. Алексей Роза (DoctorRoza) 05.12.14 09:41 Сейчас в теме
Отмечусь, нужно детально изучить! :)
20. Рамиль Баширов (bashirov.rs) 14 14.01.15 13:44 Сейчас в теме
Спасибо. Информативно. У меня вопрос следующего характера - можете по подробнее описать что означают или в каких ситуациях возникают все из перечисленных статусов транзакции?
21. Олег Шалимов (CaSH_2004) 344 10.06.15 15:52 Сейчас в теме
Объясните а зачем нужен файл описаний если есть файл данных? Вроде вся информация находится в нем
22. Олег Шалимов (CaSH_2004) 344 11.06.15 01:20 Сейчас в теме
И кстати журналы в базах в которых пользователи сидят не читаются, думаю нужно было сделать чтение через VBScript - там вроде заблокированные на запись файлы читаются
23. Two World (Prometeus2011) 36 05.07.15 14:59 Сейчас в теме
Не заметил информации относительно того, как выбрать журнал регистрации нужной базы. В директории "C:\Program Files\1cv8\srvinfo\reg_1541" лежит куча ГУИДОВ и файл "1CV8Clst.lst". Вот в нем-то и хранятся сопоставления.
24. sai_ NT (sai_NT) 07.04.16 19:31 Сейчас в теме
(14) Антон Ширяев, благодарю за наводку: помогла инфа касательно смещения. Переписал свою обработку, основанную во многой на вашей, по перекодировке файла журнала данных и теперь транзакции с правильными статусами отображаются.
25. Дядя Федор (ufedor) 44 09.09.16 12:30 Сейчас в теме
id метаданных, скорее всего, это номер таблицы, который можно получить с помощью функции ПолучитьСтруктуруХраненияБазыДанных
26. Антон Володченко (Euroset1) 4 28.02.17 18:35 Сейчас в теме
Так же встречаются пока неопознанные коды 11, 12 и 13

Я сейчас работаю над переводом старой версии журнала на Sqlite (конвертация файлов) и вроде как докопался до 11,12 и 13 кодов. Они имеют чуть иную логику, нежели предыдущие. И их суть сводится к таблице ComputerToUserCodes на sqlite. А именно, связи компьютеров и пользователей, которые с них заходили. Причем 13й может идти несколько раз подряд. Вместо значения и индекса тут связь индекс-индекс.

Похоже, что 11й добавляется после пользователя и означает начало блока связки этого пользователя с компьютером. 12й после добавления компьютера и символизирует начало связки с пользователем. А 13е - это непосредственно сами данные, как "связать".
27. Антон Володченко (Euroset1) 4 28.02.17 23:44 Сейчас в теме
13й не происходит при выполнении фонового задания. То есть 13й массив заполняется лишь связями клиентских пользователей и машин
Также есть подозрения, что 11й и 12й не влияют а 13й. Похоже, они задумывались, как вспомогательные массивы под пользователей и машины. Но на практике у них всегда заполнен {0} в качестве значения. С точки зрения анализа и переноса в новый формат, это бессмысленная информация. Рудимент и не более.
28. Дмитрий Выприцкий (VipDim) 20.04.17 09:29 Сейчас в теме
Тоже очень (просто жизненно) интересно что означает {"P",{6,{"S","Строка1"},{"S","Строка2"}}}
Столкнулся с проблемой обращения к журналу регистрации через SQLite. Приходится расшифровывать все эти данные для вывода в табличную часть и последующего отбора. Для указанной комбинации перепробовал все возможные типы. Ничего не подошло.
Может кто разобрался что это за данные?
Оставьте свое сообщение