Инструменты экспорта журнала регистрации 1С в ClickHouse/ElasticSearch

Публикация № 1325649

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

Журнал регистрации Elastic search SQL Server Clickhouse Мониторинг Администрирование

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

Удалил релизы инструментов, которые были выложены здесь. Все последующие обновления и справочная информация обновляются и доступны только на странице репозитория. Оставлю эту статью как анонс.

Реализована работа только с файловым форматом журнала (lgp и lgf).

В публикации описаны инструменты для 2 СУБД:

  • ElasticSearch
  • ClickHouse

Я в своей ежедневной работе остановился на связке ClickHouse + Redash для визуализации данных (за что отдельное спасибо Юрию, сам бы не добрался посмотреть ее:)).

Для работы с ElasticSearch достаточно лишь установленного экземпляра ноды и Kiban`ы для визуализации.

Приложения работают в "Live" режиме, автоматически отслеживая появление/удаление файлов журнала и продолжая работать с последней позиции файла после перезапуска службы. Написаны на C# (net standard 2.1, net 5). Исходный код всех приложений открыт под лицензией MIT и может использоваться Вами как угодно. 

Репозиторий на Github состоит из нескольких проектов, вершиной айсберга которых является служба EventLogExporter.

 Ну, приступим.

Состав репозитория:

  • OneSTools.EventLog - Библиотека для чтения журнала регистрации (старый формат, LGF и LGP файлы). Позволяет выполнять как разовое чтение данных, так и запуск в "live" режиме
  • OneSTools.EventLog.Exporter.Core - Библиотека-ядро для инструментов экспорта журнала регистрации, на основе которой можно создавать приложения для экспорта в новые СУБД.
  • OneSTools.EventLog.Exporter.ClickHouse - Базовый пакет, реализующий интерфейс IEventLogStorage для экспорта журнала регистрации 1С в ClickHouse
  • OneSTools.EventLog.Exporter.ElasticSearch - Базовый пакет, реализующий интерфейс IEventLogStorage для экспорта журнала регистрации 1С в ElasticSearch
  • EventLogExporter - Служба для экспорта журнала регистрации в ClickHouse и ElasticSearch

Get started:

Конфигурация:

Файл конфигурации (appsettings.json) разбит на несколько секций, каждая из которых отвечают за функциональность определенной части приложения.

Exporter: В этой секции размещены общие параметры экспортера, не зависящие от СУБД.

"Exporter": {
    "StorageType": 2,
    "LogFolder": "C:\\Users\\akpaev.e.ENTERPRISE\\Desktop\\1Cv8Log",
    "Portion": 10000,
    "TimeZone": "Europe/Moscow",
    "WritingMaxDegreeOfParallelism": 8,
    "CollectedFactor": 8,
    "ReadingTimeout": 1,
    "LoadArchive": false
  }

где:

  1. StorageType - тип хранилища жрунала регистрации. Может принимать значения:
    1 - Clickhouse
    2 - ElasticSearch
  2. LogFolder - путь к каталогу журнала регистрации 1С.
  3. Portion - Размер порции, записываемый в БД за одну итерацию (10000 по умолчанию)
  4. TimeZone - часовой пояс (в формате IANA Time Zone Database), в котором записан журнал регистрации. По умолчанию - часовой пояс системы
  5. WritingMaxDegreeOfParallelism - количество потоков записи в СУБД. Т.к. в ClickHouse не поддерживаются одновременные BULK операции, то параметр имеет смысл только для ElasticSearch. По умолчанию - 1.
  6. CollectedFactor - коэффициент количества элементов, которые могут быть помещены в очередь записи. Предельное количество элементов равно Portion * CollectedFactor. По умолчанию - 2.
  7. ReadingTimeout - таймаут сброса данных при достижении конца файла (в секундах). По умолчанию - 1 сек.
  8. LoadArchive - Специальный параметр, предназначенный для первоначальной загрузки архивных данных. При установке параметра в true, отключается "live" режим и не выполняется запрос последнего обработанного файла из БД

ClickHouse: Заполнение секции требуется, если в секции Exporter у параметра StorageType указано значение 1.

"ConnectionStrings": {
    "Default": "Host=localhost;Port=8123;Username=default;password=;Database=database_name;"
  }

ElasticSearch:

"ElasticSearch": {
    "Nodes": [
      {
        "Host": "http://192.168.0.95:9200",
        "AuthenticationType": "0"
      },
      {
        "Host": "http://192.168.0.93:9200",
        "AuthenticationType": "1",
        "UserName": "",
        "Password": ""
      }
      {
        "Host": "http://192.168.0.94:9200",
        "AuthenticationType": "2",
        "Id": "",
        "ApiKey": ""
      }
    ],
    "Index": "upp-main-el",
    "Separation": "M",
    "MaximumRetries": 2,
    "MaxRetryTimeout": 30
  }

где:

  1. Nodes - узел, содержащий хосты кластера ElasticSearch, либо один узел при работе с одной нодой. При недоступности текущего узла будет происходить переключение на следующий узел списка. Для узлов доступны 3 типа аутентификации:
    0 - без аутентификации
    1 - Basic
    2 - ApiKey
  2. Index - префикс названия индекса, конечное название будет определено в зависимости от значения параметра Separation.
  3. Separation - метод разделения данных по индексам. Может принимать значения:
    H (Hour) - делить индексы по часам. Пример конечного названия индекса: index-name-el-2020010113
    D (Day) - делить индексы по дням. Пример конечного названия индекса: index-name-el-20200101
    M (Month) - делить индексы по месяцам. Пример конечного названия индекса: index-name-el-202001
    При указании любого другого (либо не указании вовсе) значения, разделения индекса не будет и конечное название индекса будет выглядеть так: index-name-el-all
  4. MaximumRetries - количество попыток переподключения к очередному узлу
  5. MaxRetryTimeout - таймаут попытки подключения

Так-же при первом подключении к узлу приложение проверяет наличие шаблона индекса (Index template) с именем "oneslogs" и при отсутствии - создает. Если шаблон уже создан, то его перезапись происходить не будет, так как предполагается возможная ручная модификация первично созданного шаблона.

Пример файла кофигурации, содержащий секции для всех поддерживаемых СУБД:

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Exporter": {
    "StorageType": 2,
    "LogFolder": "C:\\Users\\akpaev.e.ENTERPRISE\\Desktop\\1Cv8Log",
    "Portion": 10000,
    "TimeZone": "Europe/Moscow",
    "WritingMaxDegreeOfParallelism": 1,
    "CollectedFactor": 2,
    "ReadingTimeout": 1,
    "LoadArchive": false
  },
  "ClickHouse": {
    "ConnectionString": "Host=192.168.0.93;Port=8123;Database=upp_main_el;Username=default;password=;"
  },
  "ElasticSearch": {
    "Nodes": [
      {
        "Host": "http://192.168.0.95:9200",
        "AuthenticationType": "0"
      }
    ],
    "Index": "upp-main-el",
    "Separation": "M",
    "MaximumRetries": 2,
    "MaxRetryTimeout": 30
  }
}

Использование:

Все приложения могут быть запущены в 2 режимах: как обычное приложение, либо как служба Windows/Linux. Для теста в Вашей среде, достаточно просто выполнить конфигурацию приложения в файле appsettings.json, установить runtime .net 5 (при его отсутствии) и запустить exe/dll. Базы данных в СУБД вручную создавать не нужно, они будут созданы автоматически.

Для запуска приложения как службы необходимо (название службы и путь к исполняемому файлу подставить свои):

Windows:
Поместить файлы приложения в каталог и выполнить в консоли команду:

sc create EventLogExporter binPath= "C:\elexporter\EventLogExporter.exe"

и запустить службу командой:

sc start EventLogExporter

Linux: (на примере Ubuntu 20.04.1 LTS):
В этом примере файлы приложения были помещены в каталог /opt/EventLogExporter
В /etc/systemd/system создать файл eventlogexporter.service с содержимым:

[Service]
Type=notify
WorkingDirectory=/opt/EventLogExporter
ExecStart=/usr/bin/dotnet /opt/EventLogExporter/EventLogExporter.dll

[Install]
WantedBy=multi-user.target

Применить изменения командой:

systemctl daemon-reload

и запустить службу:

systemctl start eventlogexporter.service

Результаты тестирования:

Для теста был использован сервер с Intel Xeon E5-2643 3.40 GHz x2, 128 GB RAM и SAS дисками (Windows Server 2016). Экземпляр ElasticSearch установлен на хосте, экземпляр ClickHouse развернут на нем же в виртуальной машине (Hyper-V) с 4096 MiB RAM. Размер загружаемого журнала регистрации - 945 MiB.

СУБД Порция Время загрузки
Потребляемая память
Событий/сек MiB/сек Размер таблицы
ClickHouse 10000
 1 мин. 41 сек.
~ 60 MiB
      71032
   9.13
56.66 MiB
ElasticSearch 5000 2 мин. 35 сек. ~ 100 MiB 45968 6.09 1106.7 MiB

ClickHouse использовался as is, но на колонки (в зависимости от типа и состава данных) были выставлены кодеки. Для шаблона индекса ElasticSearch были выставлены параметры number_of_shards = 6, number_of_replicas = 0, index.codec = best_compression и использовалось 4 потока записи.

Исходные коды этих приложений и других библиотек для работы с данными 1С можно посмотреть на моей странице Github. Там же можно бесплатно скачать архивы.

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. user612295_death4321 12.11.20 19:54 Сейчас в теме
Можно ли привести аналогию сравнения размеров данных ?

Например имеем входные данные интенсивной работы пользователей, допустим ЖР на 1 ГБ в сутки.

Сколько эти 1 ГБ будут весить в КХ или Эластике ? Скорость ведь не бесплатная..
3. akpaevj 154 14.11.20 10:28 Сейчас в теме
(1) Опубликовал результаты теста
user612295_death4321; +1 Ответить
4. user612295_death4321 14.11.20 14:22 Сейчас в теме
(3) Спасибо, очень познавательно. Честно говоря, у меня есть эта проблема с тем, что слишком огромные ЖР и я все мечтаю начать куда нибудь их начать переливать.

Евгений, а можете поделиться целевой архитектурой, как у себя организовали импорт данных в КХ ?

Интересны следующие вещи:
1. Какая стратегия формирования файлов журналов регистрации в продуктиве? Час / День / Неделя / Месяц / etc ?
2. Служба импорта работает напрямую на сервере приложений 1С или вынесена на какую то отдельную ноду на которую копируются файлы ЖР?
3. КХ требует каких - то навыков администрирования, грамотного обслуживания и т.д.?
4. Как часто очищаете данные из КХ ?
5. akpaevj 154 14.11.20 14:43 Сейчас в теме
(4)
1. Файлы ЖР делятся по дням и удаляются ежедневно.
2. В целом, схема такая:
Есть 2 сервера приложений 1С. На одном из них установлен сборщик и виртуалка с КХ и Redash. Сбор осуществляется с локальных и сетевых папок.
3. На этот вопрос нет общего ответа. У меня развернут 1 экземпляр КХ и все обслуживание сводится к мониторингу доступности, так как нет таких объёмов логов, которые могут потребовать отдельного внимания на КХ. На более сложных системах возможно и потребуется, но это должны быть действительно большие системы с кластером КХ и/или ОЧЕНЬ большим объёмом логов. Вообще, у Яндекса очень хорошая документация на эту БД, там есть ответы на большинство вопросов.
4. Размер таблиц логов настолько мал, что, кажется, чистить их будет мой преемник:))
user612295_death4321; user1464234; +2 Ответить
6. user612295_death4321 17.11.20 18:25 Сейчас в теме
(5) Евгений, а я что-то сразу не обратил внимание. Я верно читаю результаты тестирования, что при исходном текстовом файле лога журнала регистрации условных 3.3 ГБ, на выходе в КХ мы получили логов на 15 мегабайт. Может где-то нолики или циферки потерялись???
7. akpaevj 154 17.11.20 18:33 Сейчас в теме
(6) Вы все правильно прочитали, ошибки нет. Так как СУБД колоночная, то на размер напрямую влияет уникальность значений в столбце
16. user612295_death4321 05.12.20 08:14 Сейчас в теме
(7) Протестировал у себя, у меня результаты конечно не такие радужные, 600 МБ логов превратились в 37 МБ, но все ровно круто)
17. akpaevj 154 05.12.20 11:30 Сейчас в теме
(16) Я протестирую еще на нескольких наборах данных и обновлю данные тестов. Похоже моя тестовая выборка была не очень репрезентативной. С 600 до 37 - просто отличный результат.
8. DonAlPatino 151 18.11.20 20:00 Сейчас в теме
(5)
1. Старые файлы ЖР удаляются вашим приложением или что-то отдельное работает?
2. Я правильно понимаю, что файл тоже читает само приложение - никаких logtash/filebeat? Оно же запоминает точку остановки в случае перезапуска?
А сборку нескольких записей в журнал в одну строку тоже само приложение делает?
Проблема с тем что начало журналирования операции попало во "вчерашний" файл, а конец в "сегодняшний" как-то решается? Или отсутствие записей об окончании в случае перезапуска сервера?
9. akpaevj 154 18.11.20 21:11 Сейчас в теме
(8) В статье уже несколько устаревшая информация, обновлять ее здесь не планирую. Очень много нововведений, в том числе работа с кластером elastic'а. Все обновления документации и инструментов доступно на странице репозитория в github.
1. В статье описан только инструмент экспорта. Дополнительно я в данный момент разрабатываю и тестирую у себя службу, которая автоматически добавляет новые базы к экспорту логов и удаляет устаревшие файлы.
2. Кроме самого elastic'а больше ничего не нужно. Приложение запоминает местоположение и продолжает экспорт с последней прочитанной позиции. Вторую часть вопроса (о начале и конце "операции") не совсем понял, поясните
10. DonAlPatino 151 20.11.20 15:01 Сейчас в теме
(9) Ох, говорила мне мама - учи C#, а то так и будешь всю жизнь "манагером".

Я правильно понимаю, что вот тут (это из EventLogReader.cs)
            var (Value, Uuid) = _lgfReader.GetReferencedObjectValue(ObjectType.Users, (int)parsedData[3], cancellationToken);
            eventLogItem.UserUuid = Uuid;
            eventLogItem.User = Value;


Как раз по ссылке собираются все записи с одним ID, чтобы потом выкинуть в КХ или Эластик одной записью?
Сорри я парсером журналов больше года назад занимался, а сейчас вообще из мира 1С ушел.
Просто такую задачку мы решали сначала загружая все в SQL базу, а затем там объединяли записи (Сложнейшая загрузка журнала регистрации в ElasticSearch (или делаем настоящий ETL)
А тут все сильно проще, быстрее и того монстра явно можно закопать.
11. DonAlPatino 151 20.11.20 15:28 Сейчас в теме
(10)Перечитал комменты к моей старой статье. Я как раз comol'а просил поделиться как правильно сделать на КХ. Прошло время - вот оно :-)
13. akpaevj 154 20.11.20 17:53 Сейчас в теме
(11) А, я понял о каком объединении Вы говорите. Вероятно, речь идет об агрегации начала/конца/отката транзакции. Этим служба не занимается. Для анализа длительности транзакций на мой взгляд проще пользоваться clickhouse с его mergetree и постобработкой, ну и ТЖ, естественно.
14. DonAlPatino 151 23.11.20 12:33 Сейчас в теме
(13)Ну тогда это пока не то :-( Я же все это включая буферную базу замутил, чтобы отчет в ELKе "как в 1С" получить. Ибо те же одинэсники встали в позу. И делали мы ее практически без участия 1с программеров.
Вот когда будет рассказ про "mergetree и постобработку" с выводом результатов как в 1С - тогда можно будет и мою систему закопать наконец-то.
15. akpaevj 154 23.11.20 15:18 Сейчас в теме
(14) С задачей агрегации данных и получения длительности транзакции все просто - ее не стоит выполнять с помощью журнала регистрации, that's all)) Только с помощью ТЖ, либо с помощью подсистемы "Оценка производительности" из БСП.
12. akpaevj 154 20.11.20 16:44 Сейчас в теме
(10) Это фрагмент кода заполнения экземпляра класса EventLogItem (записи события журнала), где устанавливаются GUID и Имя пользователя:) ничего более. В журнале нет нескольких записей с одним id. Каждое событие представлено отдельной записью. Видел Вашу статью, знатно вы там наворотили:))
2. akpaevj 154 12.11.20 20:29 Сейчас в теме
(1) Без суда и следствия могу сказать что клик выигрывает по всем показателям с очень большим отрывом. В ближайшее время выложу сравнение
18. Evil Beaver 6924 30.12.20 12:18 Сейчас в теме
Огнищще! Я джва года ждал такую разработку!
Оставьте свое сообщение

См. также

Повышение качества разработок и онлайн контроль ошибок Промо

Журнал регистрации v8 Абонемент ($m)

Анализ ошибок и сбор ошибок журнала регистраций из десятков и сотен баз в одном месте.

09.03.2018    26825    DitriX    48    

Мультибазовая очистка Журнала регистрации с автоматическим перемещением архивных данных в указанный каталог

Журнал регистрации v8 Россия Абонемент ($m)

На сервере 1С со временем увеличивается в размерах папка , содержащая журналы регистрации 1С и как следствие может возникнуть проблема свободного пространства на системном жестком диске. Чтобы избежать роста папки, необходимо периодически очищать журнал регистрации 1С.

1 стартмани

26.12.2019    3309    bryantsev.yury    3    

Как отправить ошибки из журнала регистрации на почту?

Журнал регистрации v8 УПП1 Абонемент ($m)

Процедуры отправки ошибок из журнала регистрации на почту. Журнал регистрации выгружается в файл Excel, далее прикрепляется к письму. Для отправки писем создано регламентное задание.

1 стартмани

06.02.2019    9109    wowik    0    

Мониторинг журнала регистрации при помощи Powershell

Сервисные утилиты Журнал регистрации v8 Абонемент ($m)

Работа с журналом регистрации в формате SQLite внешними средствами на примере мониторинга изменений в конфигурации базы данных.

1 стартмани

12.07.2018    13037    user768334    7    

Журнал регистрации 1С (sql lite) в web app

Журнал регистрации v8 1cv8.cf Абонемент ($m)

Данная публикация рассматривает построение компонентного решения работы журнала регистрации в стороннем приложении(web app). Встала задача миграции sql lite жр во внешнюю базу. Данное решение было создано: 1. для хранения жр за весь период 2. для ускорения работы с жр 3. для ускорения сервера предприятия, так как именно он (а точнее рагент) пытается записать данные в жр sql lite(фактически файл на диске), после увеличения размера файла более 10 гб, поступали жалобы по вопросу быстродействия 1с (и не только ради этого) Данная публикация может быть полезной администраторам, программистам, оптимизаторам.

1 стартмани

09.07.2018    9648    dmarenin    8    

Перенос журналов регистрации при изменении сервера приложения 1С (клиент-серверный вариант)

Журнал регистрации v8 1cv8.cf Россия Абонемент ($m)

Описание расположения журналов регистрации информационных баз 1С при клиент-серверном варианте работы с 1С:Предприятие 8. Пример переноса журналов регистрации информационной базы 1С с платформы 1С:8.2 на платформу 1С:8.3

15.08.2017    23491    OlegAl    2