Среди прочих алертов у нас есть алерты на падение сервиса – когда метрика *_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