aidaho6

aidaho6

На Пикабу
в топе авторов на 640 месте
765 рейтинг 12 подписчиков 7 подписок 15 постов 7 в горячем
Награды:
Пикабу 17 лет!5 лет на Пикабу

Как мы добавили Global Orchestration в IncidentRelay: маршрутизация алертов до создания инцидента

Когда система мониторинга отправляет алерт, он редко выглядит так, как хотелось бы дежурному инженеру.

Один источник пишет critical, другой — disaster, третий передаёт severity: 5. В одном payload сервис называется checkout, в другом — payments-api, а в третьем его приходится угадывать по namespace.

Если все эти события приходят через общий Alertmanager или webhook, одной статической настройки маршрута быстро становится недостаточно.

Обычно проблему решают одним из трёх способов:

  1. Усложняют правила на стороне каждой системы мониторинга.

  2. Создают много почти одинаковых endpoint’ов и маршрутов.

  3. Добавляют промежуточный сервис, который преобразует payload перед отправкой в on-call-систему.

Все три варианта работают. А потом появляется ещё одна команда, меняется схема меток, кто-то копирует правило с ошибкой — и распределённая конфигурация начинает жить собственной жизнью.

В IncidentRelay 2.0 мы добавили Event Orchestration. В этой статье разберём одну из основных частей новой функции — Global Orchestration: зачем она нужна, где находится в потоке обработки, как устроены правила и почему мы не ограничились обычным rule engine с кнопкой «Включить».

IncidentRelay Global Orchestration explain trace

IncidentRelay Global Orchestration explain trace

Какую задачу решает Global Orchestration

Global Orchestration — это набор упорядоченных правил, принадлежащий группе IncidentRelay. Он обрабатывает нормализованное событие до того, как будет окончательно выбран сервис и запущен обычный жизненный цикл алерта.

Упрощённо поток выглядит так:

Payload интеграции ↓ Аутентификация и нормализация ↓ Global Orchestration группы ↓ Оркестрация выбранного сервиса, если он известен ↓ Обычный жизненный цикл IncidentRelay ↓ Группа алертов, дочерний алерт, эскалация и уведомления

IncidentRelay Global Orchestration

IncidentRelay Global Orchestration

На глобальном уровне можно:

  • выбрать команду, маршрут и сервис;

  • нормализовать severity, title и другие поля события;

  • назначить приоритет и политики;

  • добавить или удалить метки;

  • настроить group_key и dedup_key;

  • подавить уведомления;

  • отложить создание алерта;

  • полностью отбросить событие;

  • поставить безопасный асинхронный webhook в очередь.

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

Иными словами, мы добавили не второй жизненный цикл алерта, а слой принятия решений перед ним.

Почему global и service — разные области

В IncidentRelay есть две области оркестрации:

Область

Когда запускать

Типичные задачи

global

Владелец события ещё неизвестен или правило относится к нескольким сервисам

Нормализация, выбор команды и сервиса, общие правила подавления

service

Сервис уже выбран

Политики конкретного сервиса, локальное обогащение, задержка известного сигнала, запуск диагностики

Разделение оказалось важным. Без него глобальное определение быстро превращается в огромный файл со знаниями обо всех особенностях всех сервисов.

Хорошая граница ответственности выглядит так:

Global Orchestration: Кому принадлежит событие? В какой общий формат его привести? Service Orchestration: Как именно этот сервис хочет его обработать?

Глобальное правило может выбрать сервис. После этого IncidentRelay запускает оркестрацию, прикреплённую к выбранному сервису.

Если service orchestration передаёт событие другому сервису, runtime защищает цепочку от циклов и чрезмерного количества переходов. Потому что бесконечная маршрутизация — это тоже вид мониторинга, только уже за состоянием CPU.

Так общие соглашения хранятся в одном месте, а знания о конкретном сервисе остаются рядом с самим сервисом.

Пример: один Alertmanager и несколько команд

Представим, что общий Alertmanager принимает алерты всей production-платформы.

В IncidentRelay приходит нормализованное событие:

{ "source": "alertmanager", "title": "High error rate", "message": "Error rate is above 20%", "severity": "fatal", "status": "firing", "dedup_key": "checkout-db-2:high-error-rate", "labels": { "environment": "production", "application": "checkout", "component": "database", "instance": "checkout-db-2", "customer_impacting": true } }

Из payload уже понятно почти всё необходимое. Но статический маршрут не знает, какую комбинацию решений следует принять.

Глобальная оркестрация может выполнить такую последовательность:

  1. Преобразовать fatal в каноническое значение critical.

  2. По application=checkout выбрать команду Payments.

  3. По component=database выбрать сервис Checkout Database.

  4. Для критического события с customer_impacting=true задать приоритет P1.

  5. Построить стабильные ключи группировки и дедупликации.

  6. Остановить дальнейшие глобальные правила маршрутизации.

  7. Передать результат в оркестрацию сервиса и обычный lifecycle.

Почему правила выполняются последовательно

Мы рассматривали вариант, при котором все правила получают один неизменяемый исходный контекст, а затем результаты как-то объединяются.

На бумаге это выглядит функционально и аккуратно. На практике быстро возникает вопрос: что делать, если два правила выбрали разные сервисы или установили разные значения priority?

В текущей модели правила выполняются сверху вниз, а действия внутри совпавшего правила — в указанном порядке. Последующие правила видят изменения предыдущих.

Например:

Правило 1: IF event.severity equals disaster THEN set_severity critical AFTER continue Правило 2: IF event.severity equals critical AND labels.customer_impacting is_true THEN set_priority P1

Второе правило уже увидит critical.

Это позволяет строить определение как понятный конвейер:

Нормализовать значения разных интеграций Добавить общие метки Выбрать владельца Выбрать priority и policies Настроить grouping и deduplication Принять решение suppress / pause / drop Поставить автоматизацию в очередь

Минус у подхода тоже есть: порядок становится частью логики.

Поэтому в execution trace сохраняются совпавшие условия, выполненные действия и значения до и после каждого изменения.

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

В условиях используются dotted paths к разрешённым частям контекста:

event.severity event.status labels.environment labels.application raw.alerts.0.labels.namespace variables.service route.id service.id team.id integration.source result.disposition

Движок читает JSON-объекты и индексы массивов, но не выполняет методы или произвольные выражения.

Основные операторы:

equals not_equals contains not_contains starts_with ends_with regex not_regex in not_in exists not_exists greater_than less_than greater_or_equal less_or_equal is_true is_false

Для логики доступны вложенные группы:

  • ALL — AND;

  • ANY — OR;

  • NONE — NOT.

Пример:

ALL ├── labels.environment equals production └── ANY ├── event.severity equals critical └── labels.priority equals p1

То есть:

production AND (critical OR p1)

Шаблоны тоже ограничены

Текстовые действия используют подстановки вида:

{{ labels.service | upper }}: {{ event.title | trim }}

Поддерживается небольшой набор детерминированных фильтров:

lower upper trim default replace truncate

Например:

{{ labels.cluster | default("unknown") | trim | lower }}

Если необязательное поле может отсутствовать, это следует явно обработать через default.

В противном случае ошибка шаблона попадёт в трассировку и будет обработана согласно on_failure действия.

У каждого действия есть одна из трёх стратегий ошибки:

Значение

Поведение

continue

Записать ошибку и перейти к следующему действию

stop_rule

Остановить действия текущего правила

stop_orchestration

Остановить всю оркестрацию

Для необязательного обогащения подходит continue.

Для выбора маршрута или разрушительного действия безопаснее остановить правило или всю оркестрацию, чем продолжать с частично изменённым событием.

Валидация выбранных сущностей

Недостаточно просто получить из правила числовой service_id. Во время выполнения IncidentRelay проверяет согласованность выбранных объектов.

Например, будут отклонены случаи, когда:

  • маршрут принадлежит другой группе;

  • route source равен sentry, а источник события — alertmanager;

  • выбранный сервис принадлежит другой команде, чем маршрут;

  • escalation policy или notification policy принадлежит другой команде;

  • выбранный объект был отключён или удалён после публикации версии.

Поведение после такой ошибки зависит от compatibility mode.

Два переключателя режима — и это не одно и то же

У определения есть runtime mode и compatibility mode. Поначалу их легко перепутать.

Runtime mode

Он отвечает на вопрос: влияет ли опубликованная версия на реальные события?

Режим

Что происходит

disabled

Production-события не вычисляются; доступны редактирование, validation и simulation

shadow

Опубликованная версия вычисляется и записывается, но её решения не меняют production

active

Допустимые решения применяются к реальной обработке

Для shadow и active нужна опубликованная версия.

Compatibility mode

Он отвечает на другой вопрос: как оркестрация делит ответственность с существующим lifecycle?

Режим

Что происходит

legacy

Существующая логика остаётся главным источником решений

hybrid

Явные решения оркестрации сохраняются, а старый lifecycle заполняет оставшиеся значения

orchestration

Оркестрация становится главным источником маршрутизации; требуется валидный route

Например, в hybrid:

Оркестрация явно установила priority=P1 → priority policy не заменяет это значение Оркестрация не выбрала notification policy → обычный механизм выбора policy продолжает работать

Если комбинация выбранных сущностей оказалась невалидной, hybrid может отклонить кандидата и продолжить legacy-обработку.

В режиме orchestration аналогичная ошибка блокирует дальнейшую обработку вместо fallback.

Для первого production-внедрения мы рекомендуем hybrid.

Отдельный крайний случай: конфигурация active + legacy не применяет решения оркестрации к production. Слово active здесь относится к runtime mode, но compatibility mode всё ещё оставляет старый lifecycle главным.

Название немного обманчивое, зато конфигурация безопасная. Иногда программное обеспечение шутит само, даже если разработчики не просили.

Simulator: проверить не только счастливый payload

Simulator вычисляет текущий draft изолированно.

Он не:

  • создаёт алерты;

  • отправляет уведомления;

  • вызывает webhooks;

  • меняет режим выполнения;

  • публикует версию;

  • изменяет production-данные.

Можно передать уже нормализованное событие или сырой payload поддерживаемой интеграции.

Во втором случае payload проходит через тот же зарегистрированный normalizer, который используется при production ingestion.

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

  1. Точное совпадение.

  2. Почти совпадающее событие, которое не должно пройти.

  3. Другое окружение.

  4. Другой source.

  5. Отсутствие необязательной метки.

  6. Статус resolved.

  7. Повторное событие, которое должно получить тот же dedup_key.

Результат симуляции содержит:

  • исходное нормализованное событие;

  • совпавшие правила;

  • condition trace;

  • значения до и после каждого действия;

  • итоговый контекст;

  • выбранные сущности;

  • disposition;

  • разницу между draft и active version.

Успешная симуляция доказывает, что движок смог выполнить определение. Она не доказывает, что бизнес-решение правильное.

Зелёный HTTP 200 вполне способен сообщить, что вы очень успешно направили все production-алерты команде стажёров.

Grouping и deduplication — тоже часть маршрутизации

Правильный владелец не спасает ситуацию, если каждый повтор создаёт новый алерт.

Для группы однотипных событий можно задать:

group_key: {{ labels.alertname }}: {{ labels.environment }} dedup_key: {{ labels.alertname }}: {{ labels.instance }} window_seconds: 900

Так события с одним alert name в одном окружении попадут в общую группу, а каждый instance сохранит собственный дочерний алерт. Повторный сигнал обновит нужный child alert.

Ключи должны быть стабильными.

Временная метка в dedup_key формально допустима, но фактически означает «создавай новый алерт при каждом запросе». Очень удобно, если ваша цель — нагрузочно протестировать дежурного инженера.

suppress, pause и drop — три разных решения

Эти действия легко объединить в голове как «не уведомлять», но последствия отличаются принципиально.

Действие

Результат

suppress

Алерт создаётся и остаётся видимым, но уведомления и эскалация подавляются

pause

Событие хранится как pending и активируется после задержки, если раньше не пришёл resolve

drop

Алерт и группа вообще не создаются

suppress подходит для событий, которые нужно сохранить для поиска или корреляции.

pause полезен для кратковременных сбоев. Например, можно подождать пять минут и отменить создание алерта, если за это время пришёл совпадающий resolve.

drop следует использовать только для сигналов без операционной ценности — например, точно определённого тестового heartbeat.

Пустое условие совпадает со всеми событиями. Поэтому catch-all вместе с drop, suppress, pause или обязательной маршрутизацией требует особенно осторожной проверки.

Catch-all с drop — очень эффективное средство против alert fatigue, примерно как демонтаж пожарной сигнализации против писка разряженной батарейки.

Асинхронные webhooks вместо произвольного кода

Если после совпадения правила нужно запросить диагностику, создать тикет или вызвать внутреннюю автоматизацию, используется переиспользуемое действие enqueue_webhook.

HTTP-запрос не выполняется внутри ingestion request. IncidentRelay ставит выполнение в очередь, а scheduler доставляет его асинхронно с timeout, retry и ограничениями безопасности.

Секретные заголовки хранятся зашифрованными и не возвращаются API. URL проверяются против SSRF, redirects повторно валидируются, а private network targets запрещаются или ограничиваются allowlist согласно конфигурации.

В simulation и shadow mode webhook не отправляется.

Иначе проверка нового правила могла бы создать несколько сотен вполне настоящих задач с заголовком TEST PLEASE IGNORE.

Что получилось в итоге

Global Orchestration дала нам единое место, где разнородные факты мониторинга превращаются в объяснимое операционное решение до начала paging:

  • интеграции могут сохранять собственные форматы payload;

  • общие правила нормализации не дублируются по сервисам;

  • ownership выбирается по содержимому события;

  • локальная логика остаётся в service orchestration;

  • каждое решение можно проверить в trace;

  • draft не влияет на production;

  • опубликованные версии неизменяемы;

  • simulation и shadow mode позволяют внедрять изменения без ставки на удачу.

IncidentRelay — open-source и self-hosted. Исходный код доступен на GitHub.

Подробное руководство по условиям, действиям, Simulator и shadow mode находится в документации Event Orchestration, а API — в отдельном руководстве.

Показать полностью 2
13

Мы тут сделали первый стабильный релиз IncidentRelay 1.1

Это open-source система для on-call дежурств и алертов, которую можно поставить у себя.

Если по-человечески: когда ночью что-то ломается, IncidentRelay помогает понять, кому звонить, куда отправлять уведомление, кто сейчас дежурный, почему алерт попал именно в эту команду, и что вообще произошло. Ну то есть занимается тем, что обычно в маленьких командах живёт в голове у одного человека, который “вроде помнит, как оно настроено”. Спойлер: он не всегда помнит.

Мы сделали IncidentRelay self-hosted, потому что не всем хочется тащить весь incident workflow во внешний SaaS. Иногда хочется просто поставить у себя, подключить Alertmanager/Grafana/Zabbix/Sentry/LibreNMS/что-нибудь-webhook, настроить команды, ротации, каналы и жить чуть спокойнее. Хотя “спокойнее” в мире on-call звучит как смелое заявление.

IncidentRelay Heartbeat

IncidentRelay Heartbeat

Что умеет:

- принимать алерты из разных систем мониторинга;
- маршрутизировать их по командам и сервисам;
- понимать, кто сейчас дежурит;
- слать уведомления в Mattermost, Slack, Telegram, email, browser push, webhook и даже voice call;
- делать ACK/Resolve;
- напоминать и эскалировать;
- учитывать maintenance windows;
- глушить шумные алерты через silences;
- показывать календарь дежурств;
- делать CalDAV/ICS-подписки;
- группировать похожие алерты;
- показывать Explain Trace: почему система решила именно так;
- отслеживать сервисы, зависимости и impact;
- проверять Heartbeats, когда задача должна была прислать “я жива”, но решила уйти в молчание.

За 5 месяцев от первой версии до 1.1 проект оброс довольно большим количеством функций. Начиналось всё с базового alert flow, Telegram-действий и фильтров. Потом понеслось: ротации стали многоуровневыми, появились escalation policies, сервисный каталог, SLI/SLO, Business Services, heartbeats и отдельная логика impact.

Самым сложным неожиданно оказался не “принять webhook и отправить сообщение”. Это как раз весёлая часть. Сложным оказалось понять, как правильно считать влияние сервисов друг на друга.

Вот есть сервис A, от него зависит B, от B зависит C, у C алерт, у A degraded, у B maintenance, где-то P2, где-то critical, а бизнес-сервис сверху должен показать понятный статус. И желательно не писать пользователю “всё горит”, если на самом деле горит только маленький угол. Но и не писать “всё нормально”, если этот маленький угол держит половину продукта. Тут начинаются настоящие разговоры с графом зависимостей. Иногда граф смотрит в ответ. Осуждающе.

Отдельно пришлось повозиться с визуализацией графа. Потому что граф сервисов в UI легко превращается в тарелку лапши: линии везде, подписи пересекаются, root cause где-то спрятался, downstream impact убежал за край экрана. Пришлось продумывать расположение, уровни, подсветку и то, как показать пользователю не просто красивую картинку, а полезную информацию.

Ещё одна штука, которой мы довольны, - Explain Trace. Это когда можно открыть алерт и увидеть: какой route сработал, какие matchers совпали, почему алерт сгруппировался, почему уведомление ушло или не ушло. Очень помогает в ситуации “почему меня разбудило в 03:17”, хотя честный ответ иногда всё равно “потому что ты дежурный, прости”.

В релизе 1.1 также есть Heartbeats. Это проверки для задач, которые должны периодически сообщать “я завершилась успешно”. Backup, ETL, watchdog, агент на сервере. Если ping не пришёл - создаётся обычный алерт. Есть multi-instance режим, чтобы один живой сервер не прикрывал пятерых молча умерших товарищей.

Разворачивается через Docker Compose, RPM, systemd или Helm. Маленькие установки могут жить на SQLite, для production лучше PostgreSQL. Лицензия MIT.

GitHub: https://github.com/roxy-wi/IncidentRelay

Сайт: https://incidentrelay.io/

Показать полностью 2
3

IncidentRelay месяц спустя: от маршрутизации алертов к полноценному on-call workflow

Чуть больше месяца назад я впервые рассказал об IncidentRelay, open-source и self-hosted системе для дежурств, маршрутизации алертов и эскалаций.

В первой версии основная цепочка уже работала:

Monitoring -> Route -> On-call -> Notification -> ACK / Resolve

IncidentRelay месяц спустя: от маршрутизации алертов к полноценному on-call workflow

С тех пор проект добрался до v1.0.21-beta. Цепочка стала длиннее, но пользоваться системой стало проще. В отличие от некоторых корпоративных процессов, здесь усложнение действительно пошло на пользу.

Не буду пересказывать весь changelog. Расскажу о нескольких изменениях, которые сильнее всего повлияли на продукт.

Дежурства стали похожи на настоящие

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

Поэтому в IncidentRelay появились многослойные ротации. У каждого слоя могут быть свои:

  • участники и приоритет;

  • временные ограничения;

  • часовой пояс;

  • правила передачи смены.

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

Расписание можно подключить к Google Calendar, Outlook, Apple Calendar и другим клиентам через ICS или read-only CalDAV. Пользователи также могут получать уведомления о предстоящих сменах.

Появился On-call Health. Он заранее ищет пустые слои, неактивных участников, разрывы в расписании, маршруты без получателя и проблемы с каналами уведомлений.

Лучше увидеть красный индикатор днём, чем обнаружить ночью, что единственный дежурный существует только в базе данных.

Двадцать алертов теперь могут стать одним инцидентом

Одна проблема редко присылает одно аккуратное сообщение. Обычно сначала жалуется база, потом API, затем очередь, а через минуту к обсуждению присоединяется всё, у чего есть доступ к Alertmanager.

Теперь IncidentRelay умеет группировать связанные события по сервису, окружению, кластеру, имени алерта и другим labels.

Для группы можно:

  • задержать первое уведомление;

  • настроить периодические обновления;

  • выполнить ACK или Resolve сразу для всей группы;

  • объединить несколько групп вручную;

  • оставить комментарии и сохранить историю расследования.

Исходные алерты при этом не теряются. Дежурный получает одну развивающуюся историю вместо серии сообщений с одинаковым смыслом и разной пунктуацией.

Появилось понимание того, что именно сломалось

Раньше IncidentRelay хорошо отвечал на вопрос «кому отправить алерт», но почти ничего не знал о самом объекте аварии.

Теперь в системе есть каталог сервисов. Для каждого сервиса можно задать владельцев, критичность, окружение, runbooks, ссылки, правила сопоставления с алертами и зависимости от других сервисов.

На основе зависимостей система показывает:

  • возможную первопричину;

  • затронутые сервисы;

  • путь распространения проблемы;

  • общий blast radius.

Также появилась аналитика: сгруппированные инциденты, объём сырых алертов, дедупликация, уровень шума и время реакции.

Это не замена observability-платформе. Задача скромнее: избавить дежурного от традиционного ритуала поиска актуального runbook среди wiki, старого чата и ссылки, которая «точно работала в прошлом квартале».

Инцидент больше не заканчивается на ACK

ACK сообщает, что алерт кто-то увидел. К сожалению, он не ремонтирует базу данных. Мы проверяли.

Поэтому в IncidentRelay появились:

  • приоритеты от P1 до P5;

  • автоматическое повышение приоритета по severity;

  • запрос дополнительных responders;

  • stakeholders и настройки их уведомлений;

  • комментарии и timeline;

  • maintenance windows.

Maintenance window можно привязать к группе, команде, сервису или маршруту. Во время работ система может отключить уведомления, не создавать новые инциденты или временно остановить эскалации.

Поддерживаются часовые пояса и повторяющиеся правила RFC 5545. Потому что любое простое окно обслуживания рано или поздно превращается в «каждый второй вторник, кроме праздников и последней недели квартала».

Теперь система объясняет свои решения

Самая заметная новая функция называется Alert Explain Trace.

Если алерт не дошёл или попал не в ту команду, больше не нужно вручную воспроизводить всю конфигурацию. IncidentRelay записывает этапы обработки входящего события.

В трассе видно:

  1. Был ли принят payload.

  2. Какой route совпал.

  3. Какой service был найден.

  4. В какую группу попал алерт.

  5. Сработали ли silence или maintenance window.

  6. Как выбрали дежурного.

  7. Какие уведомления были отправлены или пропущены.

Интеграция получает trace_id, по которому результат можно открыть в UI или запросить через API.

Для self-hosted продукта прозрачность особенно важна. «Система решила именно так» звучит гораздо убедительнее, когда рядом есть список причин, а не только уверенный зелёный индикатор.

Что получилось

За месяц IncidentRelay вырос из маршрутизатора алертов в более связный workflow:

Alert -> Route -> Service -> Group -> Priority -> Escalation -> On-call -> Responders -> Notifications -> Resolution

Проект всё ещё находится в beta и активно развивается. Впереди новые интеграции, улучшение аналитики и более простая установка. Но уже сейчас система умеет не только разбудить дежурного, но и объяснить, почему выбрала именно его. В мире on-call это почти проявление вежливости.

Буду рад обратной связи и примерам реальных расписаний. Чем страннее график, тем полезнее тестовый сценарий.

Показать полностью 1
11

IncidentRelay - открытая система для организации дежурств и маршрутизации оповещений

Опубликован проект IncidentRelay, развивающий открытую систему для организации дежурств, маршрутизации оповещений и сопровождения инцидентов, запускаемую на собственном сервере (self-hosted). Проект ориентирован на SRE, DevOps и инфраструктурные команды, которым требуется локально разворачиваемая альтернатива SaaS-сервисам для управления дежурством (on-call management), применения политик эскалации и реагирования на инциденты. Код проекта написан на Python и распространяется под лицензией MIT.

IncidentRelay принимает события из систем мониторинга, сопоставляет их с правилами маршрутизации и доставляет уведомления ответственным дежурным или командам. В системе реализованы расписания дежурств, ротации, переопределения смен, подтверждение получения инцидента, перевод инцидента в resolved, напоминания, эскалации и silences для подавления известных или плановых срабатываний.

Поддерживается приём событий из Prometheus Alertmanager, Zabbix и произвольных webhook-ов. Для отправки уведомлений предусмотрены каналы Mattermost, Telegram, email, webhook и голосовые провайдеры. В Mattermost и Telegram уведомления могут содержать действия для подтверждения и решения проблемы, что позволяет обрабатывать инцидент без перехода в отдельный интерфейс.

В IncidentRelay предусмотрена модель разделения доступа по группам и командам. Это позволяет разграничить видимость расписаний, маршрутов, каналов уведомлений и алертов между различными командами. Для автоматизации доступен HTTP API, а для интеграций используются bearer-токены и route-токены.

Проект может применяться как промежуточный слой между системами мониторинга и каналами уведомлений: Alertmanager или Zabbix отправляет событие в IncidentRelay, после чего система определяет команду, текущего дежурного, применяет правила маршрутизации и отправляет уведомление в нужный канал. Для неподтверждённых инцидентов могут выполняться повторные напоминания и эскалация на следующего участника ротации.

Показать полностью 3
18

Улучшения в RMON: расширенный Ping, группировка алертов и трассировка через MTR

Нам часто пишут пользователи, которые хотят мониторить качество каналов связи — не просто проверять “доступен ли хост”, а действительно оценивать стабильность сети и реагировать на деградации. Один из таких пользователей недавно подключил мониторинг для нескольких регионов, и его запрос дал нам полезный импульс для доработок.

Рассказываем, какие улучшения появились в RMON.


Ping стал умнее

Раньше проверка ping в RMON отправляла один пакет — это было достаточно для грубой оценки, но плохо отражало реальное состояние канала. Теперь всё иначе:

  • Можно указать количество ICMP-пакетов в настройках проверки.

  • Система собирает и отображает:

    • min RTT

    • max RTT

    • avg

    • mean

Это особенно полезно, если канал нестабилен: одиночный ping может случайно показать “всё хорошо”, хотя на деле теряются пакеты или резко плавает задержка.

| Возможность | SmokePing | RMON |

|-----------------------------|----------------|---------------------------|

| Графики RTT и потерь | ✅ Да | ✅ Да |

| Группировка алертов | ❌ Нет | ✅ Да |

| Настраиваемое кол-во пакетов| ✅ Частично | ✅ Да |

| Интерактивный веб-интерфейс | ❌ (CGI) | ✅ Современный UI |

| MTR из разных регионов | ❌ Нет | ✅ Да |

| Проверки из нескольких точек| ❌ (1 сервер) | ✅ Геораспределённые агенты |

| Telegram/Slack уведомления | Только через внешние скрипты | ✅ Встроено |

| API | ❌ Ограничен | ✅ Полноценный REST API |

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

RMON же изначально создавался с упором на:

  • простую установку;

  • удобный интерфейс;

  • встроенные нотификации и API;

  • и главное — распределённый мониторинг из разных географий.

Группировка алертов

Пользователи с несколькими агентами в разных регионах сталкивались с таким сценарием:

"Падает один хост — и мы получаем 5+ одинаковых алертов от каждого региона".

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

  • Вы получаете единое уведомление со списком всех регионов, где обнаружена проблема.

  • Упрощается логирование, снижается "шум" в системах алертинга (Telegram, Slack и т.п.)

MTR на месте

Мы добавили возможность запускать MTR (traceroute с расширенной статистикой) из конкретного региона:

  • Прямо из веб-интерфейса или API

  • Можно быстро проверить маршрут от нужного агента до целевого хоста

Это особенно удобно при отладке проблем между регионами, в CDN, или при работе с провайдером.


Что дальше

Мы продолжаем развивать RMON как инструмент для распределённого мониторинга, ориентированный на:

  • телеметрию от агентов из разных регионов;

  • гибкую конфигурацию проверок;

  • удобную интеграцию с Telegram, Slack, Prometheus, Zabbix и другими системами.

Если вы хотите точно знать, где и когда у вас реально деградирует сеть — попробуйте RMON: https://rmon.io

Показать полностью 2
22

365 дней спустя, или жизнь еще одного мониторинга

Помню в детстве, перед началом летних каникул, казалось, что лето никогда не кончится - 3 месяца где-то рядом с бесконечностью. А сейчас... Оказывается мы уже больше года разрабатываем RMON, первый коммит в Github был 15 марта 2024 года. Вжух и один год жизни пролетел. Ладно, хватит разговаривать на скуфском - это было маленькое вступление для подведения небольшого итога года работы. Вперед!

Terraform

Изначально мы его не планировали, но впереди была большая инсталляция и показалось, что настраивать кучу агентов руками и серверов, такое себе. Создавать проверки через Terraform оказалось очень удобно.

Одна проверка с нескольких агентов

Изначально мы планировали эту возможность, но реализовали, только, спустя полгода. У фичи достаточно сложная логика, по этому прокрастинировали, как можно дольше :). Получилось, вроде неплохо:

Переписали HTTP проверки на libcurl

Изначально использовали Python requests, так как было проще всего начать с нее, но мы сразу понимали, что requests не подходит из-за скорости работы и не возможности снимать HTTP метрики. В поисках решения нашли libcurl. Оказывается, curl - это не просто консольная утилита, с помощью, которой можно скачать файл и дернуть ifconfig.io, но и мощная библиотека для выполнения разных запросов. Кто ж знал.

С помощью Pycurl с libcurl достаточно легко и удобно работать из Python:

class CurlHttp:

def __init__(self, **kwargs) -> None:

...

def curl(self):

try:

buf = io.BytesIO() # We need to measure download time.

c = pycurl.Curl()

self.set_http_method(c)

self.set_curl_options(c, buf)

except pycurl.error as e:

raise Exception(f'Cannot set curl http_{self.check_id} {e.args[1]}')

try:

c.perform()

except pycurl.error as e:

self.reset_http_results(e.args[1])

except Exception as e:

self.reset_http_results(e)

return c, buf

def set_http_method(self, c):

http_methods = {

'get': c.HTTPGET,

'post': c.POST,

'put': c.PUT,

'head': c.NOBODY

}

custom_http_methods = {

'patch': "PATCH",

'delete': "DELETE",

'options': "OPTIONS"

}

if self.http_method in http_methods:

c.setopt(http_methods[self.http_method], 1)

else:

c.setopt(c.CUSTOMREQUEST, custom_http_methods[self.http_method])

def set_curl_options(self, c, buf):

c.setopt(c.URL, self.url)

c.setopt(c.DNS_CACHE_TIMEOUT, 0) # disable dns cache.

c.setopt(c.FORBID_REUSE, 1) # disable dns cache.

c.setopt(c.FRESH_CONNECT, 1) # disable dns cache.

c.setopt(c.HEADERFUNCTION, self.headers.write)

c.setopt(c.WRITEFUNCTION, buf.write)

c.setopt(c.TIMEOUT, self.timeout)

c.setopt(c.USERAGENT, 'RMON-bot')

# c.setopt(pycurl.VERBOSE, 1)

# c.setopt(pycurl.DEBUGFUNCTION, self.debug_curl)

...

if self.is_https == 'https':

c.setopt(c.OPT_CERTINFO, 1)

if self.ignore_ssl_error:

c.setopt(c.SSL_VERIFYPEER, 0)

c.setopt(c.SSL_VERIFYHOST, 0)

При переходе на libcurl удалось запустить несколько тысяч HTTP проверок на довольно слабенькой ВМ, вместо сотен на requests. Кстати, так же с помощью libcurl удалось реализовать SMTP проверки!

Больше параметров богу параметров!

Разве необходимо много параметров, чтобы проверить работает ли сайт? Как оказалось - да, надо много! Сейчас их много, что аж на экран не помещается (классная метрика, достаточности "что аж на экран не помещается", да?):

Но надо еще больше. Как минимум сейчас не хватает:

  1. Важности алертов (warning, critical)

  2. Инверсивная проверка

  3. Возможность принимать несколько статус кодов ответа

  4. Авторизация.

Нет предела совершенству и есть куда развиваться.

Что-то вроде итога

Это конечно же не все изменения что были проделаны, но лишь то что может быть интересно пользователям. Что еще хотелось бы отметить:

  1. Добавление поддержки PostgreSQL

  2. Возможность писать логи в JSON

  3. Пуш метрик в VictoriaMetrics

  4. Свои CSS стили для Status pages

  5. Стабилизация проекта и более читаемый вывод ошибок

  6. Переписали всю документацию на сайте

Кто захочет попробовать и потестить, не смотрите на прайс, просто напишите мне ;).

Показать полностью 2
15

GUI — это хорошо, но большие дяди хотят IaC

Вечерело, накрапывал морозный дождь… шел 7-й год разработки Roxy-WI. Понимание необходимости автоматизации пришло давно, поэтому был разработан API. Он был, скажем так, кривой и местами нелогичный, но работал. После создания RMON и написания к нему "нормального" API было решено создать API и для Roxy-WI с поддержкой CRUD и Swagger.

GUI — это хорошо, но большие дяди хотят IaC

После консультаций с опытными разработчиками API было принято решение написать его на Flask с использованием views и перейти на JWT-авторизацию. Старый API был разработан на фреймворке Bottle, но поскольку Roxy-WI был переписан на Flask, наличие двух фреймворков в одном проекте не казалось хорошей идеей. На тот момент я уже довольно хорошо изучил Flask. JWT был внедрён, чтобы объединить авторизацию в WEB-версии и API, так как до этого в API использовалась самописная авторизация.

И вот, спустя месяц была выпущена 8 версия! Помимо API и JWT также была внедрена валидация входящих данных на базе Pydantic. Pydantic оказался очень мощным инструментом, но я сопротивлялся использованию библиотеки очень долго - сам уже не знаю почему. И вот, API готов, но необходима документация, поэтому был нужен Swagger. Описывать самому структуру чуть-чуть (очень сильно, капец, как сильно, я же не YAML разработчик) не хотелось. И я решил попробовать ИИ, который предлагает JetBrains за 10 у.е. в месяц (зря что ли плачу?!). Так вот, роботы поработят нас еще не скоро и без работы не оставят :-p. В итоге получилось, правда пришлось поматериться пару вечеров.

Редактирование конфиг

Редактирование конфиг

API готово, значит пора писать Terraform-провайдер. Долго ли, коротко ли, но первая версия была выпущена и там уже и я подключился к разработке провайдерая и обратился к за помощью. Rocky_Break написал первую версию провайдера и прислал мне книгу по Go. Оказалось, что мало написать API, оно должно еще быть консистентным. Долго ли, коротко ли, но первая версия была выпущена и там уже и я подключился к разработке провайдера (как же не удобно писать на Go, после Python :`( ).


Кстати! Чтобы была возможностью управлять HAProxy полностью терраформом было необходим доработать работу с конфигурациями HAProxy - теперь после "накликивания" себе конфига, его можно так же кликами изменить.

Так что теперь есть IaC вэй для создание HA-кластеров с возможностью создание UDP и HAProxy балансиров ;).

Показать полностью 2
46

Как случайно написать систему мониторинга (еще одну)

Интересно как-то у меня выходит - мои пет проекты получаются случайно. Нет финальной цели, есть только импульс: "О! А это звучит интересно, как же это можно сделать?". И все: "сон для слабаков", "пиво в пятницу? конечно не буду!" и все в таком духе. Как говорится - есть только путь. И это история началась примерно так же... Вечерело На работе мне было нечем заняться, нужно было поставить некоторое количество серверов и сервисов на мониторинг, но из-за большой бюрократии в компании сделать это было не просто, да и сама мониторинговая система работала на базе SNMP, вот только где взять SNMP у самописного сервиса? И тут в голову пришла гениальная идея попробовать самому. К тому же сложным это не выглядело: мониторинг портов, http и куда-нибудь отправить алерт. "Почему бы и не да" - подумал я, к тому же больше познаю Python. И так появился он...

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

Как случайно написать систему мониторинга (еще одну)

Спустя пару лет я вспомнил о том, что у меня был самопальный мониторинг и почему бы его не добавить в мой основном пет проект, в Roxy-WI. Сказано - сделано. Ведь чем больше функций тем лучше! И так получилось, что со временем мониторингу стало "тесно" в стенах Roxy-WI: с одной стороны надо развивать веб интерфейс, с другой мониторинг, чтобы не было перевеса в одной из сторон я решил вынести мониторинг в отдельный проект. Приветствуйте - RMON! Да... с именами у меня так себе.

RMON история проверок

RMON история проверок

Пф... еще один мониторинг, какой уже по счету?

100500? Да, пожалуй так, так же наверное говорили про Prometheus в свое время: "Зачем ведь есть Zabbix?!", а до этого и про Zabbix: "Зачем ведь есть SNMP, MRTG и Nagios?!". Да, есть, но почему нет? Вдруг получится сделать в чем-то лучше. Конечно я пока не ставлю RMON в ряды с этими системами мониторинга, пока не ставлю. А вдруг получится сделать чем-то лучше ;)?

В чем я вижу "конкурентное преимущество" RMON над существующими системами мониторинга, прежде всего над Prometheus (как промышленный стандарт) и Uptime Kuma (как более близкий по функционалу)? Основных, киллер фич, как по мне, минимум пять:

  1. Агенты - можно установить несколько штук как внутри периметра, так и снаружи и мониторить доступность из нескольких точек. Агенты можно объединять в "регионы" для балансировки чеков, шарить между группами.

  2. API.

  3. Ролевая модель доступа к агентам.

  4. Простота установки и настройки, Web интерфейс и Status pages.

  5. 7 метрик HTTP соединения + мониторинг протухания SSL серта.

Так же есть мониторинг Ping-ом, DNS записей и TCP. В будущем планирую расширять возможности проверок.

Как случайно написать систему мониторинга (еще одну)

Мы все это уже видели

Да, агенты по сути реализованы в Prometheus и Blackbox exporter: Blackbox exporter-ы тоже можно поставить в разных точках и мониторить от туда, +- тоже самое. Да, Uptime Kuma даже легче поднимается и тоже имеет web интерфейс. API можно заменить тем же Ansible, например. Но есть одно но - этого нет и там и там. Нельзя отдать playbook человеку и сказать: "Вон на тех экспортерах ничего не создавай, тебе низя!", надо будет поднимать несколько инстансов, чтобы разделить доступ, плюс его надо обучить работать с Ansible. А еще нельзя автоматизировать работу с проверками. Точнее скорей всего можно, но это костыли и высокий уровень входа.

Как итог и тем кто будет писать: "Web отстой, консоль наше все!"

Да, временами так и есть, а временами - нет. Порой даже самые передовые и технологически правильные решения не подходят. Где-то жалко тратить время и ресурсы, где-то неохота погружаться, а где-то надо "через 2 минуты, чтобы все было". А временами передовые решения просто не нужны и удобней работать с тем что попроще. Надо исходить из конкретной ситуации, а не загонять всех в рамки: "%UserName%, используй только %ProgrameName% во всех случаях жизни!".

P.S. если захотите попробовать, то пишите, с удовольствием покажу/объясню :).

Показать полностью 3
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества