Среди прочих алертов у нас есть алерты на падение сервиса — когда метрика *_up == 0.
Проблема в том, что такой алерт сработает только в том случае, если екпортёр сервиса явно вернёт значение ноль, но если ЕС2 с сервисом и екпортёром был выключен/удалён — то Alertmanager ничего не сообщит.
Например — алерт на RDS выглядит так:
...
- name: MySQL.rules
rules:
- alert: DatabaseServerDown
expr: mysql_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: 'Database server down!'
description: '{{$labels.env}}:{{$labels.job}} Status DOWN!'
...
Значение mysql_up сейчас:
Для того, что бы проверять наличие метрик от экпортёра можно использовать либо absent(), либо avg_over_time().
Функция absent() вроде как предназначена как раз для таких целей, но с ней проблема в том, что при срабатывании алерт с ней не будет иметь никаких лейблов, т.к. сама метрика отсутствует.
Потому — удобнее использовать avg_over_time(), к оторой проверим среднее значение за промежуток времени.
В avg_over_time() будем проверять значение up (или mysql_up, если хотим проверять только метрики mysql_exporter), которая возвращает 1 для любого екпортёра, если метрики с него получены, и зададим интервал в 2 минуты, за которые будем проверять среднее значение.
Если оно упадёт ниже единицы — значит метрики с екпортёра не собираются, и можно создавать алерт.
Добавляем правило:
...
- alert: ExporterMetricsAlarmAvgTimeTest
expr: avg_over_time(up[2m]) < 0.9
for: 1m
labels:
severity: info
annotations:
summary: 'Exporter does not return any metrics!'
description: 'ENV: {{$labels.env}}\nHost: {{$labels.host}}\n{{$labels.job}} exporter down!'
Перезапускаем Prometheus, и останавливаем один из екпортёров на Dev:
[simterm]
root@mobilebackend-dev-app-1:/home/admin# docker stop prometheus-client_mysql_exporter_db1_1 prometheus-client_mysql_exporter_db1_1
[/simterm]
Проверяем значение avg_over_time() в Prometheus:
И получаем алерт:
Slack:
Готово.
Ссылки по теме
Prometheus Alerting Gotchas — Detecting No Events
Alerting on gauges in Prometheus 2.0








