Elastic + filebeat + ТЖ 1С








Рассмотрим как можно обрабатывать удобно большой объем информации с простой структурой.
Это удобно для анализа логов ТЖ, поскольку типовыми механизмами он невозможен.

Официальный сайт эластика https://www.elastic.co/.
По ссылке https://www.elastic.co/downloads/ необходимо закачать и установить
1. elasticsearch
2. filebeat
3. kibana

Рассмотрим что для чего используется.
Elasticsearch это поисковый движок, он хранит данные.
Filebeat вычитывает файлы логов маркируя прочитанные и отправляет в elasticsearch.
Kibana это интерфейс к elasticsearch, который отображает данные и позволяет быстро находить нужные по отборам.

Запуск инструментов

Запуск filebeat
"D:distribfilebeat-7.0.0-windows-x86_64filebeat.exe" -c "D:distribfilebeat-7.0.0-windows-x86_64filebeat.yml" -path.home "D:distribfilebeat-7.0.0-windows-x86_64" -path.data "C:ProgramDatafilebeat" -path.logs "C:ProgramDatafilebeatlogs"
Проверка настроек filebeat
D:distribfilebeat-7.0.0-windows-x86_64filebeat.exe test config -c D:distribfilebeat-7.0.0-windows-x86_64filebeat.yml

Установка elasticsearch в виде сервиса
d:distribelasticsearch-7.0.0inelasticsearch-service.bat install

Запуск kibana выполняется файлом kibana.bat из папки bin корневого каталога.

Механизм работы:
Filebeat вычитывает файлы логов маркируя прочитанные и отправляет в elasticsearch с указанием в какой индекс ложить.
Если индекса нет он создается, если индекс есть в него добавляются новые записи.
Структура индекса создается по шаблону, который filebeat передает elasticsearch.
Сам шаблон filebeat берет из настроек fields.yml, так же можно указать свой шаблон.
Если в elasticsearch уже есть шаблон то по умолчанию он не обновляется (настройка setup.template.overwrite).
Для принудительного обновления шаблона необходимо выставить настройку setup.template.overwrite: true.
Так же можно самому создать шаблон напрямую в elasticsearch чтобы он подхватывался при создании индекса.
После создания индекса и шаблона необходимо задать правила парсинга сообщения ТЖ для разбора и заполнения полей индекса.

Настройка

Filebeat
Filebeat может обрабатывать каталоги и файлы.
Файлы читает построчно и гарантирует что прочитанное сообщение будет отправлено по крайней мере один раз и без потери данных.
Каждый файл обрабатывается отдельно.
Данные о прочитанных файлах хранятся в реестре.
По каждому файлу хранится уникальный идентификатор.
Это необходимо т.к. файл может быть переименован или перемещен.
Уникальные идентификаторы хранятся в реестре, поэтому возможен его рост при чтении большого количества файлов.
Более подробно описано в https://www.elastic.co/guide/en/beats/filebeat/7.0/how-filebeat-works.html.

# настраиваем сбор логов ТЖ
#=========================== Filebeat inputs =============================
filebeat.inputs:
— type: log

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    #- /var/log/*.log
    # Обращаем внимание на формат, ** будет смотреть в подкаталог, когда * не будет
    — d:logs1С**.log

#————————— Elasticsearch output ——————————

output.elasticsearch:
# Array of hosts to connect to.
hosts: ["localhost:9200"]

# Имя индекса, если нет то создается новый
index: "onectj-%{+yyyy.MM.dd}"

# Разделим на индексы по типам сообщений
# Без разделения все будет ложиться в один индекс описанный выше
indices:
— index: "onectj-call-%{+yyyy.MM.dd}"
when.contains:
message: "SCALL"
— index: "onectj-conn-%{+yyyy.MM.dd}"
when.contains:
message: "conn"

timeout: 60

# Нас интересует преобразование логов при обработке в эластике
# для этого необходимо указать pipeline (https://www.elastic.co/guide/en/beats/filebeat/6.4/elasticsearch-output.html) 
# который будет обрабатывать лог в эластике.
# В эластике необходимо настроить этот pipeline.
# Более подробно описано здесь
# https://www.elastic.co/guide/en/beats/filebeat/7.0/configuring-ingest-node.html
pipeline: "onectj_pipeline"

# загружать шаблон индекса в эластик, если шаблон есть он не перезаписывается
setup.template.enabled: true
# имя шаблона искомого в эластике для разбора индекса
setup.template.name: "onectj"
# паттерн шаблона
setup.template.pattern: "onectj-*"

#============================== Setup ILM =====================================

# Изменение имени индекса по умолчанию будет игнорироваться
# если включена ILM (управление жизненным циклом индекса).
# Можно либо доработать ILM либо отключить
# Более подробно описано здесь
# https://www.elastic.co/guide/en/beats/filebeat/7.0/ilm.html#setup-ilm-overwrite-option
# filebeat 7.0+
setup.ilm.enabled: false
#setup.lim.overwrite: true

Elasticsearch
Для его настройки используем kibana, точнее ее консоль.

Добавим шаблон по которому будет создаваться индекс.

PUT _template/onectj
{
"index_patterns": ["onectj-*"],
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
/*добавляем поля*/
"num_min": {
"type": "integer"
}
,"num_sec": {
"type": "integer"
}
,"ten_thousandth_second": {
"type": "integer"
}
,"duration": {
"type": "integer"
}
,"event1c": {
"type": "text"
}
,"level_event": {
"type": "text"
}
,"process_name": {
"type": "text"
}
,"usr": {
"type": "text"
}
,"context": {
"type": "text"
}
,"process1c": {
"type": "text"
}
,"ClientID_name": {
"type": "text"
}
,"ClientID": {
"type": "text"
}
,"computerName": {
"type": "text"
}
/*можно добавить группу полей*/
/*"onec": {
"properties": {
"num_min": {
"type": "long"
}
,"num_sec": {
"type": "long"
}
,"ten_thousandth_second": {
"type": "text"
}
,"duration": {
"type": "text"
}
}*/
}
}
}
}

Посмотреть существующий шаблон можно по команде

# получим шаблон индекса ТЖ
GET /_template/onectj

Чтобы просмотреть все шаблоны команда будет похожая

GET /_template/*

Для удаления шаблона используется команда

# удалим шаблон
DELETE _template/onectj*

Внимание!!!
Изменение шаблона делается по аналогии с добавлением.
Но если изменился тип поля то он обновится только в новом индексе либо при переиндексации существующего.

После создания шаблона определим правила разбора сообщения на поля индекса.

Внимание!!!
В индексе отображаются только заполненные поля.
Т.е. если поле есть в шаблоне, но не заполняется правилами оно не будет отображаться при просмотре индекса.

При создании правил допускается указание нескольких правил списком, при этом отработает первое подходящее.

# установим шаблон разбора сообщений ТЖ
PUT _ingest/pipeline/onectj_pipeline
{
"description" : "onec tj pipeline",
"processors": [
{
"grok": {
"field": "message",
"patterns": ["%{NUMBER:num_min}:%{BASE10NUM:num_sec}-%{WORD:duration},%{WORD:event1c},%{WORD:level_event}"]
}
},
{
"grok": {
"field": "message",
"patterns": [
"process=%{WORD:process1c}"
],
"on_failure": [
{
"set": {
"field": "process1c",
"value": ""
}
}
]
}
},
{
"grok": {
"field": "message",
"patterns": [
"Usr=%{WORD:usr}"
],
"on_failure": [
{
"set": {
"field": "usr",
"value": ""
}
}
]
}
},
{
"grok": {
"field": "message",
"patterns": [
"Context=%{WORD:context}"
],
"on_failure": [
{
"set": {
"field": "context",
"value": ""
}
}
]
}
}
]
}

Отладить выражения для разбора можно следующим образом

# проверим шаблон разбора сообщений ТЖ
POST _ingest/pipeline/_simulate
{
"pipeline": {
"description" : "parse multiple patterns",
"processors": [
{
"grok": {
"field": "message",
"patterns": ["%{NUMBER:num_min}:%{BASE10NUM:num_sec}-%{WORD:duration},%{WORD:event1c},%{WORD:level_event},process=%{WORD:process_name}"]
}
},
{
"grok": {
"field": "message",
"patterns": [
"process=(%{DATA:process},|%{GREEDYDATA:process})"
],
"on_failure": [
{
"set": {
"field": "process",
"value": ""
}
}
]
}
}
]
},
"docs":[
{
"_source": {
"message": "16:40.991013-1,SCALL,0,process=ragent,ClientID=248,Interface=0459eaa0-589f-4a6d-9eed-c1a7461c8e3f,IName=IClusterRegistry,Method=18,CallID=915855,MName=getServersList"
}
}
]
}

Kibana

Для просмотра индексов в kibana необходимо создать паттерн их отображения.

Для этого зайдем в паттерны индексов и создадим новый.

Укажем маску для группировки нескольких индексов.

Выберем поле хранящее время события

Создадим паттерн индекса.
Теперь выбрав этот паттерн можно будет просматривать индексы.

Отладка

Для анализа проблем обработки в elasticsearch используем журнал filebeat.

#================================ Logging =====================================

# Sets log level. The default log level is info.
# Available log levels are: error, warning, info, debug
logging.level: debug
logging.to_files: true
logging.files:
path: "d:\distrib\filebeat-7.0.0-windows-x86_64\logs"
name: filebeat

Указываем уровень регистрируемых ошибок, включаем журнал. При желании можно указать свой каталог логов.
В случае ошибок они отобразятся в логах
Например
 

#2024-06-07T09:40:14.117+0700 DEBUG [elasticsearch] elasticsearch/client.go:532 Bulk item insert failed (i=0, status=500): {"type":"exception","reason":"java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Provided Grok expressions do not match field value: [ОбщийМодуль.ГлобальныйМодуль.Модуль : 10 : ТекущийРежим = ПолучитьБлокировкуУстановкиСоединений();']","caused_by":{"type":"illegal_argument_exception","reason":"java.lang.IllegalArgumentException: Provided Grok expressions do not match field value: [ОбщийМодуль.ГлобальныйМодуль.Модуль : 10 : ТекущийРежим = ПолучитьБлокировкуУстановкиСоединений();']","caused_by":{"type":"illegal_argument_exception","reason":"Provided Grok expressions do not match field value: [ОбщийМодуль.ГлобальныйМодуль.Модуль : 10 : ТекущийРежим = ПолучитьБлокировкуУстановкиСоединений();']"}},"header":{"processor_type":"grok"}}

Данная ошибка говорит об отсутствии в паттерне шаблона условия для разбора сообщения.
Сообщение не загрузилось.
Пример сообщений журнала.

17 Comments

  1. Kluch

    Хорошая статья.

    А как указать, что нужно загружать шаблон индекса из файла json. Вроде есть такая возможность, но что-то не получается:

    setup.template.json.enabled: true

    setup.template.json.name: «onectj»

    setup.template.json.path: ${path.config}/my_template.json

    И есть ли возможность также указать файл с pipeline в настройках?

    Чтобы не вызывать:

    PUT _template/onectj

    PUT _ingest/pipeline/onectj_pipeline

    Reply
  2. starik-2005

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

    Reply
  3. pashamak

    (1) Добрый день.

    Спасибо!

    По документации имя pipeline нужно указывать в настройках, о его загрузке из настроек речи нет.

    Подробнее здесь https://www.elastic.co/guide/en/beats/filebeat/7.0/elasticsearch-output.html.

    К шаблону предъявляются требования.

    В логах есть ошибка загрузки шаблона?

    Пример двух разных ошибок некорректного разбора шаблона:

    2019-06-20T09:44:23.605+0700 ERROR pipeline/output.go:100 Failed to connect to backoff(elasticsearch(http://localhost:9200)): Connection marked as failed because the onConnect callback failed: Error loading Elasticsearch template: could not unmarshal json template: json: cannot unmarshal array into Go value of type map[string]interface {}

    2019-06-20T09:56:59.672+0700 ERROR pipeline/output.go:100 Failed to connect to backoff(elasticsearch(http://localhost:9200)): Connection marked as failed because the onConnect callback failed: Error loading Elasticsearch template: could not unmarshal json template: invalid character ‘}’ after top-level value

    (1)

    Приложил пример шаблона приведенного в статье.

    У меня после удаления шаблона в эластике он загрузился из json корректно.

    Reply
  4. Kluch

    (3) Добрый день.

    В логах в консоли как я понимаю пишет: Template already exists and will not be overwritten и загружает шаблон по умолчанию.

    Ошибки в моем шаблоне нет, через PUT _template он загружается.

    Логи в файл тоже не собираются (выводятся на экран в консоли).

    Думаю проблема в задании путей. Что-то не пойму как их указывать?

    «E:\ELK_Stack_7.0.0\filebeat-7.0.0\logs» — с двумя слешами

    «E:ELK_Stack_7.0.0filebeat-7.0.0logs» — с одним слешем

    E:ELK_Stack_7.0.0filebeat-7.0.0logs — без кавычек

    ${path.config}/logs — или может так?

    В секции filebeat.inputs работает так:

    paths:

    — D:Logs_ELK*.log

    Reply
  5. ALex_1C_8

    Может не внимательно читал, но я так и не понял. Как решаете проблему многострочных событий в ТЖ.

    Reply
  6. Kluch

    (5) По идее есть настройка в разделе filebeat.inputs:

    multiline.pattern:

    Например:

    multiline.pattern: ‘(dd:dd).(d+)-(d+)’

    Reply
  7. pashamak

    (4) Проблема в существовании шаблона, он его не может обновить без включенной настройки замены.

    Можно (1 ) удалить существующий шаблон или (2) указать замену шаблон в настройках.

    1. DELETE _template/[имя шаблона]

    2. Описано здесь https://www.elastic.co/guide/en/beats/filebeat/7.0/configuration-template.html

    setup.template.overwrite

    A boolean that specifies whether to overwrite the existing template. The default is false.

    Reply
  8. pashamak

    (5) Это не описывал в статье.

    Посмотрите по (6) описание в доке https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-reference-yml.html

    Reply
  9. Repich

    (5)

    input {

    file {

    codec => multiline {

    pattern => «#k8SjZc9Dxk(0[0-9]|1[0-9]|2[0-3]|[0-9]):[0-5][0-9]»

    negate => true

    what => «previous»

    }

    Reply
  10. serge_focus

    Привет

    А для файлового ЖР у Вас есть pipeline и Настройка.yml?

    Хочу перевести ЖР в старый формат

    Reply
  11. pashamak

    (10) Для журнала регистрации есть сервис который его разбирает и складывает в эластик.

    Сервис написан, но находится в процессе отладки.

    Пример прилагаю в скриншоте.

    При интересе пишите в личку могу отправить.

    Reply
  12. EGOLEGE

    Интересная статья!

    Reply
  13. Darklight

    Интересная статья, но не для начинающих (всё-таки основы тут не разбираются — нужно вникакать в принципы описания взаимодействий filebeat и elasticserach по другим статьям — не про разбор 1С ТЖ).

    Вот, я так и не смог разобраться — как формируется дата события — части времени берутся из строки события ТЖ и помещаются в заданные для них поля индекса. Но, во-первых, там нет полного времени ни даты ни часа — это всё находится в имени файла, а оно в filebeat тут никак не разбирается. А, во-вторых, так и не понятно — как потом формируется timestamp записи в Elasticsearch (поле — которое указывается при создании паттерна индекса в kibana)? Можете это подробнее пояснить?

    Так же жаль, что не уделили времени в статье обработке событий, разделённых на несколько строк. Ну, в (8),(9) конечно дали намёк — что нужно включить обработку таких строк в filebeat и определять перенос строки — когда начало перенесённой строки не совпадает с партерном описания времени (то это перенесённая строка — хотя это и не совсем надёжно). Но всё- равно стоило бы это описать в статье — ибо для 1C ТЖ это рядовая ситуация и не самая простая при обработке ТЖ классическими путём

    Reply
  14. EliasShy

    Добрый день.

    Спасибо за статью — очень ценная информация.

    Подскажите, какими настройками Filebeat удалось его заставить сообщение формировать не по концу строки, а полное — т.е. чтобы начиналось с маркера времени?

    Reply
  15. pashamak

    Если речь о скрине выше то это отдельный сервис написанный на .net. Он ставится отдельно и сам все разбирает.

    Если речь про ТЖ то с работы pipeline не покажу.

    Смотрите в строну нескольких регулярок.

    Reply
  16. pashamak

    (14)Для многострочных событий используйте мультилайн, он описан выше

    Reply
  17. EliasShy

    (9) это настройка для logstash насколько понимаю

    для filebeat будет

    multiline.pattern: ‘#k8SjZc9Dxk[0-9][0-9]:[0-9][0-9][.][0-9][0-9][0-9][0-9][0-9][0-9]’

    multiline.match: after

    multiline.negate: true

    Только после чтения документации понимаешь почему after и почему negate — по-наитию сначала ставил before и negate false

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *