API-query
API-query — механизм выполнения запросов ко внутреннему хранилищу данных Smart Monitor, работающий на основе Domain-Specific Language (DSL) и позволяющий получать, фильтровать и агрегировать данные в виде документов Smart Monitor Data Storage.
Функционал API-query может быть использован разными способами, например через curl запросы или из интерфейса Smart Monitor в Консоль разработчика (Навигационное меню - Параметры системы - Консоль разработчика). В данной статье в качестве примеров приводится последний вариант.
Структура query
Запросы в API-query строятся по единой структуре, включающей в себя следующие атрибуты:
query— основной раздел поискового запроса, определяющий условия выборки документовТип запроса— указывает формат поиска, например: match, term, range, bool и другие операторы DSLПоле— имя поля документа, по которому выполняется запросПоисковое значение— обрабатываемое в запросе значениеЛогика комбинирования— дополнительные конструкции, например must и must_not, использующиеся для составления условий логики запросаПараметры точности— настройки соответствия, такие как fuzziness, operator или boost, уточняющие поведение поиска
Запрос может быть дополнен уточняющими параметрами для обрабатываемых данных, такими как, например, size или from.
Ниже приведен основной шаблон, который используется в большинстве случаев:
GET <index>/_search
{
"query": {
"<тип_запроса>": {
"<поле>": "<значение>"
}
},
"size": <количество_документов>,
"from": <смещение_для_пагинации>
}
Пример запроса:
GET test_node_stats/_search
{
"query": {
"term": {
"event_type": "alert"
}
},
"size": 2
}
Пример вывода
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 0.24116206,
"hits": [
{
"_index": "test_node_stats",
"_id": "1",
"_score": 0.24116206,
"_source": {
"event_type": "alert",
"severity": "high",
"host": "sm-node-01",
"timestamp": "2025-12-01T10:00:00Z",
"message": "CPU usage is above threshold"
}
},
{
"_index": "test_node_stats",
"_id": "2",
"_score": 0.24116206,
"_source": {
"event_type": "alert",
"severity": "medium",
"host": "sm-node-02",
"timestamp": "2025-12-01T10:05:00Z",
"message": "Memory usage warning"
}
}
]
}
}
Распространенные сценарии использования
Фильтрация по нескольким условиям (bool-запрос):
GET test_node_stats/_search
{
"query": {
"bool": {
"must": [
{ "term": { "event_type": "alert" } },
{ "term": { "severity": "high" } }
]
}
}
}
Пример вывода
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.2707815,
"hits": [
{
"_index": "test_node_stats",
"_id": "1",
"_score": 1.2707815,
"_source": {
"event_type": "alert",
"severity": "high",
"host": "sm-node-01",
"timestamp": "2025-12-01T10:00:00Z",
"message": "CPU usage is above threshold"
}
},
{
"_index": "test_node_stats",
"_id": "3",
"_score": 1.2707815,
"_source": {
"event_type": "alert",
"severity": "high",
"host": "sm-node-03",
"timestamp": "2025-12-01T10:10:00Z",
"message": "Disk space is low"
}
}
]
}
}
Агрегация данных:
GET test_node_stats/_search
{
"size": 0,
"aggs": {
"by_severity": {
"terms": {
"field": "severity"
}
}
}
}
Пример вывода
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 6,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"by_severity": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "high",
"doc_count": 2
},
{
"key": "low",
"doc_count": 2
},
{
"key": "critical",
"doc_count": 1
},
{
"key": "medium",
"doc_count": 1
}
]
}
}
}
Агрегация с фильтрацией по времени:
GET test_node_stats/_search
{
"size": 0,
"query": {
"range": {
"timestamp": {
"gte": "2025-12-01T00:00:00Z",
"lte": "2025-12-01T23:59:59Z"
}
}
},
"aggs": {
"alerts_count": {
"terms": {
"field": "event_type"
}
}
}
}
Пример вывода
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 6,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"alerts_count": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "alert",
"doc_count": 5
},
{
"key": "metric",
"doc_count": 1
}
]
}
}
}
Пагинация
Параметры size и from, упомянутые в основном шаблоне запроса, используются для постраничного получения данных.
size— количество документов на страницеfrom— количество документов, которые нужно пропустить перед выдачей результата
Пример первой страницы:
GET test_node_stats/_search
{
"query": {
"term": {
"event_type": "alert"
}
},
"size": 2,
"from": 0
}
Пример вывода
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 0.24116206,
"hits": [
{
"_index": "test_node_stats",
"_id": "1",
"_score": 0.24116206,
"_source": {
"event_type": "alert",
"severity": "high",
"host": "sm-node-01",
"timestamp": "2025-12-01T10:00:00Z",
"message": "CPU usage is above threshold"
}
},
{
"_index": "test_node_stats",
"_id": "2",
"_score": 0.24116206,
"_source": {
"event_type": "alert",
"severity": "medium",
"host": "sm-node-02",
"timestamp": "2025-12-01T10:05:00Z",
"message": "Memory usage warning"
}
}
]
}
}
Пример второй страницы:
GET test_node_stats/_search
{
"query": {
"term": {
"event_type": "alert"
}
},
"size": 2,
"from": 2
}
Пример вывода
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": 0.24116206,
"hits": [
{
"_index": "test_node_stats",
"_id": "3",
"_score": 0.24116206,
"_source": {
"event_type": "alert",
"severity": "high",
"host": "sm-node-03",
"timestamp": "2025-12-01T10:10:00Z",
"message": "Disk space is low"
}
},
{
"_index": "test_node_stats",
"_id": "5",
"_score": 0.24116206,
"_source": {
"event_type": "alert",
"severity": "low",
"host": "sm-node-04",
"timestamp": "2025-12-01T10:20:00Z",
"message": "Service response time increased"
}
}
]
}
}
Чтобы результаты на разных страницах не меняли порядок между запросами, рекомендуется задавать сортировку:
GET test_node_stats/_search
{
"query": {
"term": {
"event_type": "alert"
}
},
"sort": [
{ "timestamp": { "order": "asc" } }
],
"size": 2,
"from": 2
}
Пример вывода
{
"took": 9,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "test_node_stats",
"_id": "3",
"_score": null,
"_source": {
"event_type": "alert",
"severity": "high",
"host": "sm-node-03",
"timestamp": "2025-12-01T10:10:00Z",
"message": "Disk space is low"
},
"sort": [
1764583800000
]
},
{
"_index": "test_node_stats",
"_id": "5",
"_score": null,
"_source": {
"event_type": "alert",
"severity": "low",
"host": "sm-node-04",
"timestamp": "2025-12-01T10:20:00Z",
"message": "Service response time increased"
},
"sort": [
1764584400000
]
}
]
}
}