Работа с RQL-запросами
В данном разделе описано, как использовать язык запросов R-Vision SIEM для анализа данных о событиях. Описано создание запросов, которые включают условия, управление выводом, сортировку и группировку результатов, работу с проекциями и заполнение данных. Также описывается использование фильтров, временных ограничений и формирование запросов для дашбордов.
Содержание раздела:
Создание запросов
Использование условий
В SQL в состав запроса необходимо включать указание на таблицу БД, к которой обращается запрос. В системе R-Vision SIEM для каждого хранилища событий в системе выбирается модель событий, определяющая формат хранения данных. Работа с событиями в разделе Поиск возможна только в рамках определенного хранилища.
Когда вы задаете временной диапазон поиска событий, оставив пустым поле поиска, и нажимаете кнопку Поиск, система по умолчанию выполняет поиск по всем полям текущей модели данных независимо от того, какие поля отображаются в списке событий.
Таким образом, из стандартного запроса с выборкой по определенному условию вида SELECT * FROM table WHERE
в рамках системы исключаются компоненты SELECT *
и FROM table
. Система обращается к таблице, соответствующей выбранной модели данных, выполняя поиск по всем полям. Запрос с выборкой по определенному условию в системе сводится к заданию условия WHERE
. Совмещение нескольких условий происходит стандартно, с использованием операторов и функций языка запросов RQL.
Пример запроса с условием
Запрос, возвращающий события, у которых значения в поле tenantId
начинаются с символа n, а количество символов в поле raw
превышает 10.
SELECT * FROM table WHERE tenantId LIKE 'n%' AND length(raw) > 10
tenantId LIKE 'n%' AND length(raw) > 10
Оператор WHERE используется в запросе при работе с проекциями.
|
Поиск по подсетям
Для поиска данных по подсетям используйте оператор IN
. Формат записи: %Сетевая маска%/%Префикс%
.
sourceIp IN '::ffff:192.0.2.0/24'
sourceIp IN '2001:db8::/32'
deviceTranslatedAddress IN '203.0.113.0/24'
Группировка результатов и работа с проекциями
Если вы используете оператор объединения результатов, необходимо указать, к какой проекции будет применяться объединение. Например, запрос вида GROUP BY tenantID
воспринимается системой как SELECT * GROUP BY tenantID
, и поэтому некорректен. Корректный запрос с указанной проекцией имеет вид SELECT tenantID GROUP BY tenantID
.
С оператором GROUP BY
в поисковых запросах очень часто применяются агрегатные функции (COUNT
, SUM
, AVG
, MAX
, MIN
).
SELECT tenantId, count(*) ORDER BY tenantId ASC
Этот запрос возвращает события, отсортированные по полю tenantId
с сортировкой по возрастанию и указанием количества событий в каждой группе.
Использование проекций позволяет применять к указанному полю запрос с выборкой строк по определенному условию.
SELECT tenantId WHERE length(tenantId) = 5
Этот запрос возвращает события с количеством символов в поле tenantId
, равным 5.
Стандартный запрос | Запрос в системе |
---|---|
SELECT tenantId FROM table |
SELECT tenantId |
SELECT tenantId FROM table WHERE length(tenantId) = 5 |
SELECT tenantId WHERE length(tenantId) = 5 |
SELECT tenantId, count(*) FROM table GROUP BY tenantId |
SELECT tenantId, count(*) GROUP BY tenantId |
Фильтрация результатов группировки
Если требуется отфильтровать группы данных, полученные после объединения результатов, используйте оператор HAVING.
SELECT tenantID, count(*) AS cnt GROUP BY tenantID HAVING cnt > 10
Этот запрос выбирает события, группируя их по tenantID, и возвращает только те группы, в которых количество событий больше 10.
Максимальное количество и сортировка возвращаемых записей
По умолчанию в списке результатов поискового запроса отображается 500 записей. Вы можете ограничить количество
возвращаемых записей с помощью оператора LIMIT
. Например, ограничение количества записей до 20 выполняется запросом LIMIT 20
. При этом также можно добавить команду OFFSET
, указывающую, сколько строк необходимо пропустить перед началом вывода строк.
Возможна сортировка выборки по любому полю с помощью команды ORDER BY
. Например, чтобы отсортировать события по полю collectorId
, введите запрос ORDER BY collectorId
.
Заполнение пропусков в списке возвращаемых результатов
При сортировке и группировке записей можно использовать модификатор WITH FILL
для заполнения пропусков в списке возвращаемых результатов.
Модификатор WITH FILL
может быть использован после ORDER BY expr
с опциональными параметрами FROM expr
, TO expr
и STEP expr
. Все пропущенные записи для колонки expr
будут заполнены значениями, соответствующими предполагаемой последовательности записей колонки, другие колонки будут заполнены записями по умолчанию.
Можно использовать следующие варианты синтаксиса:
-
ORDER BY field_name WITH FILL
: сортировка по полю с заполнением отсутствующих групп результатов с использованием значений по умолчанию для этого типа данных. -
ORDER BY field_name WITH FILL STEP expr
: сортировка по полю с заполнением отсутствующих групп результатов с указанным шагом для этого типа данных. -
ORDER BY field_name WITH FILL FROM expr TO expr STEP expr
: сортировка по полю с заполнением отсутствующих групп результатов с указанным шагом в указанном промежутке для этого типа данных.
Здесь field_name
— имя поля, по которому происходит сортировка, а expr
— выражение, которое определяет значения для заполнения пропущенных записей:
-
FROM expr
— начальное значение интервала, который будет заполнен; -
TO expr
— конечное значение; -
STEP expr
— шаг, с которым будет заполняться интервал.
Ограничения на использование оператора:
-
expr
должно принадлежать к одному из следующих типов:-
числовой литерал (целое или дробное число);
-
метка времени;
-
арифметическая операция с числами, меткой времени, интервалом или функцией;
-
функция с возвращаемым значением в виде числа или метки времени.
-
-
WITH FILL
можно применять только после имени колонки вORDER BY
. Допускается использование несколькихWITH FILL
для разных колонок.
Для случая с несколькими полями ORDER BY field2 WITH FILL, field1 WITH FILL порядок заполнения будет соответствовать порядку полей в секции ORDER BY .
|
Примеры заполнения пропусков
SELECT toStartOfHour(timestamp) as ts, sum(cnt) as sum_cnt GROUP BY ts HAVING sum_cnt > 0 ORDER BY ts WITH FILL FROM now() - INTERVAL 1 day TO now() STEP INTERVAL 1 hour
Данный запрос выполняет следующую последовательность операций:
-
SELECT toStartOfHour(timestamp) as ts, sum(cnt) as sum_cnt
: выбираются значения поляtimestamp
, округленные до начала каждого часа, и вычисляется сумма поляcnt
для каждой группы записей с одинаковым значениемts
. -
GROUP BY ts
: результаты группируются по полюts
, которое представляет округленные значения. -
HAVING sum_cnt > 0
: применяется фильтр, чтобы оставить только те группы записей, у которых сумма поляcnt
больше нуля. Это означает, что в результирующем наборе будут только записи, для которых существуют записи с положительными значениямиcnt
внутри группы. -
ORDER BY ts WITH FILL FROM now() - INTERVAL 1 day TO now() STEP INTERVAL 1 hour
: результаты сортируются по полюts
. Здесь используется модификаторWITH FILL
, который обеспечивает заполнение пропущенных интервалов с шагом в 1 час от текущего времени минус 1 день до текущего времени. То есть, если в исходных данных отсутствуют записи для определенных интервалов времени, то они будут включены в результирующий набор со значениями по умолчанию.
SELECT toStartOfHour(timestamp) as ts, sum(cnt) as sum_cnt GROUP BY ts HAVING sum_cnt > 0 AND ts >= now() - INTERVAL 1 day AND ts <= now() ORDER BY ts WITH FILL FROM now() - INTERVAL 1 day TO now() STEP INTERVAL 1 hour
Здесь выполняются те же самые операции, что и в первом запросе, но добавляется дополнительный фильтр в выражении HAVING
и выражении AND
. Этот фильтр ограничивает результаты только записями, у которых поле ts
находится в интервале от текущего времени минус 1 день до текущего времени. Таким образом, данный запрос дополнительно фильтрует записи по временному интервалу перед применением сортировки и заполнением пропущенных интервалов.
В результате выполнения этого запроса будет получен отсортированный список записей, где каждая запись будет содержать округленное значение timestamp
, сумму cnt
для соответствующей группы записей, а также пропущенные интервалы времени со значениями по умолчанию, если таковые имеются. В результирующем наборе будут только записи, удовлетворяющие условиям фильтрации по сумме cnt
и временному интервалу.
Работа с настраиваемыми полями универсальной модели
В RQL-запросах доступно обращение к регулярным настраиваемым полям универсальной модели события. Обращение к таким полям может осуществляться как напрямую (непосредственно к самим полям), так и посредством определенного синтаксиса.
Синтаксис
{custom_field}:{custom_field_label} {expression}
где:
-
{custom_field}
— ключ значения настраиваемого поля, например:cn1
,cs1
,deviceCustomDate1
,c6a1
.Вместо ключа конкретного поля можно использовать его семейство, зависящее от типа данных значения в этом поле:
-
cs
—LCString
; -
cn
—UInt64
; -
c6a
—IPv6
; -
deviceCustomDate
—DateTime
.
Семейство полей рекомендуется использовать в случаях, когда требуется проверять условие {expression}
по всем полям этого семейства. -
-
{custom_field_label}
— поле метаданных, хранящее метку, которая указывает на содержание и назначение связанного с ним поля{custom_field}
. Эта метка играет роль названия для поля{custom-field}
и позволяет интерпретировать хранящиеся в нем данные.Примеры меток:
-
cn1Label
— для поляcn1
; -
cs1Label
— для поляcs1
; -
deviceCustomDate1Label
— для поляdeviceCustomDate1
; -
c6a1Label
— для поляc6a1
.
-
-
{expression}
формулирует условие поиска по полю значения, используя операции сравнения (=
,!=
,<>
,<
,>
,<=
,>=
) и/или операторыIN
,LIKE
,NOT LIKE
.
|
Примеры обращения к настраиваемым полям
Пример обращения к полю напрямую
Допустим, имеется поток событий, у которых в поле cs1
хранится адрес электронной почты пользователя, совершившего подозрительное действие. Известно, что часть событий является тестовой и приходит от разных пользователей с одним и тем же электронным адресом test@example.com
.
Требуется исключить из рассматриваемого потока тестовые события. Ниже представлен вариант соответствующего RQL-запроса с непосредственным обращением к полю cs1
.
cs1 != "test@example.com"
Запрос выдаст события, поле cs1
которых не содержит значение test@example.com
.
Пример обращения к полю по его ключу
Допустим, имеется поток событий от разных источников. Для событий от некоторых источников в поле cs1
хранится адрес электронной почты пользователя, совершившего подозрительное действие. В соответствующем поле метки cs1Label
этих событий хранится значение email
. Известно, что часть событий от этих источников является тестовой и приходит от разных пользователей с одним и тем же электронным адресом test@example.com
.
Требуется получить поток событий, для которых указаны электронные адреса пользователей, и исключить из него тестовые события. Ниже представлен RQL-запрос, построенный на основе представленного ранее синтаксиса. Обращение к полю cs1
выполняется по его ключу.
cs1:email != "test@example.com"
Запрос выдаст события, для которых одновременно выполняются следующие условия:
-
Поле
cs1
не содержит значениеtest@example.com
. -
Поле
cs1Label
содержит названиеemail
.
Представленный запрос эквивалентен следующему запросу:
cs1 != "test@example.com" AND cs1Label = "email"
Пример обращения к полю по его семейству
Допустим, имеется поток событий из разных источников. Для событий некоторых источников в полях семейства cs
(например, cs1
, cs2
, cs3
) хранится адрес электронной почты пользователя, совершившего подозрительное действие. В соответствующих полях меток (например, cs1Label
, cs2Label
, cs3Label
) этих событий хранится значение email
. Известно, что часть событий от этих источников является тестовой и приходит от разных пользователей с одним и тем же электронным адресом test@example.com
.
Требуется получить поток событий, для которых указаны электронные адреса пользователей, и исключить из него тестовые события. Ниже представлен RQL-запрос, построенный на основе представленного ранее синтаксиса. Обращение к настраиваемым полям универсальной модели события выполняется по их семейству cs
.
cs:email != "test@example.com"
Запрос выдаст события, для которых одновременно выполняются следующие условия:
-
Ни одно из полей значений семейства
cs
не содержит значениеtest@example.com
. -
Поле метки, соответствующее полю значений семейства
cs
, содержит названиеemail
.
Представленный запрос эквивалентен следующему запросу:
(cs1 != "test@example.com" AND cs1Label = "email") OR (cs2 != "test@example.com" AND cs2Label = "email") OR (cs3 != "test@example.com" AND cs3Label = "email") OR (cs4 != "test@example.com" AND cs4Label = "email") OR (cs5 != "test@example.com" AND cs5Label = "email") OR (cs6 != "test@example.com" AND cs6Label = "email")
Использование фильтров и ограничений по времени
После выполнения запроса данных в таблице событий системы можно отфильтровать возвращенные результаты с помощью кнопки Добавить фильтр. В окне добавления фильтра указывается поле, по которому проводится фильтрация, оператор сравнения и значение для сравнения. Система воспринимает применяемый фильтр как дополнительный компонент в строке поискового запроса, которому предшествует оператор AND
.
Примеры использования
Пример 1
Вы ввели в строке поиска запрос tenantId like 'n%' AND length(raw) > 10
. Затем добавили фильтр по полю
originalTimestamp
c оператором =
и значением 05.05.2023б 05:00:00
. Последовательность этих действий равнозначна
следующему запросу в строке поиска:
tenantId like 'n%' AND length(raw) > 10 AND originalTimestamp = '2023.05.05 05:00:00'
Вместе с фильтрами удобно использовать функциональность ограничения запроса по времени. Ее применение аналогично добавлению к запросу компонента, помещающего результат запроса в указанные временные рамки.
Пример 2
Вы хотите ограничить результат запроса tenantId like 'n%' AND length(raw) > 10
датами 01.01.2023
и 12.12.2023
.
Для этого нужно после выполнения запроса выбрать значение Задать период в поле периода и указать диапазон периода в полях
справа. Эти действия аналогичны следующему запросу:
tenantId like 'n%' AND length(raw) > 10 AND (timestamp >= 2023.01.01 AND timestamp <= 2023.12.12)
Таким образом, применение фильтров и ограничений по времени существенно упрощает создание поисковых запросов в системе.
Работа с активными списками
В RQL-запросах для обогащения и фильтрации данных через активные списки используются операторы JOIN
и ENRICH
. Данный функционал доступен в двух разделах системы: Поиск и RQL-песочница, каждый из которых имеет свои особенности работы с оператором JOIN
.
-
В разделе Поиск для фильтрации записей по данным активных списков используется оператор
JOIN
, позволяя уточнить результаты запросов на основе совпадения данных без их обогащения. ОператорENRICH
, используется в комбинации сJOIN
и позволяет обогащать эти результаты данными из активных списков. Поддерживаются операцииINNER JOIN
иLEFT JOIN
. -
В разделе RQL-песочница для объединения данных из активных списков с событиями из хранилища с целью обогащения информации используется оператор
JOIN
. Поддерживаются операцииINNER JOIN
,LEFT JOIN
,RIGHT JOIN
иFULL JOIN
.
Работа в разделе Поиск
В разделе Поиск оператор JOIN
применяется для фильтрации записей с использованием данных из активных списков, что позволяет детализировать результаты запросов через анализ совпадений значений полей без обогащения событий. В контексте этого процесса, события хранилища и записи активных списков анализируются как данные, хранящиеся в двух разных таблицах: хранилище событий системы служит "левой таблицей", а активный список — "правой".
Применение оператора ENRICH в комбинации с оператором JOIN
в данном разделе расширяет возможности обработки данных, позволяя не только фильтровать события на основе совпадений в активных списках, но и обогащать их данными из этих списков. В комбинации с оператором JOIN
, оператор ENRICH
дает возможность заменять или добавлять значения в полях событий на основе данных из соответствующих записей активного списка.
Синтаксис соединений
(INNER | LEFT) JOIN `{active_list_name}` [AS alias_name] ON {expression}
ENRICH {target_field} = {source_field}
Здесь:
-
(INNER | LEFT)
указывает на тип операцииJOIN
:-
INNER JOIN
отбирает строки при наличии совпадения данных между обеими таблицами. -
LEFT JOIN
отображает все строки из левой таблицы (хранилище событий), дополняя их совпадающими данными из правой таблицы (активный список), если таковые имеются. Применяется совместно с операторомENRICH
.
-
-
`{active_list_name}`
обозначает имя активного списка, который используется в качестве правой таблицы для операцииJOIN
.Имя активного списка необходимо заключать в обратные апострофы. -
[AS alias_name]
предоставляет возможность задать псевдоним для активного списка, упрощая дальнейшее обращение к данным в запросе. -
{expression}
формулирует условие объединения, используя операции сравнения (=
,<>
,<
,>
,<=
,>=
) и логические операторы (AND
,OR
), для определения совпадений данных между таблицами.При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля в "левой" таблице (хранилище событий). Если поле в "левой" таблице не найдено, поиск поля продолжается в "правой" таблице (активный список).
Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
-
ENRICH {target_field} = {source_field}
описывает операцию обогащения, где:-
{target_field}
— целевое поле в записях событий, которое будет обогащено или заменено данными.Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
-
-
{source_field}
— исходное поле из записи активного списка, значение которого будет использовано для обогащения{target_field}
.Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
-
Применение ENRICH
в запросах позволяет дополнить данные событий новой информацией из активных списков, основываясь на результатах операции JOIN
.
Примеры использования
Пример 1. Использование INNER JOIN
для фильтрации событий
Оператор INNER JOIN
в разделе Поиск может быть использован для фильтрации записей, позволяя ограничить выборку событий на основе соответствия условиям, заданным для данных из активных списков. Этот механизм не обогащает данные событий новой информацией, но позволяет исключить из результата те события, которые не соответствуют заданным критериям.
Пример запроса ниже демонстрирует использование INNER JOIN
для фильтрации событий по списку угроз threat_list
, исключая из результатов все события, не соответствующие IP-адресам, занесенным в этот список. Цель запроса — идентифицировать потенциально вредоносную активность, происходящую с IP-адресов, указанных в списке угроз.
INNER JOIN `threat_list` ON sourceIp = `threat_list`.ip_address
Этот запрос исключит из результата все события, источник которых не совпадает с IP-адресами, указанными в активном списке threat_list
. Таким образом, анализ будет сосредоточен исключительно на событиях, источник которых был заранее классифицирован как потенциальная угроза. Поскольку объединение данных не происходит, в результатах запроса отображаются только поля исходных событий, соответствующих условиям фильтрации.
Пример 2. Использование INNER JOIN
с ENRICH
для обогащения событий
Применение запросов с INNER JOIN
и ENRICH
в разделе Поиск позволяет обогатить данные событий дополнительными данными из активных списков при условии точного совпадения между записями событий и данными активного списка. В отличие от LEFT JOIN
, INNER JOIN
выбирает только те записи, для которых существуют совпадающие данные в обеих таблицах, и далее ENRICH
используется для обогащения этих данных.
Этот метод подходит для сценариев, где необходимо ограничить анализ только событиями, имеющими прямое соответствие в активных списках, и одновременно обогатить эти события дополнительной информацией из этих списков. |
INNER JOIN `device_info` ON deviceId = `device_info`.device_id
ENRICH deviceType = `device_info`.type
В данном примере события объединяются с активным списком device_info
по условию совпадения deviceId
и device_id
. Используя оператор ENRICH
, информация о типе устройства (deviceType
) в записях событий обогащается на основе данных из поля type
активного списка device_info
. Это позволяет добавить к каждому событию точную классификацию устройства, основываясь на данных, предоставленных активным списком.
Пример 3. Использование LEFT JOIN
для обогащения событий
Применение запросов с LEFT JOIN
и ENRICH
в разделе Поиск позволяет обогащать записи событий из хранилища данными из активных списков. LEFT JOIN
используется для включения всех записей из "левой" таблицы (хранилище событий), дополнительно обогащая их информацией из "правой" таблицы (активный список), где имеется соответствие по заданному условию.
Оператор LEFT JOIN позволяет анализировать все события, даже если в активных списках нет соответствующей информации. Благодаря этому его удобно использовать в сценариях, где необходимо получить полный объем данных о событиях.
|
LEFT JOIN
используется для включения всех записей из "левой" таблицы (хранилище событий), дополнительно обогащая их информацией из "правой" таблицы (активный список) с помощью ENRICH
, где указывается соответствие по заданному условию.
LEFT JOIN `user_info` ON userId = `user_info`.user_id
ENRICH userAge = `user_info`.age
В данном примере события соединяются с активным списком user_info
по условию совпадения userId
с user_id
. Затем, используя оператор ENRICH
, значение поля userAge
в событии обогащается данными из поля age
активного списка user_info
для каждой записи, где найдено совпадение.
Работа в разделе RQL-песочница
В разделе RQL-песочница оператор JOIN
позволяет объединять данные из активных списков и хранилища событий, обогащая информацию о событиях. Поддерживаются операции INNER JOIN
, LEFT JOIN
, RIGHT JOIN
и FULL JOIN
, каждая из которых имеет свои особенности при объединении данных. В контексте этого процесса, события хранилища и записи активных списков анализируются как данные, хранящиеся в двух разных таблицах: хранилище событий системы служит "левой таблицей", а активный список — "правой".
Синтаксис
(INNER | LEFT | RIGHT | FULL) JOIN `{active_list_name}` [AS alias_name] ON {expression}
где:
-
(INNER | LEFT | RIGHT | FULL)
определяет тип операцииJOIN
, применяемой для объединения данных из левой таблицы (хранилища событий) и правой (активного списка):-
INNER JOIN
выбирает строки, где присутствует совпадение по заданным условиям в обеих таблицах. -
LEFT JOIN
отображает все строки из левой таблицы, дополняя их данными из правой таблицы при наличии совпадений. -
RIGHT JOIN
аналогиченLEFT JOIN
, но выводит все строки из правой таблицы, дополняя их данными из левой таблицы при наличии совпадений. -
FULL JOIN
объединяет методыLEFT JOIN
иRIGHT JOIN
, показывая все строки из обеих таблиц.
-
-
`{active_list_name}`
обозначает имя активного списка, который используется в качестве правой таблицы.Имя активного списка необходимо заключать в обратные апострофы. -
[AS alias_name]
позволяет назначить псевдоним активному списку, упрощая дальнейшую работу с запросом. -
{expression}
условие для объединения, которое может включать операции сравнения (=
,<>
,<
,>
,<=
,>=
) и логические операторы (AND
,OR
), для определения критериев совпадения данных между таблицами.При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля в "левой" таблице (хранилище событий). Если поле в "левой" таблице не найдено, поиск поля продолжается в "правой" таблице (активный список).
Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
Примеры использования
Пример 1. Использование INNER JOIN
Оператор INNER JOIN
может быть использован для объединения данных о событиях с активными списками, что позволит идентифицировать события, исходящие с IP-адресов, внесенных в список блокировки.
Пример запроса ниже демонстрирует использование INNER JOIN
для соединения данных событий с активным списком blacklist_ips
по IP-адресу источника (sourceIp
), с целью выявления событий с блокированными IP-адресами.
INNER JOIN `blacklist_ips` ON sourceIp = `blacklist_ips`.ip_address
Визуализация ожидаемого результата запроса:
event.sourceIp | event.timestamp | event.action | blacklist_ips.ip_address |
---|---|---|---|
192.0.2.1 |
2022-07-01T12:00:00Z |
Blocked |
192.0.2.1 |
192.0.2.2 |
2022-07-02T12:00:00Z |
Blocked |
192.0.2.2 |
В этой таблице отображаются события, произошедшие с IP-адресов, указанных в системе (event
), и соответствующие IP-адресам в активном списке blacklist_ips
. Используя INNER JOIN
, выборка ограничивается событиями, источники которых находятся в списке блокировки.
Пример 2. Использование LEFT JOIN
Оператор LEFT JOIN
может быть использован для объединения данных о событиях входа в систему с информацией о пользователях из активного списка. Это позволяет получить расширенный контекст активности пользователей, включая отсутствие событий для определенных пользователей. В случаях, когда соответствующая запись в активном списке отсутствует, результатом объединения для данной записи события будут значения NULL
в полях, предназначенных для данных из активного списка.
Пример запроса ниже демонстрирует использование LEFT JOIN
для соединения событий с записями активного списка о пользователях user_info
по идентификатору пользователя. Цель — включить в анализ всех пользователей, включая тех, по которым отсутствуют данные о событиях входа.
LEFT JOIN `user_info` ON userId = `user_info`.user_id
Визуализация ожидаемого результата запроса:
event.sourceIp | event.timestamp | user_info.ip_address | user_info.userName |
---|---|---|---|
192.0.2.1 |
2022-07-01T12:00:00Z |
192.0.2.1 |
Sergey |
192.0.2.2 |
2022-07-02T12:00:00Z |
192.0.2.2 |
John |
192.0.2.3 |
2022-07-03T12:00:00Z |
NULL |
NULL |
В этой таблице показаны все попытки входа пользователей, зафиксированные в системе (event
), дополненные информацией о них из активного списка user_info
. Последняя строка демонстрирует случай, когда в таблице событий имеются данные о входе с IP-адреса 192.0.2.3, но информация о пользователе, выполнившем вход, отсутствует в активном списке user_info
.
Пример 3. Использование RIGHT JOIN
Оператор RIGHT JOIN
может быть применен для объединения информации об устройствах из активного списка с данными о событиях, позволяя анализировать данные обо всех устройствах независимо от наличия связанных с ними событий. В случаях, когда соответствующая запись в хранилище отсутствует, результатом объединения для данной записи события будут значения NULL
в полях, предназначенных для данных из хранилища.
Пример запроса ниже демонстрирует использование RIGHT JOIN
для соединения информации об устройствах из активного списка device_info
с данными о событиях на основе совпадения серийных номеров устройств (serial_number
) с внешними идентификаторами устройств в событиях (deviceExternalId
). Цель — предоставить полный обзор по всем устройствам, включая те, по которым отсутствуют события.
RIGHT JOIN `device_info` ON deviceExternalId = `device_info`.serial_number
Визуализация ожидаемого результата запроса:
event.deviceExternalId | event.action | device_info.serial_number | device_info.device_name |
---|---|---|---|
12345 |
Alert |
12345 |
DeviceA |
NULL |
NULL |
67890 |
DeviceB |
В этой таблице отображается информация об устройствах из активного списка device_info
, дополненная данными о событиях из системы. Запись устройства DeviceB
демонстрирует случай, когда для устройства нет зарегистрированных событий.
Пример 4. Использование FULL JOIN
Оператор FULL JOIN
можно использовать для комплексного анализа данных, чтобы объединить информацию о событиях с данными из активных списков, не исключая записи без взаимных соответствий. Это обеспечивает возможность анализа, включая изучение как связанных, так и независимых данных событий и элементов активных списков.
Пример запроса ниже иллюстрирует использование FULL JOIN
для объединения данных о событиях с информацией из активного списка network_segments
на основе соответствия между IP-адресами устройств (deviceIp
) и сегментами сети (segment_ip
). Цель — предоставить полный обзор сетевой активности и конфигурации сети, включая события и сетевые сегменты, которые прямо не связаны.
FULL JOIN `network_segments` ON deviceIp = `network_segments`.segment_ip
Визуализация ожидаемого результата запроса:
event.deviceIp | event.action | network_segments.segment_ip | network_segments.segment_name |
---|---|---|---|
198.51.100.1 |
Access_Granted |
198.51.100.1 |
Office_Network |
NULL |
NULL |
198.51.100.1 |
Data_Center |
203.0.113.24 |
Unauthorized_Access |
NULL |
NULL |
В этой таблице представлена информация, объединяющая события сетевой активности и конфигурацию сетевых сегментов. Запись для сегмента Data_Center
показывает сетевой сегмент без зарегистрированных событий, тогда как запись для IP-адреса 203.0.113.24
демонстрирует событие, для которого нет соответствующего сегмента сети в активном списке.
Работа с оператором ENRICH
Оператор ENRICH
предназначен для обогащения данных событий в RQL-запросах значениями из активных списков. В сочетании с оператором JOIN
оператор ENRICH
позволяет заменять или добавлять значения в поля событий на основе совпадений данных с активными списками.
Оператор ENRICH
может быть использован в разделах Поиск и RQL-песочница.
Синтаксис
ENRICH {target_field} = {source_field}
где:
-
{target_field}
— целевое поле в записях событий, значение которого будет заменено, или к которому будет добавлено значение.Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
-
-
{source_field}
— исходное поле из активного списка, значение из которого используется для обогащения данных событий.Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
Применение ENRICH
в RQL-запросах
Оператор ENRICH
должен использоваться в сочетании с оператором JOIN
, формируя часть запроса, которая указывает на замену или добавление данных в записи событий на основе совпадения условий, заданных в операторе JOIN
. Применение ENRICH
возможно только после выполнения условия соединения, определенного в JOIN
.
JOIN `{active_list_name}` ON {join_condition}
ENRICH {target_field} = {source_field}
где:
-
`{active_list_name}`
— имя активного списка, данные из которого используются для обогащения.Имя активного списка необходимо заключать в обратные апострофы. -
{join_condition}
— условие соединения, определяющее правила поиска совпадений между данными событий и записями в активном списке.При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля в "левой" таблице (хранилище событий). Если поле в "левой" таблице не найдено, поиск поля продолжается в "правой" таблице (активный список).
Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
-
{target_field}
— поле в записях событий, для которого будет выполнено обогащение.Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
-
-
{source_field}
— поле в активном списке, значения из которого используются для обогащения данных событий.Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
Оператор ENRICH
позволяет обогащать данные событий из нескольких активных списков в рамках одного запроса. Для точного указания полей из конкретных активных списков следует использовать полное имя поля, включающее имя активного списка и имя поля, разделенные точкой.
Примеры использования ENRICH
Пример 1. Обогащение данных события значениями из одного активного списка
LEFT JOIN `active_list` ON raw = `active_list`.name
ENRICH id = `active_list`.age
В данном примере запрос обогащает значение поля id
в записях событий значением поля age
из активного списка active_list
, если значение поля raw
события совпадает с полем name
в активном списке.
Пример 2. Обращение к нескольким активным спискам
SELECT id
LEFT JOIN `admin_list` ON userId = `admin_list`.user_id
LEFT JOIN `security_events` ON eventCode = `security_events`.code
ENRICH adminName = `admin_list`.name, securityLevel = `security_events`.level
В данном примере запрос обогащает данные событий, используя информацию из двух разных активных списков — admin_list
и security_events
. Оператор ENRICH
применяется для замены (или добавления, если такого поля нет) в записях событий: значения поля adminName
на основании данных об имени администратора из списка admin_list
и значения поля securityLevel
на основании уровня безопасности из списка security_events
. Оба обогащения основываются на совпадении условий: userId
с user_id
для списка администраторов и eventCode
с code
для событий.
Создание запросов в дашбордах
При вводе поисковых запросов в поле Запрос в виджетах и метриках, создаваемых в дашбордах, активно используются проекции различных колонок таблицы событий. Проекции при перечислении в запросе разделяются запятой.
Не ставьте разделитель после последней проекции, включенной в запрос. |
Стандартный запрос | Запрос в системе |
---|---|
SELECT tenantId, raw FROM table |
SELECT tenantId, raw |
SELECT tenantId, raw FROM table WHERE length(tenantId) = 5 |
SELECT tenantId, raw WHERE length(tenantId) = 5 |
Также используются псевдонимы, позволяющие сократить названия используемых компонентов запроса в разделе Сопоставление полей при редактировании виджетов и метрик.
Пример
При редактировании виджета типа Таблица вводится запрос:
SELECT collectorId, count(*) AS cnt WHERE collectorId like '%' GROUP BY collectorId
Здесь для функции count(*) задается псевдоним cnt
.
Когда вам необходимо указать эту функцию в разделе сопоставления полей, можно использовать ее псевдоним — cnt
.