[Документация Yandex Cloud](../../index.md) > [Monium](../index.md) > Логи > Вычисление метрик по логам

# Вычисление метрик по логам {#aggregates}

{% note info %}

Функциональность метрик по логам находится на стадии [Preview](../../overview/concepts/launch-stages.md).

{% endnote %}

_Метрика по логам_ — непрерывное вычисление статистики по данным из логов для создания метрик в Monium.

Примеры метрик, которые можно вычислять по логам:

* Количество логов с сообщением об ошибке в поле `message`.
* Количество уникальных пользователей, получивших ошибку, с группировкой по методу API.
* Максимальное время выполнения запроса.

## Начало работы с метриками по логам {#quick-start}

Адрес для записи логов через API: `ingest.monium.yacloudkz.tech:443`.

{% list tabs group=instructions %}

- Интерфейс Monium {#console}

  Чтобы создать метрику по логам:

  1. На главной странице [Monium](https://kz.monium.yandex.cloud) слева выберите один из разделов:
     * ![alt](../../_assets/console-icons/compass.svg) **Обзор** → **Логи**. Нажмите кнопку **Метрики по логам**.
     * ![alt](../../_assets/console-icons/box.svg) **Поставка и хранение** → **Метрики по логам**.
  1. Справа вверху нажмите **Создать**.
  1. (Опционально) Введите название метрики.
  1. Введите **ID** метрики — значение имени метрики. Обычно это `name`, но может использоваться и другая метка, например `sensor` или `signal`. Это имя задается в настройках шарда. Подробнее в разделе [Язык запросов в Monium](../concepts/querying.md).
  1. В блоке **Селектор логов** введите запрос, выбирая метки из списка или в текстовом режиме. Запрос определяет, какие строки логов участвуют в вычислении метрики.
  1. В блоке **Правило вычисления** укажите:
     * **Функция агрегации** — `count`, `sum`, `min`, `max`, `avg`, `unique` или `uniqueNewfound`.
     * **Окно вычисления** — `1 минута` или `5 минут`.
  1. Если нужно разбить метрику по значениям атрибута, в блоке **Группировать по** введите имя атрибута.
  1. В блоке **Итоговая метрика** проверьте автоматически сформированный запрос и при необходимости уточните значения меток `cluster` и `service`.
  1. Нажмите **Создать**.

  Чтобы создать метрику по уже построенному графику логов:

  1. На главной странице [Monium](https://kz.monium.yandex.cloud) слева выберите **Обзор** → **Логи**.
  1. Введите запрос и нажмите **Выполнить запрос**.
  1. На вкладке **Статистика** рядом с графиком нажмите **Создать метрику**.
  1. Укажите параметры метрики и при необходимости уточните запрос.
  1. Нажмите **Создать**.

{% endlist %}

## Примеры метрик по логам {#quick-examples}

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

### Количество событий {#example-count}

Вычисление частоты запросов к API:

* **Селектор логов**: `{project = "logging", service = "query", cluster = "production", message = "*started"}`
* **Функция агрегации**: `count`
* **Атрибут для агрегации**: —
* **Группировать по**: —
* **Окно вычисления**: `1 минута`
* **Итоговая метрика**: `{project=logging, cluster=production, service=logging_aggregates, name=query_got_reqs_1m}`


### Объем прочитанных логов в байтах {#example-bytes}

Сколько байт за пять минут прочитал сервис в ответ на запросы пользователей:

* **Селектор логов**: `{project='logging', service='query', cluster='production', meta.ch.profile.bytes='*'}`
* **Функция агрегации**: `sum`
* **Атрибут для агрегации**: `meta.ch.profile.bytes`
* **Группировать по**: —
* **Окно вычисления**: `5 минут`
* **Итоговая метрика**: `{project=logging, cluster=production, service=logging_aggregates, name=query_bytes_read_5m}`

### Количество уникальных пользователей в разбивке по методу API {#example-unique-users}

Сколько уникальных пользователей обратилось к отдельным методам API за одну минуту:

* **Селектор логов**: `{project='logging', service='query', cluster='production', origin.login='*', func='AutocompleteKeys|AutocompleteValues|SearchLogs'}`
* **Функция агрегации**: `unique`
* **Атрибут для агрегации**: `origin.login`
* **Группировать по**: `func`
* **Окно вычисления**: `1 минута`
* **Итоговая метрика**: `{project=logging, cluster=production, service=logging_aggregates, name=query_unique_users_by_func_1m}`

## Принцип работы {#how-it-works}

### Параметры метрик по логам {#rules}

* **Селектор логов** — какие логи попадут в выборку.
* **Функция агрегации** — функция, с помощью которой вычисляется значение метрики: `count`, `min`, `max`, `avg`, `sum`, `unique`, `uniqueNewfound`.
* **Атрибут для агрегации** — для `min`, `max`, `avg`, `sum`, `unique`, `uniqueNewfound`: имя атрибута, значение которого используется как аргумент функции.
* **Группировать по** — по какому атрибуту создавать отдельные агрегаты для каждого значения.
* **Окно вычисления** — временной диапазон для вычисления функции агрегации. Поддерживаются диапазоны: `1 минута` и `5 минут`.
* **Итоговая метрика** — с каким селектором записать метрику в Monium.

### Селектор логов (запрос) {#selector}

_Селектор логов_ — это фильтр на [языке запросов](../concepts/querying.md), который определяет, какие строки логов участвуют в вычислении метрик. Для создания метрик в селектор добавляют метки окружения (`project`, `cluster` и `service`) и метки из строки логов: уровень логирования, текст сообщения, значение `meta.*` и другие атрибуты.

Метки окружения:

* `project = <идентификатор_проекта>` — выберите проект, заданный в параметре `x-monium-project` в конфигурации передачи телеметрии приложения.

    Это может быть проект облака (`cloud__<идентификатор_облака>`), каталога (`folder__<идентификатор_каталога>`) или другой [проект](../collector/project.md#project-create).
* `cluster = <имя_кластера>` — выберите имя инсталляции, в которой запущено ваше приложение. Если кластер не задан, то по умолчанию `cluster = default`.
* `service = <имя_сервиса>` — имя вашего приложения или сервиса. Может передаваться в переменной окружения `OTEL_SERVICE_NAME`.

  Если нужных меток нет в подсказках, их можно ввести вручную. Но, скорее всего, в систему не поступали данные с такими метками. Решение возможных проблем описано в разделе [Устранение неполадок при поставке данных](../collector/troubleshooting.md).

{% note info %}

Значение `project` должно совпадать с проектом, в котором создается метрика. Метрика в проекте `my_shop` может обрабатывать только логи из `project=my_shop`.

{% endnote %}

Примеры селекторов:

```
{project='my_project', service='metabase', level >= 'ERROR', message='*LEAK*', logger='io.netty.util.ResourceLeakDetector'}
{project='my_project', service='journald', cluster='production', meta.systemd_unit='alerting.service', message=*'terminating on uncaught exception;'}
{project='ci', service='api', cluster='stable', message=*'vtail.api.query.Query/SearchLogsStreaming', message=*'DEADLINE_EXCEEDED'}
{project='my_agent', service='telemetry'}
```

### Функция агрегации {#aggregation-function}

После выборки логов по селектору из них вычисляется числовое значение:

#|
|| **Функция** | **Нужен атрибут** | **Описание** | **Пример** ||
|| `count` | Нет | Количество строк в выборке | Количество логов с ошибкой в коде (например, когда `message` содержит `panic`) ||
|| `min` | Да | Минимальное значение атрибута | Минимальное значение `meta.cpu_limit` ||
|| `max` | Да | Максимальное значение атрибута | Максимальное значение `meta.memory_usage` ||
|| `avg` | Да | Среднее значение атрибута | Среднее значение `meta.event_duration` ||
|| `sum` | Да | Сумма значений атрибута | Сумма `meta.bytes_read` ||
|| `unique` | Да | Количество уникальных значений атрибута | Количество уникальных значений `meta.user_id` ||
|| `uniqueNewfound` | Да | Количество новых уникальных значений атрибута по сравнению с предыдущими 48 часами | Количество новых сообщений об ошибках (`message`), не встречавшихся за предыдущие 48 часов ||
|#

Для функций `min`, `max`, `avg` и `sum` значение атрибута автоматически приводится к [числу с плавающей точкой](https://en.wikipedia.org/wiki/Double-precision_floating-point_format). Максимальная поддерживаемая [точность](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Precision_limitations_on_integer_values) для целочисленных значений — `2^53`.

### Группировка {#group-by}

Дополнительно можно указать атрибут для группировки. По его значениям будут создаваться отдельные метрики. Например, если для группировки указать атрибут `api_method`, у которого в логах встречаются значения `Export`, `Update`, `Delete`, будет создана не одна, а три метрики:

* `api_method=Export`;
* `api_method=Update`;
* `api_method=Delete`.

Атрибут группировки автоматически добавляется в [селектор метрики](#metrics-selector). Указывать его отдельно в итоговой метрике не обязательно.

### Окно вычисления (агрегации) {#aggregation-window}

Логи для вычисления выбираются за фиксированное временное окно: **1 минута** или **5 минут**.

Например, при подсчете количества строк за каждую минуту:

#|
|| **Временная метка (ts)** | **Значение** | **Описание** ||
|| 2025-03-20 11:03:00 | 193 | Строки логов за `[11:03:00; 11:04:00)` ||
|| 2025-03-20 11:04:00 | 371 | Строки логов за `[11:04:00; 11:05:00)` ||
|| 2025-03-20 11:05:00 | 237 | Строки логов за `[11:05:00; 11:06:00)` ||
|#

### Итоговая метрика (селектор метрики) {#metrics-selector}

В селекторе должны быть обязательные метки: `project`, `cluster`, `service` и `ID` метрики — метка, которая обозначает имя метрики в проекте или указанном шарде. Обычно это `name`, но может использоваться `sensor`, `signal` или другое произвольное имя метки. Подробнее в разделе [Язык запросов в Monium](../concepts/querying.md). Например:

`{project='shop', cluster='production', service='logging_aggregates', name='unique_users_5m'}`

Если указан атрибут для группировки, он автоматически добавляется в метрику. Например, при селекторе метрики `{project='logging', cluster='production', service='logging_aggregates', name='api_errors'}` и атрибуте группировки `api_method` будут созданы метрики:

#|
|| **Временная метка (ts)** | **Метки** | **Значение** ||
|| 2025-02-13 17:03:00 | `{..., name='api_errors', api_method=Export}` | 100 ||
|| 2025-02-13 17:03:00 | `{..., name='api_errors', api_method=ListEntries}` | 4 ||
|| 2025-02-13 17:03:00 | `{..., name='api_errors', api_method=Delete}` | 82 ||
|| ... | ... | ... ||
|#

Значения атрибута из группировки можно использовать в подстановках. Например, если в группировке используется `api_method`, в селекторе метрики можно указать:

`{project='logging', cluster='production', service='logging_aggregates', endpoint=grpc.not_var{{api_method}}, name='api_errors'}`

В результате метка `api_method` не добавляется автоматически, а значение подставляется в метку `endpoint`:

#|
|| **Временная метка (ts)** | **Метки** | **Значение** ||
|| 2025-02-13 17:03:00 | `{..., name='api_errors', endpoint=grpc.Export}` | 100 ||
|| 2025-02-13 17:03:00 | `{..., name='api_errors', endpoint=grpc.ListEntries}` | 4 ||
|| 2025-02-13 17:03:00 | `{..., name='api_errors', endpoint=grpc.Delete}` | 82 ||
|| ... | ... | ... ||
|#

### Сценарии группировок и подстановок {#groupby-scenarios}

#### Автоматическая подстановка значений из группировки {#auto-substitution}

При группировке по атрибуту `origin.login` и селектору метрики

`{project=logging, service=logs_to_metrics, cluster=production, name=reqs_by_login}`

в селектор метрики автоматически добавится метка:

`{project=logging, service=logs_to_metrics, cluster=production, name=reqs_by_login, origin.login=not_var{{origin.login}}`

Если в строке лога встретится `origin.login=ivan_petrov`, метрика будет записана по меткам:

`{project=logging, service=logs_to_metrics, cluster=production, name=reqs_by_login, origin.login=ivan_petrov}`

#### Автоматическая подстановка нескольких значений {#auto-substitution-multiple}

При группировке по нескольким атрибутам (`host`, `component`) они автоматически добавляются в метрику:

`{project=logging, service=logs_to_metrics, cluster=production, name=cnt, host='not_var{{host}}', component='not_var{{component}}'}`

#### Ручная настройка подстановки {#explicit-substitution}

Помимо автоматической подстановки, подстановку можно задать вручную. Следующие селекторы метрик дают одинаковый результат:

* **Селектор логов**: `{project=logging, service=query, cluster=production, host=*}`
* **Функция агрегации**: `count`
* **Группировать по**: `host`
* **Итоговая метрика 1**: `{project=logging, service=logs_to_metrics, cluster=production, name=cnt}`
* **Итоговая метрика 2**: `{project=logging, service=logs_to_metrics, cluster=production, name=cnt, host='not_var{{host}}'}`

В таких подстановках можно изменять и ключ, и значение. Например:

`{project=logging, service=logs_to_metrics, cluster=production, name=errors, host='query-not_var{{host}}', context='query_not_var{{host}}_not_var{{component}}_production'}`


#### Группировка по кластеру {#group-by-cluster}

Группировка по `cluster` поддерживается в нескольких вариантах:

Вариант 1 — кластер как значение метки `cluster`:

* **Селектор логов**: `{project=logging, service=query}`
* **Функция агрегации**: `count`
* **Группировать по**: `cluster`
* **Итоговая метрика**: `{project=logging, service=logs_to_metrics, cluster='not_var{{cluster}}', name=cnt}`

Вариант 2 — кластер как значение пользовательской метки `user_cluster`:

* **Селектор логов**: `{project=logging, service=query}`
* **Функция агрегации**: `count`
* **Группировать по**: `cluster`
* **Итоговая метрика**: `{project=logging, service=logs_to_metrics, cluster=production, name=cnt, user_cluster='not_var{{cluster}}'}`

#### Группировка по сервису {#group-by-service}

Группировка по `service` поддерживается только при явном перечислении значений:

* **Селектор логов**: `{project=logging, service=query|collector}`
* **Функция агрегации**: `count`
* **Группировать по**: `service`
* **Итоговая метрика**: `{project=logging, service='not_var{{service}}', cluster=production, name=cnt}`

## Квоты и лимиты {#quota}

На каждый проект выделены определенные ресурсы CPU и RAM для вычисления метрик по логам. Максимальное количество метрик в проекте — 1000.

Чтобы увеличить квоту, обратитесь в [службу поддержки](https://kz.center.yandex.cloud/support).

### Как снизить потребление ресурсов {#usage-optimizations}

* Используйте точные значения в селекторах. Избегайте регулярных выражений и wildcard-выражений — они увеличивают нагрузку на CPU.
 
  Не рекомендуется:
  ```
  {..., api_endpoint="*Export*", ...}
  ```

  Рекомендуется:
  ```
  {..., api_endpoint="/api/v1/Export", ...}
  ```

* Переносите «дорогие» сравнения в конец селектора. Если wildcard-выражений не избежать, ставьте их после точных условий.

  Не рекомендуется:
  ```
  {..., message = "*panic*", error_code="500", ...}
  ```

  Рекомендуется:
  ```
  {..., error_code="500", message = "*panic*"}
  ```

  Так большая часть логов отсеется на этапе проверки атрибута `error_code`.

* Чтобы снизить потребление RAM, установите окно агрегации — `5 минут`.

## Особенности вычисления {#guarantees}

* Значение метрики по логам появляется с задержкой, которая зависит от размера окна агрегации. Максимальная задержка — `3 минуты` после завершения окна. Например, для окна `1m` значение за интервал `17:07:00`–`17:08:00` будет доступно не позднее `17:11:00`.
* Значения, полученные по сырым логам и по метрикам на основе логов, могут временно отличаться. Например, поиск логов может вернуть `X` строк по селектору, а метрика `count` по тому же селектору — значение `Y`.
* Функция `unique` возвращает приблизительное количество уникальных элементов. Подробнее — [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog).
* Повторно отправленные строки логов учитываются повторно, дедупликация не выполняется.
* Числовые значения атрибутов приводятся к [числам с плавающей точкой](https://en.wikipedia.org/wiki/Double-precision_floating-point_format). Максимальная поддерживаемая [точность](https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Precision_limitations_on_integer_values) для целочисленных значений — `2^53`.

### Исчерпание квоты {#guarantees-quota-overflow}

При превышении квоты на вычисление метрик по логам:

* логи продолжают записываться;
* значения метрик могут быть неполными;
* новые метрики могут создаваться, если для метрики по логам настроена [группировка](#group-by).

### Запись в прошлое {#backfill}

Значение метрики может быть пересчитано для логов, записанных за **30 минут** в прошлое.

Рассмотрим пример со следующими условиями:

* Настроена метрика по логам, считающая каждую минуту `count` для `{project, cluster, service, message=*'failed'}`.
* Текущее время — `17:29:17`.

При поступлении в Monium двух строк лога выполняются действия:

#|
|| **Временная метка (ts)** | **Лог** | **Что произойдет с метрикой** ||
|| 16:59:00 | `message=failed to exec request ...` | Лог записан, значение за эту минуту не пересчитается ||
|| 17:00:00 | `message=failed to load data from ...` | Лог записан, значение за 17:00:00 будет пересчитано ||
|#

## Особенности отображения метрик {#display}

{% note info %}

Рекомендуем отображать метрики по логам в виде [столбцов](../metrics/metric-explorer.md#set-graph). Это показывает, что каждая точка — это агрегированное значение за временной промежуток, а не значение в моменте.

{% endnote %}

* Все метрики записываются с типом [DGAUGE](../concepts/data-model.md#metric-types).
* Каждая точка на графике показывает значение за окно агрегации, а не в секунду. Например, если метрика считает количество запросов к API за минуту, точка показывает количество запросов **за минуту**.
* Если в течение окна агрегации не поступали логи, попадающие в выборку, значение за это окно не отправляется — на графике будет пропуск.
* При [прореживании метрик](../metrics/metric-explorer.md#set-graph) указывайте интервал, равный окну агрегации: `1 минута` или `5 минут`.
* Метрики по логам с функциями `unique`, `uniqueNewfound` и `avg` несовместимы с прореживанием — отключайте его при просмотре больших временных диапазонов.
* Точки метрики за последние 30 минут могут быть пересчитаны и повторно отправлены в Monium. Если в шарде настроена агрегация по метрикам, это может привести к некорректному отображению значений.

### Прореживание и совместимость с функциями агрегации {#downsampling}

{% note info %}

При просмотре метрик укажите интервал прореживания, равный окну вычисления: `1 минута` или `5 минут`.

{% endnote %}

При просмотре метрик на большом временном отрезке в Monium включается [прореживание](../concepts/decimation.md) — из нескольких точек вычисляется одна с помощью функции агрегации. Например, если метрика по логам считается раз в минуту, а график строится за сутки, каждая точка будет средним значением набора точек.

Рекомендации по настройке прореживания для разных функций:

#|
|| **Функция агрегации** | **Рекомендация** ||
|| `min` | В [настройках графика](../metrics/metric-explorer.md#set-graph) в разделе прореживания выберите функцию агрегации `min` ||
|| `max` | Выберите функцию агрегации `max` ||
|| `sum` | Выберите функцию агрегации `sum` ||
|| `count` | Выберите функцию агрегации `sum` или `avg` в зависимости от вида метрики (счетчик или rate) ||
|| `avg`, `unique`, `uniqueNewfound` | Прореживание не поддерживается. Корректные значения доступны только для отдельных точек до выполнения прореживания ||
|#

Функции `avg`, `unique` и `uniqueNewfound` несовместимы с агрегацией в метриках Monium. Например, для `unique`:

* раз в минуту к API поочередно приходят два пользователя — `user1` и `user2`;
* метрика по логам с функцией `unique` раз в минуту записывает значение `1`;
* при просмотре на масштабе суток ни одна функция прореживания не вернет верное значение:
  * `sum` посчитает `60`;
  * `min` и `max` посчитают `1`;
  * `avg` посчитает `1`;
  * верный ответ — `2`, потому что за час было два уникальных пользователя.