Обработка данных с помощью DISSECT и GROK
Ваши данные могут содержать неструктурированные строки, которые вы хотите структурировать. Это упрощает анализ данных. Например, сообщения журналов могут содержать IP-адреса, которые вы хотите извлечь, чтобы найти самые активные IP-адреса.
Elasticsearch может структурировать ваши данные на этапе индексирования или запроса. На этапе индексирования вы можете использовать процессоры обработки Dissect и Grok, или фильтры Logstash Dissect и Grok. На этапе запроса вы можете использовать команды ES|QL DISSECT и GROK.
DISSECT или GROK? Или оба?
DISSECT работает, разбивая строку с помощью шаблона на основе разделителей. GROK работает аналогично, но использует регулярные выражения. Это делает GROK более мощным, но, как правило, также медленнее. DISSECT хорошо работает, когда данные повторяются предсказуемо. GROK - лучший выбор, когда вам действительно нужна мощность регулярных выражений, например, когда структура вашего текста меняется от строки к строке.
Вы можете использовать как DISSECT, так и GROK для гибридных случаев использования. Например, когда часть строки повторяется предсказуемо, но вся строка не повторяется. DISSECT может разобрать повторяющуюся часть строки. GROK может обработать оставшиеся значения поля с помощью регулярных выражений.
Обработка данных с помощью DISSECT
Команда обработки DISSECT сопоставляет строку с шаблоном на основе разделителей и извлекает указанные ключи в качестве столбцов.
Например, следующий шаблон:
%{clientip} [%{@timestamp}] %{status} соответствует строке журнала такого формата:
1.2.3.4 [2023-01-23T12:15:00.000Z] Connected
и приводит к добавлению следующих столбцов в входную таблицу:
| clientip:keyword | @timestamp:keyword | status:keyword |
|---|---|---|
1.2.3.4 | 2023-01-23T12:15:00.000Z | Connected |
Шаблоны dissect
Шаблон dissect определяется частями строки, которые будут отброшены. В предыдущем примере первая отбрасываемая часть — это один пробел. Dissect находит этот пробел, затем присваивает значение clientip всему до этого пробела. Затем dissect сопоставляет [ и затем ], и затем присваивает @timestamp всему между [ и ]. Особое внимание к частям строки, которые нужно отбросить, поможет создать успешные шаблоны dissect.
Пустой ключ (%{}) или именованный ключ пропуска может быть использован для сопоставления значений, но исключает значение из вывода.
Все сопоставленные значения выводятся как строковый тип данных keyword. Используйте функции преобразования типов для преобразования в другой тип данных.
Dissect также поддерживает модификаторы ключей dissect, которые могут изменить стандартное поведение dissect. Например, вы можете указать dissect игнорировать определенные поля, добавлять поля, пропускать заполнители и т.д.
Терминология
- шаблон dissect
- набор полей и разделителей, описывающих текстовый формат. Также известен как разделение. Разделение описывается с помощью набора
%{}разделов:%{a} - %{b} - %{c} - поле
- текст от
%{до}включительно. - разделитель
- текст между
}и следующими%{символами. Любой набор символов, отличный от%{,'not }'или}, является разделителем. - ключ
-
текст между
%{и}, за исключением префиксов?,+,&и порядкового суффикса.Примеры:
-
%{?aaa}- ключ этоaaa -
%{+bbb/3}- ключ этоbbb -
%{&ccc}- ключ этоccc
-
Примеры
Следующий пример анализирует строку, содержащую метку времени, текст и IP-адрес:
ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
| DISSECT a """%{date} - %{msg} - %{ip}"""
| KEEP date, msg, ip | date:keyword | msg:keyword | ip:keyword |
|---|---|---|
2023-01-23T12:15:00.000Z | some text | 127.0.0.1 |
По умолчанию DISSECT выводит столбцы типа keyword string. Для преобразования в другой тип используйте функции преобразования типов:
ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1"
| DISSECT a """%{date} - %{msg} - %{ip}"""
| KEEP date, msg, ip
| EVAL date = TO_DATETIME(date) | msg:keyword | ip:keyword | date:date |
|---|---|---|
some text | 127.0.0.1 | 2023-01-23T12:15:00.000Z |
Ключевые модификаторы разбора
Ключевые модификаторы могут изменить поведение по умолчанию для разбора. Ключевые модификаторы могут быть расположены слева или справа от %{keyname} всегда внутри %{ и }. Например, %{+keyname ->} имеет модификаторы добавления и правого отступа.
Таблица 82. Ключевые модификаторы разбора
| Модификатор | Имя | Позиция | Пример | Описание | Подробности |
|---|---|---|---|---|---|
| Пропуск правого отступа | (крайний) правый |
| Пропускает любые повторяющиеся символы справа | |
| Добавить | слева |
| Объединяет два или более полей вместе | |
| Добавить с порядком | слева и справа |
| Объединяет два или более поля вместе в указанном порядке | |
| Ключ пропуска с именем | слева |
| Пропускает сопоставленное значение в выводе. То же поведение, что и |
Модификатор правого отступа (->)
Алгоритм, выполняющий разбор, очень строг, так как требует, чтобы все символы в шаблоне совпадали с исходной строкой. Например, шаблон %{fookey} %{barkey} (1 пробел) будет соответствовать строке "foo bar" (1 пробел), но не будет соответствовать строке "foo bar" (2 пробела), так как в шаблоне есть только 1 пробел, а в исходной строке - 2 пробела.
Модификатор правого отступа помогает в этом случае. Добавление модификатора правого отступа к шаблону %{fookey->} %{barkey}, теперь он будет соответствовать "foo bar" (1 пробел), "foo bar" (2 пробела) и даже "foo bar" (10 пробелов).
Используйте модификатор правого отступа, чтобы разрешить повторение символов после %{keyname->}.
Модификатор правого отступа может быть размещен на любом ключе с любыми другими модификаторами. Он всегда должен быть самым правым модификатором. Например: %{+keyname/1->} и %{->}
Например:
ROW message="1998-08-10T17:15:42 WARN"
| DISSECT message """%{ts->} %{level}""" | message:keyword | ts:keyword | level:keyword |
|---|---|---|
1998-08-10T17:15:42 WARN | 1998-08-10T17:15:42 | WARN |
Модификатор правого отступа может использоваться с пустым ключом, чтобы пропустить нежелаемые данные. Например, та же входная строка, но заключенная в скобки, требует использования пустого ключа с правым отступом, чтобы получить тот же результат.
Например:
ROW message="[1998-08-10T17:15:42] [WARN]"
| DISSECT message """[%{ts}]%{->}[%{level}]""" | message:keyword | ts:keyword | level:keyword |
|---|---|---|
["[1998-08-10T17:15:42] [WARN]"] | 1998-08-10T17:15:42 | WARN |
Модификатор добавления (+)
Разбор поддерживает добавление двух или более результатов вместе для вывода. Значения добавляются слева направо. Можно указать разделитель добавления. В этом примере разделитель добавления определен как пробел.
ROW message="john jacob jingleheimer schmidt"
| DISSECT message """%{+name} %{+name} %{+name} %{+name}""" APPEND_SEPARATOR=" " | message:keyword | name:keyword |
|---|---|
john jacob jingleheimer schmidt | john jacob jingleheimer schmidt |
Модификатор добавления с порядком (+ и /n)
Разбор поддерживает добавление двух или более результатов вместе для вывода. Значения добавляются в соответствии с определенным порядком (/n). Можно указать разделитель добавления. В этом примере разделитель добавления определен как запятая.
ROW message="john jacob jingleheimer schmidt"
| DISSECT message """%{+name/2} %{+name/4} %{+name/3} %{+name/1}""" APPEND_SEPARATOR="," | message:keyword | name:keyword |
|---|---|
john jacob jingleheimer schmidt | schmidt,john,jingleheimer,jacob |
Ключ пропуска с именем (?)
Разбор поддерживает игнорирование совпадений в конечном результате. Это можно сделать с помощью пустого ключа %{}, но для читабельности может потребоваться присвоить этому пустому ключу имя.
Это можно сделать с помощью ключа пропуска с именем, используя синтаксис {?name}. В следующей запросе, ident и auth не добавляются в таблицу вывода:
ROW message="1.2.3.4 - - 30/Apr/1998:22:00:52 +0000"
| DISSECT message """%{clientip} %{?ident} %{?auth} %{@timestamp}""" | message:keyword | clientip:keyword | @timestamp:keyword |
|---|---|---|
1.2.3.4 - - 30/Apr/1998:22:00:52 +0000 | 1.2.3.4 | 30/Apr/1998:22:00:52 +0000 |
Ограничения
Команда DISSECT не поддерживает ключи ссылок.
Обработка данных с помощью GROK
Команда обработки GROK сопоставляет строку с шаблоном на основе регулярных выражений и извлекает указанные ключи в качестве столбцов.
Например, следующий шаблон:
%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status} сопоставляется со строкой лога в формате:
1.2.3.4 [2023-01-23T12:15:00.000Z] Connected
Соединив это в запрос ES|QL:
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
| GROK a """%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}""" GROK добавляет следующие столбцы к входной таблице:
| @timestamp:keyword | ip:keyword | status:keyword |
|---|---|---|
2023-01-23T12:15:00.000Z | 1.2.3.4 | Connected |
Специальные символы регулярных выражений в шаблонах grok, такие как [ и ], должны быть экранированы с помощью \. Например, в предыдущем шаблоне:
%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status} В запросах ES|QL, когда для строк используются одинарные кавычки, сам символ обратной косой черты является специальным символом, который необходимо экранировать с помощью еще одной \. Для этого примера соответствующий запрос ES|QL становится:
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
| GROK a "%{IP:ip} \\[%{TIMESTAMP_ISO8601:@timestamp}\\] %{GREEDYDATA:status}" По этой причине в целом удобнее использовать тройные кавычки """ для шаблонов GROK, которые не требуют экранирования обратной косой черты.
ROW a = "1.2.3.4 [2023-01-23T12:15:00.000Z] Connected"
| GROK a """%{IP:ip} \[%{TIMESTAMP_ISO8601:@timestamp}\] %{GREEDYDATA:status}""" Шаблоны grok
Синтаксис шаблона grok — %{SYNTAX:SEMANTIC}
SYNTAX — это имя шаблона, который соответствует вашему тексту. Например, 3.44 соответствует шаблону NUMBER, а 55.3.244.1 соответствует шаблону IP. Синтаксис определяет способ сопоставления.
SEMANTIC — это идентификатор, который вы задаёте для совпадающего фрагмента текста. Например, 3.44 может быть длительностью события, поэтому вы можете назвать его просто duration. Кроме того, строка 55.3.244.1 может идентифицировать client, делающего запрос.
По умолчанию сопоставленные значения выводятся как строки типа данных keyword. Для преобразования типа данных семантики добавьте целевой тип данных. Например, %{NUMBER:num:int}, что преобразует семантику num из строки в целое число. В настоящее время поддерживаются только преобразования int и float. Для других типов используйте функции преобразования типов.
Для обзора доступных шаблонов обратитесь к GitHub. Также можно получить список всех шаблонов с помощью REST API.
Регулярные выражения
Grok основан на регулярных выражениях. Любые регулярные выражения также допустимы в grok. Grok использует библиотеку регулярных выражений Oniguruma. Обратитесь к репозиторию Oniguruma GitHub для полного синтаксиса поддерживаемых регулярных выражений.
Пользовательские шаблоны
Если в grok нет нужного шаблона, вы можете использовать синтаксис Oniguruma для именованного захвата, который позволяет сопоставить фрагмент текста и сохранить его в качестве столбца:
(?<field_name>the pattern here)
Например, журналы postfix содержат queue id, являющийся 10- или 11-символьным шестнадцатеричным значением. Это можно захватить в столбец под названием queue_id с помощью:
(?<queue_id>[0-9A-F]{10,11}) Примеры
В следующем примере анализируется строка, содержащая метку времени, IP-адрес, адрес электронной почты и число:
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}"""
| KEEP date, ip, email, num | date:keyword | ip:keyword | email:keyword | num:keyword |
|---|---|---|---|
2023-01-23T12:15:00.000Z | 127.0.0.1 | 42 |
По умолчанию GROK выводит столбцы типа keyword. Типы int и float могут быть преобразованы путём добавления :type к семантике в шаблоне. Например, {NUMBER:num:int}:
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"""
| KEEP date, ip, email, num | date:keyword | ip:keyword | email:keyword | num:integer |
|---|---|---|---|
2023-01-23T12:15:00.000Z | 127.0.0.1 | 42 |
Для других преобразований типов используйте функции преобразования типов:
ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42"
| GROK a """%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"""
| KEEP date, ip, email, num
| EVAL date = TO_DATETIME(date) | ip:keyword | email:keyword | num:integer | date:date |
|---|---|---|---|
127.0.0.1 | 42 | 2023-01-23T12:15:00.000Z |
Если имя поля используется более одного раза, GROK создаёт многозначный столбец:
FROM addresses
| KEEP city.name, zip_code
| GROK zip_code """%{WORD:zip_parts} %{WORD:zip_parts}""" | city.name:keyword | zip_code:keyword | zip_parts:keyword |
|---|---|---|
Amsterdam | 1016 ED | ["1016", "ED"] |
San Francisco | CA 94108 | ["CA", "94108"] |
Tokyo | 100-7014 | null |
Отладчик Grok
Для написания и отладки шаблонов grok вы можете использовать Отладчик Grok. Он предоставляет интерфейс для тестирования шаблонов на примерах данных. Под капотом он использует тот же движок, что и команда GROK.
Ограничения
Команда GROK не поддерживает настройку пользовательских шаблонов или нескольких шаблонов. Команда GROK не подчиняется настройкам оповещения Grok.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/esql-process-data-with-dissect-and-grok.html