Info
Content

vmalert

vmalert выполняет список переданных ему alerting и recording rules в указанном в флаге -datasource.url датасорсе который должен быть совместим с Prometheus HTTP API
Для доставки алертов он полагается на Alertmanager путь до которого должен быть прописан в флаге -notifier.url
Результаты работы recording rules vmalert запишет через remote write протокол в указанный -remoteWrite.url
vmalert сильно вдохновлен Prometheus'ом и ставит перед собой цель быть совместимым с его синтаксисом

Features

  • Интеграция с VictoriaMetrics TSDB
  • Поддержка MetricsQL и валидации вырежений
  • Поддержка Prometheus формата alerting rules
  • Интеграция с Alertmanager
  • Сохранение состояния алертов при рестартах
  • Recording/Alerting rules backfilling (replay)
  • Легковесный
  • Переиспользуемые темплейты для аннотаций

Limitations

vmalert делает запросы в удаленный datasource, поэтому возможны сетевые проблемы, нужно это учитывать при составлении правил (нужны thresholds)

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

QuickStart

Чтобы начать использовать vmalert нужно:

  • list of rules - PromQL/MetricsQL выражения для выполнения
  • datasource address - эндпоинт с поддержкой Prometheus HTTP API для применения к нему запросов
  • (опционально) notifier address - Alertmanager для обработки, аггрегации алертов и отправки нотификаций. Адрес нотифайера можно получить через SD
  • (опционально) remote write address - remote write совместимый сторадж для хранения состояния алертов. Для хранения состояния в множестве хранилищ можно использовать vmagent с настроенными множественными remote writes
  • (опционально) remote read address - MetricsQL совместимый datasource откуда vmalert будет восстанавливать состояния алертов

Пример конфигурации vmalert'a:

./bin/vmalert -rule=alert.rules \            # Path to the file with rules configuration. Supports wildcard
    -datasource.url=http://localhost:8428 \  # Prometheus HTTP API compatible datasource
    -notifier.url=http://localhost:9093 \    # AlertManager URL (required if alerting rules are used)
    -notifier.url=http://127.0.0.1:9093 \    # AlertManager replica URL
    -remoteWrite.url=http://localhost:8428 \ # Remote write compatible storage to persist rules and alerts state info (required if recording rules are used)
    -remoteRead.url=http://localhost:8428 \  # Prometheus HTTP API compatible datasource to restore alerts state from
    -external.label=cluster=east-1 \         # External label to be applied for each rule
    -external.label=replica=a                # Multiple external labels may be set

Нужно отметить что раздельные -remoteWrite.url и -remoteRead.url позволяют использовать vmalert как транспортера данных между горячим, быстрым хранилищем и холодным, долгим (short-term -> long-term) (имеются ввиду record rules)

Если ты запускаешь несколько инстансов vmalert'a и все они подключаются к одному хранилищу и Alertmanager'у, то будет полезным настроить на них различающиеся лейблы, чтобы было понятно кто из них сгенерил алерт

Конфигурация для recording и alerting rules очень похожа на Prometheus rules, каждый rule пренадлежит какой-то group и каждый конфиг может содержать различное количество групп:

groups:
  [ - <rule_group>]

Groups

Каждая группа имеет слудующие аттрибуты:

# Имя группы, должно быть уникальным в рамках файла
name: <string>

# Как часто рулы из этой группы должны выполняться
[ interval: <duration> | default = -evaluationInterval flag ]

# Ограничение на количество алертов и таймсерий которые может породить этот рул. 0 - лимита нет
[ limit: <int> | default = 0 ]

# Как много правил будет выполнено за раз в рамках группы. Увеличение параллельности может скорить выполнение правил
[ concurrency: <integer> | default = 1 ]

# Опциональный тип выражения внутри рула. Значением может быть 'graphite' и 'prometheus', второй дефолтный
[ type: <string> ]

# Опциональные дополнительные HTTP URL параметры применяемые для всех запросов к хранилке в рамках выполнения рулов группы
# Например:
#  params:
#    nocache: ["1"]                # disable caching for vmselect
#    denyPartialResponse: ["true"] # fail if one or more vmstorage nodes returned an error
#    extra_label: ["env=dev"]      # apply additional label filter "env=dev" for all requests 
# see more details at https://docs.victoriametrics.com#prometheus-querying-api-enhancements
params:
  [ <string>: [<string>, ...]]

# Опциональные HTTP хедеры в формате `header-name: value` добавляемые ко всем запросам к хранилке в рамках выполнения рулов группы
# Например:
#  headers:
#    - "CustomHeader: foo"
#    - "CustomHeader2: bar"
# Заголовки выставленные таким образом имеет приоритет выше чем заголовки добавленные через флаг `-datasource.headers`
headers:
  [ <string>, ...]

# Опциональный список лейблов добавляемых каждому рулу в группе
# Эти лейблы имеют приоритет выше чем external labels
labels:
  [ <labelname>: <labelvalue> ... ]

rules:
  [ - <rule> ... ]

Rules

Каждое правило содержит поле expr с PromQL/MetricsQL выражением. vmalert выполняет это выражение и дальше действует в зависимости от типа правила
Есть два типа правил:

  • alerting - Alerting rules позволяют описать условия срабатывания алерта через поле expr и отправить нотификацию в Alertmanager если результат выполнения не пустой
  • recording - Recording rules позволяют описать поле expr результат применения которого далее будет забэкфиллен в -remoteWrite.url. Recording rules нужны для предподсчета часто используемых или вычислительно сложных выражений

vmalert не разрешает наличие дубликатов - рулов с одинаковой комбинацией имени, выражения и лейблов в рамках одной группы

Alerting rules

Синтаксис алерт рулов следующий:

# Имя алерта, должно проходить правила валидации имен метрик
alert: <string>

# Выражение. Язык выражения зависит от значения в поле `type` группы
expr: <string>

# Алерт считается "горящим" после того как в течение этого времени (из поля for) его expr возвращал не пустоту
# Алерт который срабатыват в течение времени меньшего чем for находится в состоянии pending
# Если этот параметр отсутсвует или проставлен в 0, то алерт будет срабатывать сразу
[ for: <duration> | default = 0s ]

# Лейблы для добавления или оверрайдинга под каждый алерт
labels:
  [ <labelname>: <tmpl_string> ]

# Аннотации под каждый алерт
annotations:
  [ <labelname>: <tmpl_string> ]
Templating

Разрешено использовать Go templating в аннотациях для форматирования данных, перебора или выполнения выражений. Следующие переменные доступны к использованию в темплейтинге:

Variable Description Example
$value или .Value Текущее значение алерта Number of connections is {{ $value }}
$activeAt или .ActiveAt Момент времени когда алерт стал активным (pending или firing) http://vm-grafana.com/panelId=xx?from={{($activeAt.Add (parseDurationTime "1h")).Unix}}&to={{($activeAt.Add (parseDurationTime "-1h")).Unix}}
$labels или .Labels Список лейблов алерта Too high number of connections for {{ .Labels.instance }}
$alertID или .AlertID alert's ID сгенерированный vmalert'ом Link: vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}
$groupID или .GroupID alert's group ID сгенерированный vmalert'ом Link: vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}
$expr или .Expr Выражение алерта. Может быть использована для генерации ссылки на график в графане или для чего-то еще /api/v1/query?query={{ $expr
$externalLabels или .ExternalLabels Список лейблов настроенных через флаг -external.label Issues with {{ $labels.instance }} (datacenter-{{ $externalLabels.dc }})
$externalURL или .ExternalURL URL настроенный через флаг -external.url, используется когда vmalert спрятан за проксей Visit {{ $externalURL }} for more details
Reusable templates

Как и в прометеусе, в vmalert'e есть reusable templates
Для их использования нужно описать темплейт в файле и подключить файл через флаг -rule.templates
Например есть описанный темплейт с именем grafana.filter:

{{ define "grafana.filter" -}}
  {{- $labels := .arg0 -}}
  {{- range $name, $label := . -}}
    {{- if (ne $name "arg0") -}}
      {{- ( or (index $labels $label) "All" ) | printf "&var-%s=%s" $label -}}
    {{- end -}}
  {{- end -}}
{{- end -}}

И он может быть использован в аннотации следующим образом:

groups:
  - name: AlertGroupName
    rules:
      - alert: AlertName
        expr: any_metric > 100
        for: 30s
        labels:
          alertname: 'Any metric is too high'
          severity: 'warning'
        annotations:
          dashboard: '{{ $externalURL }}/d/dashboard?orgId=1{{ template "grafana.filter" (args .CommonLabels "account_id" "any_label") }}'

Флаг -rule.templates поддерживает вайлдкарды чтобы подсасывать сразу много файлов. Контент темплейт-файлов может быть зарелоажен на лету

Recording rules

Синтаксис recording rules следующий:

# Имя алерта, должно проходить правила валидации имен метрик
record: <string>

# Выражение. Язык выражения зависит от значения в поле `type` группы
expr: <string>

# Лейблы для добавления или оверрайдинга которые будут добавлены до сохранения результата
labels:
  [ <labelname>: <labelvalue> ]

Чтобы рекординг рулы работали нужно чтобы присутствовал флаг -remoteWrite.url

Alerts state on restarts

vmalert не имеет локального хранилища, поэтому состояния алертов хранятся в опертивной памяти. Следовательно после рестарта vmalert'a стейты алертов будут потеряны. Чтобы этого избежать нужно чтобы vmalert был сконфигурирован со следующими флагами:

  • -remoteWrite.url - URL до хранилища в котором vmalert будет хранить стейты алертов с помощью таймсерий ALERTS и ALERTS_FOR_STATE. Это абсолютно рядовые таймсерии, такие же как и все остальные. Стейт алертов записывается в -remoteWrite.url при каждом прогоне правил (rule evaluation)
  • -remoteRead.url - URL до хранилища из которого vmalert будет восстанавливать состояния алертов после рестарта (запрашивая метрику ALERTS_FOR_STATE)

Оба флага нужны для нормального хранения состояний алертов. Процесс восстановления может фейлиться если таймсерии нет в указанном -remoteRead.url или если она не обновлялась за последний час (контролируется флагом remoteRead.lookback) или если полученный стейт не матчится с текущей конфигурацией vmalert'a

Multitenancy

Есть следующие варинты для алертинга и рекординга при мультитенантном сетапе:

  • Можно запустить несколько vmalert'ов, по одному на каждый тенант, и прописать каждому конкретный тенант -datasource.url=http://vmselect:8481/select/123/prometheus, аналогично с флагами -remoteWrite.url и -remoteRead.url
  • Можно указывать параметр tenant для каждой группы, но для этого нужно использовать энтерпрайз версию с флагом -clusterMode
    groups:
    - name: rules_for_tenant_123
      tenant: "123"
      rules:
        # Rules for accountID=123
    
    - name: rules_for_tenant_456:789
      tenant: "456:789"
      rules:
        # Rules for accountID=456, projectID=789
    

Когда установлен флаг -clusterMode, флаги -datasource.url, -remoteRead.url и -remoteWrite.url должны содержать просто хостнейм и порт, часть урла с тенантом (например /select/123/prometheus) будет добавлена vmalert'ом автоматически на основе тенанта из конфига

Пример запуска:

root@mon-vm-01:~# ./vmalert-prod -rule=/etc/victoriametrics/vmalert/rules.yml -datasource.url=http://mon-vm-01.g01.i-free.ru:8481 -notifier.url=http://mon-vm-01.g01.i-free.ru:9093 -clusterMode -eula
Copyright 2018-2022 VictoriaMetrics, Inc - All Rights Reserved.
For any questions please contact info@victoriametrics.com
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:12   build version: vmalert-20220808-174744-tags-v1.80.0-enterprise-0-gccf72e410
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:13   command-line flags
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:20     -clusterMode="true"
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:20     -datasource.url="http://mon-vm-01.g01.i-free.ru:8481"
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:20     -eula="true"
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:20     -notifier.url="http://mon-vm-01.g01.i-free.ru:9093"
2022-08-30T15:55:25.798Z        info    VictoriaMetrics/lib/logger/flag.go:20     -rule="/etc/victoriametrics/vmalert/rules.yml"
2022-08-30T15:55:25.799Z        info    VictoriaMetrics/app/vmalert/main.go:149 reading rules configuration file from "/etc/victoriametrics/vmalert/rules.yml"
2022-08-30T15:55:25.800Z        info    VictoriaMetrics/lib/httpserver/httpserver.go:94 starting http server at http://127.0.0.1:8880/
2022-08-30T15:55:25.800Z        info    VictoriaMetrics/lib/httpserver/httpserver.go:95 pprof handlers are exposed at http://127.0.0.1:8880/debug/pprof/
2022-08-30T15:56:11.271Z        info    VictoriaMetrics/app/vmalert/group.go:304        group "alert.rules" started; interval=1m0s; concurrency=1
2022-08-30T15:57:11.280Z        error   VictoriaMetrics/app/vmalert/group.go:321        group "alert.rules": rule "Node_State": failed to execute: failed to execute query "up == 0": error getting response from http://mon-vm-01.g01.i-free.ru:8481/select/1/prometheus/api/v1/query?query=up+%3D%3D+0&step=60s&time=1661875020: Post "http://mon-vm-01.g01.i-free.ru:8481/select/1/prometheus/api/v1/query?query=up+%3D%3D+0&step=60s&time=1661875020": EOF

Если в конфиге не указан тенант, то будет использоваться тенант из флага -defaultTenant.prometheus или -defaultTenant.graphite (в зависимости от поля type группы)
Если тенант не указан в конфиге и не указан флагом то будет ошибка:

root@mon-vm-01:~# ./vmalert-prod -rule=/etc/victoriametrics/vmalert/rules.yml -datasource.url=http://mon-vm-01.g01.i-free.ru:8481 -notifier.url=http://mon-vm-01.g01.i-free.ru:9093 -clusterMode -eula
Copyright 2018-2022 VictoriaMetrics, Inc - All Rights Reserved.
For any questions please contact info@victoriametrics.com
2022-08-30T16:19:33.935Z        info    VictoriaMetrics/lib/logger/flag.go:12   build version: vmalert-20220808-174744-tags-v1.80.0-enterprise-0-gccf72e410
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/lib/logger/flag.go:13   command-line flags
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/lib/logger/flag.go:20     -clusterMode="true"
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/lib/logger/flag.go:20     -datasource.url="http://mon-vm-01.g01.i-free.ru:8481"
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/lib/logger/flag.go:20     -eula="true"
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/lib/logger/flag.go:20     -notifier.url="http://mon-vm-01.g01.i-free.ru:9093"
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/lib/logger/flag.go:20     -rule="/etc/victoriametrics/vmalert/rules.yml"
2022-08-30T16:19:33.936Z        info    VictoriaMetrics/app/vmalert/main.go:149 reading rules configuration file from "/etc/victoriametrics/vmalert/rules.yml"
2022-08-30T16:19:33.937Z        fatal   VictoriaMetrics/app/vmalert/main.go:152 cannot parse configuration file: errors(1): invalid group "alert.rules" in file "/etc/victoriametrics/vmalert/rules.yml": group "alert.rules" must contain `tenant` section if `-clusterMode` enabled
root@mon-vm-01:~#

Указываем флаг с дефолтным тенантом и все работает:

root@mon-vm-01:~# ./vmalert-prod -rule=/etc/victoriametrics/vmalert/rules.yml -datasource.url=http://mon-vm-01.g01.i-free.ru:8481 -notifier.url=http://mon-vm-01.g01.i-free.ru:9093 -clusterMode -eula -defaultTenant.prometheus=1
Copyright 2018-2022 VictoriaMetrics, Inc - All Rights Reserved.
For any questions please contact info@victoriametrics.com
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:12   build version: vmalert-20220808-174744-tags-v1.80.0-enterprise-0-gccf72e410
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:13   command-line flags
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:20     -clusterMode="true"
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:20     -datasource.url="http://mon-vm-01.g01.i-free.ru:8481"
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:20     -defaultTenant.prometheus="1"
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:20     -eula="true"
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:20     -notifier.url="http://mon-vm-01.g01.i-free.ru:9093"
2022-08-30T16:20:33.848Z        info    VictoriaMetrics/lib/logger/flag.go:20     -rule="/etc/victoriametrics/vmalert/rules.yml"
2022-08-30T16:20:33.849Z        info    VictoriaMetrics/app/vmalert/main.go:149 reading rules configuration file from "/etc/victoriametrics/vmalert/rules.yml"
2022-08-30T16:20:33.850Z        info    VictoriaMetrics/lib/httpserver/httpserver.go:94 starting http server at http://127.0.0.1:8880/
2022-08-30T16:20:33.850Z        info    VictoriaMetrics/lib/httpserver/httpserver.go:95 pprof handlers are exposed at http://127.0.0.1:8880/debug/pprof/

Topology examples

Следующие секции показывают как может быть использован vmalert в различных сценариях
Отметим что не все флаги из примеров обязательны:

  • -remoteWrite.url и -remoteRead.url нужны только если у тебя есть recording rules или если ты хочешь сохранять стейт алертов при рестартах vmalert'a
  • -notifier.url нужен если у тебя есть alerting rules
Single-node VictoriaMetrics

Простейшая конфигурация когда используется одна нода VictoriaMetrics и как datasource, и как хранилище стейтов алертов:

./bin/vmalert -rule=rules.yml  \                    # Path to the file with rules configuration. Supports wildcard
    -datasource.url=http://victoriametrics:8428 \   # VM-single addr for executing rules expressions
    -remoteWrite.url=http://victoriametrics:8428 \  # VM-single addr to persist alerts state and recording rules results
    -remoteRead.url=http://victoriametrics:8428 \   # VM-single addr for restoring alerts state after restart
    -notifier.url=http://alertmanager:9093          # AlertManager addr to send alerts when they trigger

vmalert_single.png

Cluster VictoriaMetrics

В кластерной версии VictoriaMetrics имеет выделенные компоненты для записи и чтения данных: vminsert и vmselect
vmselect используется для получения данных из хранилища для выполнения рулов
vminsert используется для сохранения результатов работы recording rules и для сохранения стейтов алертов

Пример конфигурации:

./bin/vmalert -rule=rules.yml  \                                # Path to the file with rules configuration. Supports wildcard
    -datasource.url=http://vmselect:8481/select/0/prometheus    # vmselect addr for executing rules expressions
    -remoteWrite.url=http://vminsert:8480/insert/0/prometheus   # vminsert addr to persist alerts state and recording rules results
    -remoteRead.url=http://vmselect:8481/select/0/prometheus    # vmselect addr for restoring alerts state after restart
    -notifier.url=http://alertmanager:9093                      # AlertManager addr to send alerts when they trigger

vmalert_cluster.png

vminsert'ов и vmselect'ов может быть много
Если ты хочешь распределить нагрузку на эти компоненты то добавь балансер и указывай vmalert'у адрес балансера

HA vmalert

Для High Availability можно поднять несколько идентичных vmalert'ов которые будут выполнять одинаковые рулы в одном и том же datasource, складывать результаты их работы в одно и то же хранилище и слать алерты в одни и те же alertmanager'ы
Пример конфигурации:

./bin/vmalert -rule=rules.yml \                   # Path to the file with rules configuration. Supports wildcard
    -datasource.url=http://victoriametrics:8428 \   # VM-single addr for executing rules expressions
    -remoteWrite.url=http://victoriametrics:8428 \  # VM-single addr to persist alerts state and recording rules results
    -remoteRead.url=http://victoriametrics:8428 \   # VM-single addr for restoring alerts state after restart
    -notifier.url=http://alertmanager1:9093 \       # Multiple AlertManager addresses to send alerts when they trigger
    -notifier.url=http://alertmanagerN:9093         # The same alert will be sent to all configured notifiers

vmalert_ha.png

Чтобы избежать дублирования результатов работы recording rules нужно просто настроить дедупликацию на сторадже
Рекомендуется использовать значение для флага -dedup.minScrapeInterval большее или равное значению evaluation_interval у vmalert'a

Если есть неконсистентные или "прыгающие" значения у таймсерий сгенеренных vmalert'ом, то можно выключить -datasource.queryTimeAlignment
Из-за выравнивания в HA сетапе (когда более одного vmalert'a обрабатывают recording rules) несколько vmalert'ов будут генерить таймсерии с одинаковыми таймстемпами, но из-за бэкфиллинга (backfilling) значения могут отличаться, это зааффектит логику дедупликации и датапоинты могут "прыгать"

Alertmanager автоматически дедуплицирует алерты с одинаковыми лейблами (поэтому нужно чтобы все vmalert'ы имели идентичные конфиги)

Не забудьте настроить cluster mode для Alertmanager'а для большей доступности

Downsampling and aggregation via vmalert

vmalert не может модифицировать уже существующие данные. Но он может запускать recording rules и записывать результат в -remoteWrite.url, это позволяет аггрегировать данные. Например следующее правило будет подсчитывать среднее значение метрикиhttp_requests на 5 минутном интервале:

- record: http_requests:avg5m   
    expr: avg_over_time(http_requests[5m])

Каждый раз когда это правило будет выполняться, vmalert будет записывать результат его работы как новую таймсерии с именем http_requests:avg5m в указанный -remoteWrite.url

vmalert запускает правила с периодичностью указанной в -evaluationInterval или в параметре interval указанном для группы
Интервал позволяет контролировать разрешение произведенных таймсерий (чем чаще выполняется тем четче получается)
Возможность задавать интервал позволяет даунсемлить метрики, например следующее правило будет выполяться раз в пять минут, соответственно новые сэмплы в ней будут реже чем в исходной метрике:

groups:
  - name: my_group
    interval: 5m
    rules:  
    - record: http_requests:avg5m
      expr: avg_over_time(http_requests[5m])   

Тот факт что для vmalert'a источник данных и пункт записи сгенеренных данных задаются раздельными флагами (-datasource.url и -remoteWrite.url), позволяет читать данные из одного хранилища, даунсэмплить их и записывать получившиеся метрики в другое хранилище

Следующий пример демонстрирует как может выглядеть сетап где vmalert берет данные из горячего хранилища, обрабатывает их и записывает результат в холодное

  • горячее - с маленьким ретеншеном, быстрыми дисками, используется для оперативного мониторинга
  • холодное - с большим ретеншеном, медленными/дешевыми дисками, с низким разрешением

С помощью vmalert'a пользователь может настроить recording rules для преобразования данных из горячих в холодные

./bin/vmalert -rule=downsampling-rules.yml \                                        # Path to the file with rules configuration. Supports wildcard
    -datasource.url=http://raw-cluster-vmselect:8481/select/0/prometheus            # vmselect addr for executing recordi ng rules expressions
    -remoteWrite.url=http://aggregated-cluster-vminsert:8480/insert/0/prometheus    # vminsert addr to persist recording rules results

vmalert_multicluster.png

Функцию replay можно использовать для трансформирования исторических данных
Флаги -remoteRead.url и -notifier.url опискаются когда мы используем vmalert только для применения recording rules

Multiple remote writes

Для указания пункта сохранения данных используется флаг -remoteWrite.url, но он принимает в себя только одно значение. Чтобы сохранять данные в множество хранилищ рекомендуется использовать vmagent как fan-out proxy:

vmalert_multiple_rw.png
При такой топологии vmalert шлет данные в vmagent, который в свою очередь кладет полученные данные в указанные у него -remoteWrite.url
Использование vmagent'a дает ряд дополнительных фич, таких как сохранение данных когда сторадж не доступен или модификация таймсерий через релейблинг

Web

vmalert предоставляет фронтенд который доступен на -httpListenAddr. Он предоставляет он предоставляет метрики и данные по алертам (как у прометеуса):

  • http://<vmalert-addr> - UI
    Screenshot_2021_02_02-12_49_03-2022-08-31-at-02vmalertui.png
  • http://<vmalert-addr>/api/v1/rules - список групп и рулов
    Screenshot_2021_02_02-12_49_03-2022-08-31-at-02alerts.png
  • http://<vmalert-addr>/api/v1/alerts - список активных алертов
    Screenshot_2021_02_02-12_49_03-2022-08-31-at-02activealerts.png
  • http://<vmalert-addr>/vmalert/api/v1/alert?group_id=<group_id>&alert_id=<alert_id> - статус конкретного алерта в JSON, используется как alert source для Alertmanager'a
    Screenshot_2021_02_02-12_49_03-2022-08-31-alertstate.png
  • http://<vmalert-addr>/vmalert/alert?group_id=<group_id>&alert_id=<alert_id> - WEB UI страница по конкретному алерту
    Screenshot_2021_02_02-12_49_03-2022-08-31-specificalertstate.png
  • http://<vmalert-addr>/metrics - метрики
  • http://<vmalert-addr>/-/reload - хэндлер для релоада конфигурации

WEB UI vmalert'a может быть доступным из Виктории
Для этого ей нужно указать флаг -vmalert.proxyURL
Это нужно например для графаны

Graphite

Не интересно

Rules backfilling

vmalert поддерживает alerting и recording rules backfilling (aka replay). В реплей моде он может применить правила на указанный временной диапазон и записать результат в указанный remote storage

How it works

В replay mode vmalert работает как cli утилита и завершается сразу после завершения работы

root@mon-vm-01:~# ./vmalert-prod --datasource.url=http://localhost:8481/select/0/prometheus --notifier.url=http://localhost:9093 -remoteWrite.url=http://localhost:8480/insert/0/prometheus --rule=/etc/victoriametrics/vmalert/rules.yml -eula -replay.timeFrom=2022-08-31T02:20:00Z -replay.timeTo=2022-08-31T02:30:00Z
Copyright 2018-2022 VictoriaMetrics, Inc - All Rights Reserved.
For any questions please contact info@victoriametrics.com
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:12   build version: vmalert-20220808-174744-tags-v1.80.0-enterprise-0-gccf72e410
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:13   command-line flags
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -datasource.url="http://localhost:8481/select/0/prometheus"
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -eula="true"
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -notifier.url="http://localhost:9093"
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -remoteWrite.url="http://localhost:8480/insert/0/prometheus"
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -replay.timeFrom="2022-08-31T02:20:00Z"
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -replay.timeTo="2022-08-31T02:30:00Z"
2022-08-30T23:37:12.757Z        info    VictoriaMetrics/lib/logger/flag.go:20     -rule="/etc/victoriametrics/vmalert/rules.yml"
Replay mode:
from:   2022-08-31 02:20:00 +0000 UTC
to:     2022-08-31 02:30:00 +0000 UTC
max data points per request: 1000

Group "alert.rules"
interval:       1m0s
requests to make:       1
max range per request:  16h40m0s
> Rule "Node_State" (ID: 9459300515240668085)
1 / 1 [---------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
> Rule "recorded_metric" (ID: 331216927271362772)
1 / 1 [---------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
2022-08-30T23:37:14.792Z        info    VictoriaMetrics/app/vmalert/replay.go:81        replay finished! Imported 11 samples

Screenshot_2021_02_02-12_49_03-2022-08-31-at-02recordedrule.png

Группы обрабатываются поочередно, правила в группах обрабатыватся поочередно (concurrency нет)
vmalert шлет выражение рула на эндпоинт /query_range указанного -datasource.url
В примере выше был сделан примерно такой запрос (здесь результат изменен для краткости):

(ifree-test-k8s:default) vandud@macbook: ~ [0] ? curl -s 'http://mon-vm-01.g01.i-free.ru:8481/select/0/prometheus/api/v1/query_range?query=1&start=2022-08-31T02:20:00Z&end=2022-08-31T02:30:00Z&step=1m' | jq 'del(.data.result[0].values[0:-1])'
{
  "status": "success",
  "isPartial": false,
  "data": {
    "resultType": "matrix",
    "result": [
      {
        "metric": {},
        "values": [
          [
            1661913000,
            "1"
          ]
        ]
      }
    ]
  }
}

Полученные данные процессятся в соответствии с rule type и бэкфиллятся в -remoteWrite.url
vmalert использует evaluationInterval указанный через флаг или указанный в параметрах группы
Так же он автоматически выключает кэш на стороне VictoriaMetrics засылая ей параметр nocache=1, это позволяет предотвратить загрязнение кэша и нежелательное корректирование временных границ на протяжении backfilling'a

Результат реплея рекординг рулов должен совпадать с тем как если бы эти рулы выполнялись естественным путем
Результат реплея алертинг рулов это таймсерия ALERTS отражающая стейты алертов. Реплей алертрулов позволяет посмотреть как вел бы себя алерт в прошлом

Addtional configuration

Дополнительные необязательные флаги для реплея:

  • -replay.maxDatapointsPerQuery - максимальное количество сэмплов которые можно получить в ответ на запрос. При более высоких значениях будет сделано меньшее количество запросов на протяжении реплея
  • -replay.ruleRetryAttempts - когда датасорс не отвечает на запрос, vmalert сделает указанное количество повторных попыток на каждый рул (то есть это лимит на количество повторов per rule)
  • -replay.rulesDelay - задержка между рулами. Это применимо в случаях когда одни рулы зависят от других. Смысл в том что сторадж может иметь задержку между тем как данные в него отправлены и когда они будут доступны на чтение. Рекомендуется держать значение этого флага равным или большим чем -remoteWrite.flushInterval
  • -replay.disableProgressBar - выключает прогресс бар. Это может быть полезно потому что лог работы может быть очень большим, и он не форматируется как типичный лог, а это может зааффектить систему сбора логов

Limitations

  • Graphite engine не поддерживается для бэкфиллинга
  • query template function выключена ради производительности
  • Параметр limit в группах не имеет влияния на процесс реплея

Monitoring

vmalert экспозит различные метрики на эндпоинте /metrics
Есть официальный дашборд для графаны https://grafana.com/grafana/dashboards/14950-vmalert/

Profiling

vmalert предоставляет хэндлеры для сбора Go профилей:

  • Memory profile - curl http://vmalert/debug/pprof/heap > mem.pprof
  • CPU profile - curl http://vmalert/debug/pprof/profile > cpu.pprof

Команда для сбора CPU профиля сперва ждет 30 секунд и только потом возращает результат
Собранные профили можно проанализировать утилитой https://github.com/google/pprof
Файлы профилей не содержат сенсетивной информации поэтому их можно без страха шарить кому-то

Configuration

Flags

vmalert имеет еще массу различных флагов, актуальную справку по которым можно увидеть запустив vmalert -help

Hot config reload

Плавно релоаднуть конфигурацию можно следующими образами:

  • Послать SIGHUP сигнал процессу
  • Послать GET запрос на эндпоинт /-/reload
  • Настроить флаг -configCheckInterval для автоматического периодического релоада

URL params

Чтобы добавить какие-то дополнительные параметры для datasource.url, remoteWrite.url или remoteRead.url можно просто добавить их в url. Например - -datasource.url=http://localhost:8428?nocache=1
Чтобы добавить такие параметры для конкретных групп правил можно добавить секцию params в конфиге:

groups:
  - name: TestGroup
    params:
      denyPartialResponse: ["true"]
      extra_label: ["env=dev"]

Параметры используются только для применения выражений из правил, если происходит конфликт между параметрами из конфига и из флага то параметры из конфига будут иметь более высокий приоритет

Notifier configuration file

Notifier может быть законфигурирован через конфиг указанный в флаге -notifier.config:

./bin/vmalert -rule=app/vmalert/config/testdata/rules.good.rules \
  -datasource.url=http://localhost:8428 \
  -notifier.config=app/vmalert/notifier/testdata/consul.good.yaml

Конфиг позволяет описать статические нотифайеры и обнаруженные через Consul или DNS

static_configs: 
  - targets:
      - localhost:9093
      - localhost:9095

consul_sd_configs:
  - server: localhost:8500
    services:
      - alertmanager
      
dns_sd_configs:
  - names:
      - my.domain.com
    type: 'A'
    port: 9093

Список всех нотифайеров виден в UI

Спецификация конфига:

# Per-target Notifier timeout when pushing alerts.
[ timeout: <duration> | default = 10s ]

# Prefix for the HTTP path alerts are pushed to.
[ path_prefix: <path> | default = / ]

# Configures the protocol scheme used for requests.
[ scheme: <scheme> | default = http ]

# Sets the `Authorization` header on every request with the
# configured username and password.
# password and password_file are mutually exclusive.
basic_auth:
  [ username: <string> ]
  [ password: <secret> ]
  [ password_file: <string> ]

# Optional `Authorization` header configuration.
authorization:
  # Sets the authentication type.
  [ type: <string> | default: Bearer ]
  # Sets the credentials. It is mutually exclusive with
  # `credentials_file`.
  [ credentials: <secret> ]
  # Sets the credentials to the credentials read from the configured file.
  # It is mutually exclusive with `credentials`.
  [ credentials_file: <filename> ]

# Configures the scrape request's TLS settings.
# see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tls_config
tls_config:
  [ <tls_config> ]

# List of labeled statically configured Notifiers.
static_configs:
  targets:
    [ - '<host>' ]

# List of Consul service discovery configurations.
# See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#consul_sd_config
consul_sd_configs:
  [ - <consul_sd_config> ... ]

# List of DNS service discovery configurations.
# See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dns_sd_config
dns_sd_configs:
  [ - <dns_sd_config> ... ]

# List of relabel configurations for entities discovered via service discovery.
# Supports the same relabeling features as the rest of VictoriaMetrics components.
# See https://docs.victoriametrics.com/vmagent.html#relabeling
relabel_configs:
  [ - <relabel_config> ... ]

# List of relabel configurations for alert labels sent via Notifier.
# Supports the same relabeling features as the rest of VictoriaMetrics components.
# See https://docs.victoriametrics.com/vmagent.html#relabeling
alert_relabel_configs:
  [ - <relabel_config> ... ]

Конфигурация может быть плавно релоаднута

No Comments
Back to top