abot: прокси Alertmanager для уведомлений в Telegram и Mattermost

Published: 2026-05-12

abot — небольшой Go-сервис, который стоит между Alertmanager и каналами уведомлений. Alertmanager шлёт один webhook; abot раздаёт его в Telegram и Mattermost с нужным форматированием, логикой повторов и поддержкой прокси.


Почему не использовать встроенные receivers Alertmanager

У Alertmanager есть нативные Telegram и Slack receivers, но:

  1. Нативный Telegram receiver не поддерживает HTML-шаблоны с нужным нам форматированием.
  2. Формат webhook у Mattermost отличается от Slack, а нативного Mattermost receiver нет.
  3. On-prem кластеры не могут достучаться до api.telegram.org без HTTP-прокси. Настройка этого прокси в Alertmanager влияет на все receivers, не только Telegram.
  4. abot — единая точка управления логикой уведомлений: чтобы добавить новый канал (PagerDuty, email), достаточно изменить abot, а не конфиг Alertmanager.

Архитектура

Alertmanager
    │  POST /alert (формат webhook Alertmanager)
    ▼
abot (port 9444)
    ├── Telegram: api.telegram.org (через HTTP-прокси, если настроен)
    └── Mattermost: chat.example.com/hooks/...

abot запускается как Deployment в namespace observability на каждом кластере.


Helm-чарт

Кастомный чарт лежит в charts/abot/. Ключевые values:

yamlreplicaCount: 1
image:
  repository: registry.example.com/docker/iac/prometheus/abot2
  tag: v0.78
service:
  port: 9444
  targetPort: 9100
serviceMonitor:
  enabled: true
  namespace: observability
  interval: 30s
  metricRelabelings:
    - sourceLabels: [__name__]
      regex: 'abot_.+'
      action: keep
resources:
  limits:
    cpu: "800m"
    memory: "256Mi"
  requests:
    cpu: "200m"
    memory: "128Mi"

Конфигурация Alertmanager для abot

yamlalertmanager:
  enabled: true
  config:
    receivers:
      - name: abot
        webhook_configs:
          - url: "http://abot.observability.svc.cluster.local:9444/alert"
            send_resolved: true
    route:
      receiver: abot
      group_by: ["alertname", "cluster", "namespace"]
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 4h

send_resolved: true гарантирует, что abot получит уведомление при закрытии алерта. group_by предотвращает шквал сообщений от одного шумного инцидента.


Конфигурация прокси для Telegram

yamlconfig:
  telegram:
    bot_token: "${TG_BOT_TOKEN}"
    chat_id: "-1003960777636"
    proxy: "http://10.16.91.109:3128"
    parse_mode: "HTML"

Прокси — внутренний экземпляр tinyproxy в on-prem сети. Для YC-кластеров (sre, loadgds, demo) прокси не нужен — там есть прямой доступ в интернет. Patch для YC-окружений убирает поле proxy.


Формат сообщений

abot рендерит payload Alertmanager с помощью Go-шаблонов. Telegram-сообщение использует HTML:

🔴 · CRITICAL · <a href="https://grafana.infra.test.antonnovikov.com">dashboard</a>

🖥 dev
📦 elasticsearch · elasticsearch-master-0
💬 JVM heap usage above 85% for 5 minutes
⏰ 2026-08-25 14:32:01

Mattermost-сообщение использует Markdown с attachment для цвета:

json{
  "attachments": [{
    "color": "#cc0000",
    "text": "🔴 **CRITICAL** · [dashboard](...)\n🖥 `dev`\n📦 `elasticsearch`\n💬 JVM heap..."
  }]
}

Цвета по severity: #cc0000 (critical), #ff8c00 (warning), #00cc44 (resolved).


Конфигурация abot по окружениям через патчи

Токен бота и chat ID в каждом окружении свои (разные Telegram-группы для dev и продакшна):

yaml# projects/dev/kustomization/hub/patches/abot.yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: abot
  namespace: dev
spec:
  values:
    config:
      telegram:
        chat_id: "-1009999999999"   # чат команды dev
      mattermost:
        webhook_url: "https://chat.example.com/hooks/dev-channel-hook"

Критические продакшн-алерты идут в отдельный высокоприоритетный чат.


Собственные метрики abot

Метрика Описание
abot_notifications_total{channel,status} всего уведомлений по каналу и результату
abot_retry_attempts_total сколько повторных попыток понадобилось
abot_notification_duration_seconds задержка доставки по каналу

PrometheusRule для алерта при ошибках доставки:

yaml- alert: AbotNotificationFailed
  expr: increase(abot_notifications_total{status="failed"}[15m]) > 3
  for: 0m
  labels:
    severity: warning
  annotations:
    summary: "abot не смог доставить {{ $value }} уведомлений за 15 минут"

Отладка проблем с доставкой

bash# Логи abot
kubectl logs -n observability deploy/abot

# Ручной тест webhook
kubectl port-forward -n observability svc/abot 9444:9444
curl -X POST http://localhost:9444/alert \
  -H "Content-Type: application/json" \
  -d '{"alerts":[{"status":"firing","labels":{"alertname":"TestAlert","severity":"warning"},"annotations":{"summary":"Test"}}]}'

Если Telegram недоступен из пода, в логах будут ошибки соединения с api.telegram.org. Решение: проверить настройку прокси или убедиться, что tinyproxy запущен на нужном адресе.