Гибкий open-source инструмент alertmanager-jira

Привет, хабровчане!

Если вы работаете с мониторингом в Prometheus или VictoriaMetrics, то наверняка знаете, и Alertmanager для убобного конфигурирования алертов. Но ведь круто было бы их трекать в привычнй Jira, не правда ли? А что если автоматизировать это полностью — с назначением исполнителей, метками, компонентами и даже шаблонами для описаний? Знакомьтесь с alertmanager-jira — классным инструментом для обеспечения интеграции AlertmanagerPrometheus или VictoriaMetrics). Это Alertmanager (webhook) плагин, который создаёт и управляет задачами в Jira на основе алертов, с акцентом на гибкость. Написан на Quarkus, лёгкий и готов к деплою в docker (podman).

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


Зачем нужна интеграция

В мире DevOps и SRE мониторинг — это не только дашборды, но и оперативное реагирование. Jira здесь часто выступает центральным хабом для задач (да и вообще наиболее популярный трекер задач, как мне кажется). Вот ключевые причины, почему такая интеграция — must-have:

  1. Многие используют Jira в разработке и поддержке процессов. В командах разработчиков или SRE Jira — стандарт для багов, фич и инцидентов. Когда алерт срабатывает (скажем, на перегрузку CPU или дрейф данных), его нужно быстро превратить в тикет. Alertmanager-jira делает это автоматически: алерт → webhook → Jira-issue с полным контекстом. Это снижает MTTR и избавляет от рутины.

  2. Также удобно для ITSM-процессов, например запросов пользователей, инцидентов, обеспечения качества данных (Data Quality) и т.д. В ITIL-подобных workflows Jira идеальна для запросов пользователй, инцидентов и compliance-задач вроде data quality. Алерты на аномалии в ETL или BI-пайплайнах ночью? Утром в Jira уже готовый тикет с лейблами (labels), компонентами, исполнителями, командами... А дальше просто уже идём по процессу задачи (workflow) и строим живые дашборды

  3. Было б здорово иметь полный контроль над задачами без самописных скриптов. Представьте: назначить исполнителя (assignee) по ролям, задать любые поля (даже кастомные), использовать шаблоны для динамического описания и избежать дубликатов через JQL-поиск. Именно это даёт alertmanager-jira — гибкость без enterprise-ценников.

Имеющиеся альтернативы и почему потребовалось новое решение

Многие знают jiralert от prometheus-community — это webhook-ресивер для Alertmanager, который создаёт задачи по group_key алертов. Он классный для базовых сценариев: поддерживает Go-шаблоны для полей, авто-разрешение и переоткрытие задач. Но у него ряд серьёзных недостатков, которые мы ощутили на практике:

  1. Очень ограниченное количество настроек (переоткрывать или нет, шаблон, ну ещё парочку). Конфиг по ресиверам, но без глубокого контроля над полями — всё через YAML с базовыми шаблонами. Нет нормальной поддержки кастомных полей или динамических JQL-запросов для обновлений.

  2. Очень длинный хеш алерта для идентификации, такой, что часто даже рушит интерфейс. Работать очень неудобно. Хеш по group_key может быть огромным, ломая UI Jira. На одном из предыдущих мест работы мы даже специально патчили его, чтобы укоротить.

  3. Развивается не активно — есть баги открытые аж с 2018 года. Проект под MIT, с 30+ контрибьюторами, но обновления редкие — последние коммиты не меняют картину существенно.

Других альтернатив практически нет: на рынке либо тяжёлые дорогие тулы вроде PagerDuty (ничего не могу сказать плохого) с Jira-интеграцией, либо пишут что-то сами. Нам же очень хотелось иметь полный контроль над задачами — на кого назначить, какие метки и компоненты указать... да и вообще, использовать любые поля! Именно с этим прицелом и был сделан alertmanager-jira: можно настроить как дефолты (например в какой инстанс слать, какой проект использовать и тип задачи), так и управлять любым этим параметром, или заполняемым полем в каждом алерте, поиск по JQL для избежания дублей, возможность комментировать задачи, если проблема такая уже была создана и задача не закрыта.

Как использовать

Проект готов к быстрому старту: есть docker-образы на hub.docker.com, и они собираются с новыми релизами автоматически.

Запуск в контейнере

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

podman run -it --rm --name alertmanager-jira \
    --env JIRA_URL=https://your-jira.com \
    --env JIRA_USERNAME=service-account \
    --env JIRA_PASSWORD=your-token \
    -p 8080:8080 \
        hubbitus/alertmanager-jira:latest
Скрытый текст

Я люблю podman, особенно rootless. Но если вы используете docker, просто поменяйте podmandocker, нет никакой разницы в запуске

Настройка Alertmanager

В alertmanager.yml добавляем назначение (receiver):

receivers:
  - name: 'jira'
    webhook_configs:
      - url: 'http://your-host:8080'
        send_resolved: true  # Для обработки resolved-алертов

Пример конфигурирования алертов

Как уже упоминал вначале статьи, упор на гибкость: разными способами можно задать абсолютно любое поле, и можно использовать шаблоны! Для указания полей, относящихся к нему, используются поля с префиксом jira__. Они задаются в правилах (rules) Prometheus (или VictoriaMetrics) указываем в разделах labels/annotations.


Пример в prometheus-rules.yml:

groups:
- name: example
  rules:
  - alert: HighCPU
    expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
    for: 1m
    labels:
      severity: critical
      jira__field__severity: High  # Поле priority в Jira
    annotations:
      summary: "High CPU on {{ $labels.instance }}"
      description: "CPU usage above 80%."
      jira__project_key: OPS  # Ключ проекта
      jira__issue_type_name: Incident  # Тип задачи
      jira__field__assignee: oncall-sre  # Исполнитель
      jira__field__labels: 'monitoring, cpu, alert'  # Массив через запятую
      jira__field__component_s: 'DevOps+infrastructure, DQ-issues+alerts'  # Нормализация для "Component/s"
      jira__field__name__1: 'Custom Field'  # Пара name/value для кастомных
      jira__field__value__1: 'Some dynamic value: ${context.alert.severity}'  # Шаблон!

Уже упоминал, чтобы не повторять одно и то же в каждом алерте, рекомендую задать дефолты. Например, в alert_relabel_configs файла prometheus.yml:

alerting:
  alert_relabel_configs:
    - source_labels: [__alert_severity]
      target_label: jira__field__severity
      regex: critical;High
    - target_label: jira__project_key
      replacement: OPS

В любом алерте, если нужно, можете переопределить эти значения - там они будут иметь приоритет.

В любых полях можно использовать шаблоны с синтаксисом Groovy SimpleTemplate и подстановки вроде:

  1. ${context.alert.fingerprint} для хэша

  2. ${context.jiraProject.name} для метаданных.

  3. Поиск уже существующих задач, которые стоит прокомментировать на JQL: (labels = "alert[${context.alert.hashCode()}]" AND statusCategory != Done).

Я не буду полностью переносить сюда ридми, чтобы не растягивать, в нём я старался привести примеры, указать 3 возможных способа настройки, там же есть podman-compose чтобы поднять весь стек для разработки и отладки, просто загляните в проект. Если чего-то не хватает, в тестах можно также подсмотреть примеры.

Как сделано и что можно было бы улучшить

Под капотом — Java + Groovy на Quarkus. Используется официальный SDK от Atlassian для Jira API.

Имеются автоматические тесты: модульные для парсинга, интеграционные на внешнем инстансе Jira. Стоит заметить, однако, что автотесты не запускаются на CI. Знаю, что это очень плохо, но к сожалению Jira — не бесплатный продукт, и его так просто не поднимешь в testcontainers — требуется лицензия. И хотя временную её можно иногда получить у них на портале (не уверен, что это сейчас возможно вообще для России), всё равно вводить вручную, и она временная, да ещё и именная, требуется замена периодически... Поэтому сейчас тесты сделаны так, что запускаются на отдельно развёрнутый инстанс. Очень хотелось бы это конечно изменить, но «хороших» путей не вижу.

Обратная связь только приветствуется!

Alertmanager-jira — открытый проект под Apache 2.0, с фокусом на гибкость для реальных команд. Мы уже 2 года используем решение в продакшене. Конечно были незначительные баги, которые мы исправили, но в целом всё отлично — это стало основной автоматизации обслуживания алертов по данным дата платформы.

Предложения и пожелания, а также багрепорты в проекте GitHub приветствуются!

P.S. А для тех, кто уже переходит на отечественные решения, планирую скоро рассказать про подобное решение на EvaTeam, если конечно кому-то интересно.

Комментарии (6)


  1. Z55
    09.10.2025 05:18

    Честно говоря, не очень понятно, это замена классическому алертменеджеру?

    Ну и несколько моментов:

    Очень ограниченное количество настроек (переоткрывать или нет, шаблон, ну ещё парочку). Конфиг по ресиверам, но без глубокого контроля над полями — всё через YAML с базовыми шаблонами. Нет нормальной поддержки кастомных полей или динамических JQL-запросов для обновлений.

    А что ещё нужно? Можете рассказать про какую-то киллер-фичу, которая есть у alertmanager-jira, но нет у jiralert? И что значит "нет нормальной поддержки кастомных полей"? Такого недостаточно "customfield_13011: {"value": "Другое"}"? Конфиг через yaml. Но вроде и в статье тоже yaml?

    Очень длинный хеш алерта для идентификации, такой, что часто даже рушит интерфейс. Работать очень неудобно. Хеш по group_key может быть огромным, ломая UI Jira. На одном из предыдущих мест работы мы даже специально патчили его, чтобы укоротить.

    Даже с активным флагом hash-jira-label ? Но тут больше вопросы к создателям jira, ибо если в поле 255 символов, и полное заполнение поля ломает разметку, то выглядит как баг.


    1. Hubbitus Автор
      09.10.2025 05:18

      Честно говоря, не очень понятно, это замена классическому алертменеджеру?

      Ни в коем случае! Это кракраз интеграция с ним, чтобы алерты из него в JIRA класть. Это альтернатива jiralert.

      А что ещё нужно? Можете рассказать про какую-то киллер-фичу, которая есть у alertmanager-jira, но нет у jiralert?

      Например, попробуйте лейблы указать в jiralert для задачи, исходя из значений алерта. Никак. Или записать их значение в компонент. Или указать какие задачи переоткрывать, а какие комментировать...

      Даже с активным флагом hash-jira-label ? Но тут больше вопросы к создателям jira, ибо если в поле 255 символов, и полное заполнение поля ломает разметку, то выглядит как баг.

      Во-первых, поле label это теги, для коротких литералов вроде alert, airflow, serviceX. Оно не предполагает что там будет текст произвольной длины. Обработать на UI и как-то сократить, конечно могли бы и на стороне Jira, не спорю, но почему-то я думаю они даже не предполагали что кто-то туда будет главку из Онегина писать.
      Но, во вторых, тут важно, другое. Не всегда именно такая идентификация нужна. Например, у нас часть алертов идентифицируется как fingerprint, который сам же alertmanager и формирует. Он стабильнее, и не включает значение value алерта, если вы его используете в label, например. А часть идентифицируются вообще иначе, у нас в практике есть скажем по лейблу dag:{some_name}. Здесь вы можете это настроить как хотите. В jiraalert - не получится.


      1. Z55
        09.10.2025 05:18

        Например, попробуйте лейблы указать в jiralert для задачи, исходя из значений алерта. Никак. Или записать их значение в компонент. Или указать какие задачи переоткрывать, а какие комментировать...

        Лейблы мы не используем, jiralert кладёт туда хеш, поэтому не мешает.
        Компоненты также не используем.
        "Переоткрывать или комментировать" - это мы настраивали флагами и переходами в jira. Но у вас думаю у вас это можно более гибко настроить, надо посмотреть как.

        В любом случае, спасибо за продукт! Возможно когда дойдут руки, потестируем, сравним с jiralert.


        1. Hubbitus Автор
          09.10.2025 05:18

          "Переоткрывать или комментировать" - это мы настраивали флагами и переходами в jira. Но у вас думаю у вас это можно более гибко настроить, надо посмотреть как.

          Тут думаю некоторое недопонимание произошло того что я выше сказал. Я имел в виду что, например, случай, когда была создана задача в джире о проблеме из алерта. Она висит, какое-то время открытой, её никто не берёт. Вы настраиваете в алертменеджере в алерте чтобы он скажем каждый день повторялся (одна опция), и в джиру можно в задачу добавлять что-то вроде "проблема до сих пор актуальна" (а можно и более сложный шаблон сделать, скажем указать количество часов актальности проблемы или что-то подобное). Этот "пинг" исполнителю отзовётся в почте - вдруг забыл? У нас ещё и в чатики ГидМост приходит, но это отдельная история.

          И спасибо за отклик! Буду рад фидбеку, если попробуете


          1. Z55
            09.10.2025 05:18

             в джиру можно в задачу добавлять что-то вроде "проблема до сих пор актуальна" 

            Мы специально отключили авто резолв, ибо если инцидент был, его надо разбирать, даже если проблема уже не актуальна. Как говорится, "у любой проблемы должно быть имя, фамилия и должность" - это про нас ))

            Но фича интересная, согласен


            1. Hubbitus Автор
              09.10.2025 05:18

              Я такого же мнения придерживаюсь! Мы тоже отключили авторезолв. Но вот комментарий, например о том что проблема больше не актальна, или дополнительные данные по алерту (скажем сколько ещё неразобранных сообщений в качка топике или количество упавших дагов, или количество ошибок и т.д.), может быть весьма полезна тому кто будет разбирать.