В предыдущей статье мы рассмотрели обнаружение аномалий с помощью правила 3 сигм в Influx. Теперь сделаем то же самое в Grafana + Prometheus.

Краткое напоминание: правило 3 сигм

Правило трех сигм утверждает, что приблизительно все наши «нормальные» данные должны находиться в пределах трех стандартных отклонений (σ) от среднего значения (μ) ваших данных. В этой статье исследуется, как мы можем измерять стандартные отклонения от среднего значения и настраивать оповещения, когда это значение превышает 3.0 (другими словами, когда наш Z-показатель превышает 3.0), используя Grafana в сочетании с Prometheus.

  1. Рассчитаем Z-показатель: (x - μ) / σ
  2. Настроим алертинг при Z > 3.0

Формула Z-показателя

Итак, нам необходимо запросить в Grafana три параметра:

  1. Точку данных для описания интервала диапазона (x)
  2. Среднее значение наших данных за более длительный период времени (μ)
  3. Стандартное отклонение за тот же (более длительный) период времени (σ)

Для целей обсуждения давайте сосредоточимся на метрике «node_disk_writes_completed_total». Среднее значение и стандартное отклонение очень легко извлечь с помощью встроенных функций в Prometheus:

Среднее значение за период времени (avg_over_time(range-vector)):

avg_over_time(node_disk_writes_completed_total{instance="$node",job="$job",device=~"$diskdevices"}[1d]))

Стандартное отклонение за период времени (stddev_over_time(range-vector)):

stddev_over_time(node_disk_writes_completed_total{instance="$node",job="$job",device=~"$diskdevices"}[1d])

Приведенные выше два выражения дадут нам среднее значение и стандартное отклонение, рассчитанные за один день – отсюда и переменная диапазона [1d].

Последний элемент головоломки – это получение точки данных… «x» в нашей формуле выше. Я решил эту задачу, просто взяв еще одно среднее значение за период времени, но для интервала диапазона, равного переменной дашборда, а не фиксированного значения в 1 день, как выше:

avg_over_time(node_disk_writes_completed_total{instance="$node",job="$job",device=~"$diskdevices"}[$__rate_interval]

Обратите внимание на использование [$__rate_interval] выше: https://grafana.com/docs/grafana/latest/datasources/prometheus/#using-__rate_interval

Собираем все вместе

Реализуя нашу формулу, мы получаем следующий запрос:

(avg_over_time(node_disk_writes_completed_total{instance="$node",job="$job",device=~"$diskdevices"}[$__rate_interval])-avg_over_time(node_disk_writes_completed_total{instance="$node",job="$job",device=~"$diskdevices"}[1d]))/stddev_over_time(node_disk_writes_completed_total{instance="$node",job="$job",device=~"$diskdevices"}[1d])

Результаты

Приведенные выше запросы были выполнены для источника данных, график которого выглядел следующим образом:

График с большим выбросом справа

Обратите внимание на большой выброс справа – мы хотели бы получать оповещения о таком большом выбросе, но не обязательно о меньших выбросах слева. Вот что дает нам проверка на аномалии:

График Z-показателя с порогом

Если установить порог >= 3, то меньшие выбросы не вызовут оповещения, а наш большой выброс – вызовет, поскольку он является значительным.

Другой пример – следующий временной ряд:

График с множеством выбросов

Данный временной ряд имеет гораздо больше выбросов (в терминах сигналов ряд является более «зашумленным»), поэтому мы не хотели бы использовать статический порог, который срабатывает на каждый выброс, а только на выбросы, выходящие за пределы нормы. Применяя наш запрос на аномалии, мы получаем:

График Z-показателя для зашумленных данных

Обратите внимание, как результаты приближаются к Z-показателю 2.5, но никогда не превышают наш порог в 3, автоматически учитывая тот факт, что сигнал более зашумлен. Еще один интересный момент заключается в том, что запрос на аномалии автоматически обрабатывает два различных сценария, как показано ниже:

Сравнение двух сценариев

Оригинал: Grafana Prometheus: Detecting anomalies in time series

Похожие записи