Оповещения
Раздел «Оповещения» связывает правила с каналами доставки, чтобы команда узнавала о новых проблемах, регрессиях и всплесках без постоянного мониторинга дашбордов. Открывается по значку колокольчика в левой рельсе или напрямую по /projects/{id}/alerts.
Это страница про алерты по проблемам (issues). Пороговые алерты по числовым метрикам настраиваются отдельно — см. Оповещения по метрикам; уведомления по ним уходят в те же каналы, что описаны здесь.
Кому что доступно
Три правила по проблемам (новый issue, регрессия, всплеск) — операционная настройка: смотреть и менять их может любой оператор проекта — owner/admin организации либо обычный участник команды, привязанной к проекту, см. Команды и роли.
Каналы доставки — другое дело: их получатель и секрет — это учётные данные и персональные данные, а не операционная настройка, поэтому создавать, изменять, удалять канал и нажимать «Тест» может только owner/admin. Оператор проекта, не являющийся owner/admin, всё равно видит таблицу каналов — чтобы отличить каналы друг от друга при настройке правила, — но получатель у каждого канала замаскирован (например, t***@example.com, https://example.com/… или последние две цифры chat_id в Telegram), а секрет в его браузер вообще не попадает. К каждой маске добавлен короткий суффикс вида ·a1b2 — необратимый отпечаток полного значения: если у проекта два webhook-канала на одном хосте (Slack/Discord — секрет обычно в пути, а не в хосте), маска хоста у них совпадёт, а суффикс — нет, и их можно отличить друг от друга, не видя самого значения. Лог доставок маскирует получателя для той же аудитории тем же способом.
Каналы доставки
Канал — это конкретный адрес/получатель, куда шлётся уведомление. Один канал переиспользуется во всех правилах проекта (и в правилах по метрикам).
| Тип | Получатель (поле «Получатель») | Секрет (поле «Секрет») |
|---|---|---|
| Email-адрес | Не нужен | |
| Webhook | URL (http:// или https://) | Необязательный — если задан, тело запроса подписывается HMAC-SHA256 в заголовке X-Gotcha-Signature: sha256=<hex> |
| Telegram | chat_id получателя/группы | Обязателен — токен бота (123456789:AA...) |
Как добавить канал
- На странице «Оповещения» нажмите «+» («Добавить канал») — откроется модальное окно.
- Выберите Тип: Email, Webhook или Telegram.
- Email недоступен для выбора (пункт задизаблен, подпись «Email (SMTP не настроен)»), пока оператор инстанса не настроит SMTP — см. Конфигурацию. Это переключатель уровня всего инстанса (переменная окружения процесса), не проектная и не организационная настройка.
- Заполните Получатель:
- Email — просто адрес, например
team@example.com; - Webhook — полный URL эндпойнта, который примет
POSTс JSON-телом, напримерhttps://example.com/hooks/gotcha; - Telegram —
chat_id(число, для групп обычно отрицательное) — узнать его можно, например, у@userinfobot, добавив вашего бота в нужный чат.
- Email — просто адрес, например
- Заполните Секрет, если применимо:
- Webhook — произвольная строка, которой вы будете проверять подпись
X-Gotcha-Signatureна своей стороне; - Telegram — токен бота, выданный
@BotFather(123456789:AA...).
- Webhook — произвольная строка, которой вы будете проверять подпись
- Отметьте «Включён» (по умолчанию включено) и нажмите «Добавить канал».
Проверка на стороне сервера: email должен быть синтаксически валидным адресом, webhook — валидным http/https URL с хостом, Telegram — chat_id целым числом (у групп и супергрупп отрицательным) и непустой секрет. Неверные данные — ответ 422 с сообщением об ошибке, канал не создаётся.
Для вебхука на приватный/локальный адрес (например, http://localhost:...) по умолчанию действует SSRF-защита — такие адреса отклоняются на отправке, если оператор явно не разрешил приватные адреса на уровне инстанса (single-tenant-инсталляции).
Изменение канала — кнопка «Изменить» в строке таблицы. Меняются получатель, секрет и включённость: выключенный канал можно включить обратно, а опечатку в адресе — исправить, не теряя историю доставок. Поле секрета оставьте пустым, чтобы сохранить текущий, — оно вводится вслепую и обратно в форму не возвращается. Тип канала не меняется: у email, webhook и Telegram разный смысл адреса и секрета, поэтому «сменить тип» — это отдельный канал.
Удаление канала — кнопка «Удалить» в строке таблицы каналов; спрашивает подтверждение и после него действует сразу.
Правила по проблемам
Три вида правил, они всегда присутствуют на форме (просто «выключены», если не настраивались):
| Правило | Когда срабатывает | Доп. поля |
|---|---|---|
| Новый issue | Появилась новая проблема (новый фингерпринт) | — |
| Регрессия | Решённая проблема снова открылась (то же самое событие произошло снова) | — |
| Всплеск (spike) | Число событий одной проблемы за окно достигло порога | Порог событий, окно (минут) |
Для каждого правила: чекбокс «Включено», «Не чаще одного раза в (минут)» — минимальный интервал между повторными уведомлениями по одной и той же проблеме и правилу (защита от заваливания дублями; 0 — без троттлинга). У «Всплеска» дополнительно — «Порог событий» (например, 10) и «Окно (минут)» (например, 5): правило срабатывает, если проблема набрала N событий за последние M минут.
Все три правила сохраняются одной формой — кнопка «Сохранить правила» внизу секции «Правила» отправляет состояние всех трёх карточек разом.
Уведомление ставится в очередь на каждый включённый канал проекта при срабатывании правила соответствующего вида; повторные срабатывания по той же проблеме и правилу троттлятся согласно заданному интервалу. Лесенка эскалации к алертам по проблемам не применяется: ступеней и задержек у них нет, уведомление уходит всем каналам сразу.
Как каналы привязываются к правилам
В Gotcha нет отдельного шага «привязать канал к правилу»: включённое правило автоматически уведомляет все включённые каналы проекта. Если нужно, чтобы разные правила уходили в разные каналы, единственный способ на сегодня — включать/выключать нужные каналы. То же самое верно и для алертов по метрикам (Оповещения по метрикам) — они используют тот же список каналов проекта.
Если включённый канал — email, а SMTP на инстансе не настроен, доставка по этому каналу пропускается (с предупреждением в логе сервера), остальные каналы это не блокирует.
Лог доставок
Отдельная страница /projects/{id}/alerts/deliveries (в группе «Доставка» раздела — «Лог доставок») показывает уведомления, которые не удалось доставить: тип канала, получатель, число попыток и текст последней ошибки (например, SMTP-отказ или неуспешный HTTP-статус от вебхука), время. Полезно, когда webhook отвечает не 2xx, у Telegram-бота истёк токен или у почтового сервера временные проблемы — здесь видно причину без похода в серверные логи.
Пока неудачных доставок нет, страница показывает пустое состояние «Неудачных доставок нет».
Telegram: события не доходят до бота
Симптом: доставка в Telegram стабильно падает — в «Логе доставок» таймаут или сетевая ошибка, — а webhook и почта работают. Причина почти всегда лежит на пути к api.telegram.org, а не в боте и не в токене.
Шаг 1 — как инстанс резолвит имя.
docker compose exec gotcha getent hosts api.telegram.org
Если имя резолвится в IPv6-адрес, а глобального IPv6 у сервера нет (частый случай на VPS), соединение будет таймаутиться при полностью доступном IPv4.
Шаг 2 — доходит ли трафик до самого адреса. С сервера:
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://api.telegram.org/
Молчание до истечения таймаута означает, что до Bot API не доходит трафик: фильтрация на стороне оператора связи, закрытый исход из периметра, отсутствующий маршрут. Опознаётся по тому, что одни адреса за этим именем отвечают, а другие нет, причём набор зависит от площадки и направления — то есть Telegram здоров, а недоступен он именно отсюда.
Что с этим делать — три средства, от самого устойчивого к самому временному.
Свой адрес Bot API.
GOTCHA_TELEGRAM_API_BASEнаправляет отправку на собственныйtelegram-bot-apiили на обычный реверс-прокси в сети, откуда Telegram доступен. Единственный вариант, который не зависит от того, какие адреса Telegram проходят сегодня.Исходящий прокси. Стандартные
HTTPS_PROXY/HTTP_PROXY/NO_PROXYв окружении контейнера действуют на доставку в Telegram. На webhook-каналы и проверки аптайма они не распространяются: те намеренно ходят к цели напрямую, иначе SSRF-фильтр перестал бы решать по фактическому адресу соединения.Пиннинг имени на живой IP — быстрая мера на время расследования. В
docker-compose.override.yml:services: gotcha: extra_hosts: - "api.telegram.org:149.154.167.220"После
docker compose up -d gotchaдоставка восстанавливается. Это именно затычка: адрес держится ровно до следующей смены адресов Telegram или настроек фильтрации, и когда он отвалится, симптом вернётся без единого изменения с вашей стороны. Пин стоит снимать, как только заработал вариант 1 или 2.
Таймаут на TLS при живом соединении
Если соединение явно устанавливается, а падает первый крупный обмен — в ошибке почты видно, что приветствие 220 получено, а споткнулось на STARTTLS, — значит мелкие пакеты ходят, а крупные пропадают. Такое даёт фильтрация трафика и MTU сети контейнеров. Отличить просто: проверьте изнутри контейнера, а не с хоста.
docker compose exec gotcha wget -q -O /dev/null https://api.github.com/ && echo ok || echo fail
Если и здесь виснет — берите GOTCHA_COMPOSE_NET_MTU в разделе Конфигурация: там разобрано, почему с хоста при этом всё работает, почему до одних адресатов доходит, а до других нет, и почему поломка может исчезать на десять минут и возвращаться.
Приватность: что видят внешние каналы
Детали события — заголовок проблемы, culprit, уровень, тело уведомления, значения метрики — уходят только доверенным получателям. Остальным отправляется обезличенное уведомление: маршрутные поля (id проекта, проблемы, правила, счётчики, вид алерта) и ссылка на карточку в Gotcha.
Решение принимается по получателю, а не по типу канала:
| Получатель | Когда считается доверенным |
|---|---|
домен адреса — хост вашего инстанса (или его поддомен), либо перечислен в GOTCHA_TRUSTED_RECIPIENTS | |
| Webhook | хост URL — то же самое, а также любой адрес во внутренней сети (localhost, приватные диапазоны, зоны .local, .internal, .lan, .home.arpa) |
| Telegram | по адресу — никогда: получатель задан chat_id, домена у него нет |
| Любой канал | отметка «Получатель внутри моего контура» в форме канала |
Отметка на канале — для случаев, когда адрес ничего не доказывает: чат в Telegram, принадлежащий вам самим, опознать по chat_id невозможно. Она ставится вручную, по одному каналу, снята по умолчанию, и такие каналы помечены в таблице бейджем «С деталями». Подробнее — в разделе Приватность.
Ящик на публичном почтовом сервисе (@gmail.com, @yandex.ru) — такая же чужая инфраструктура, как Telegram: детали туда не уходят. Вебхук на ваш собственный сервер во внутренней сети, наоборот, получает их всегда.
Если почта вашей организации живёт на домене, отличном от хоста инстанса, укажите его:
GOTCHA_TRUSTED_RECIPIENTS=corp.example
GOTCHA_EXTERNAL_CHANNEL_DETAILS_ENABLED=true
снимает ограничение целиком — детали пойдут любому получателю, включая Telegram. Включайте, только если у вас есть законные основания для трансграничной передачи. Обе настройки — на уровне инстанса; подробности и обоснование см. в разделе Приватность и 152-ФЗ.
Формат тела вебхука
Каждое уведомление — POST-запрос с телом JSON (Content-Type: application/json). Если у канала задан секрет, тело подписывается: заголовок X-Gotcha-Signature: sha256=<hex> несёт HMAC-SHA256 тела запроса по секрету канала, в шестнадцатеричной кодировке, с префиксом sha256=. Чтобы проверить подпись на своей стороне: посчитать HMAC-SHA256(секрет, сырое тело запроса) и сравнить с частью после sha256= — побайтовым сравнением с постоянным временем, а не строковым ==. Если секрет не задан, заголовка нет вовсе.
Состав полей зависит от того, доверенный ли получатель канала — см. «Приватность: что видят внешние каналы» выше: при GOTCHA_EXTERNAL_CHANNEL_DETAILS_ENABLED=false и недоверенном получателе часть полей вырезается, а subject/body заменяются обезличенным текстом. Порядок ключей JSON-объекта частью контракта не является.
Ниже — тело алерта по проблеме (issue): kind равен new_issue, regression или spike.
| Поле | Тип | С деталями | Без деталей |
|---|---|---|---|
kind | строка | ✓ | ✓ |
project_id | число | ✓ | ✓ |
project_name | строка | ✓ | ✓ |
url | строка | ✓ | ✓ |
subject | строка | ✓ (тема с деталями) | ✓ (обезличенная тема) |
body | строка | ✓ (тело с деталями) | ✓ (обезличенное тело) |
issue_id | число | ✓ | ✓ |
times_seen | число | ✓ | ✓ |
title | строка | ✓ | — |
culprit | строка | ✓ | — |
level | строка | ✓ | — |
Пример тела с деталями:
{
"body": "Project: Storefront\n\nTypeError: cannot read properties of undefined\n\nCulprit: checkoutHandler\nLevel: error\nSeen: 3 times\n\nhttps://gotcha.example/issues/42",
"culprit": "checkoutHandler",
"issue_id": 42,
"kind": "new_issue",
"level": "error",
"project_id": 7,
"project_name": "Storefront",
"subject": "[Gotcha] New issue: TypeError: cannot read properties of undefined · Storefront",
"times_seen": 3,
"title": "TypeError: cannot read properties of undefined",
"url": "https://gotcha.example/issues/42"
}
Пример тела без деталей (GOTCHA_EXTERNAL_CHANNEL_DETAILS_ENABLED=false, недоверенный получатель):
{
"body": "Project: Storefront\n\nNew issue\n\nhttps://gotcha.example/issues/42",
"issue_id": 42,
"kind": "new_issue",
"project_id": 7,
"project_name": "Storefront",
"subject": "[Gotcha] New issue · Storefront",
"times_seen": 3,
"url": "https://gotcha.example/issues/42"
}
Правило совместимости: добавление нового поля в тело — не ломающее изменение (интеграция обязана игнорировать незнакомые поля); удаление поля, переименование или смена типа — ломающее изменение.
Остальные виды событий шлют тот же маршрутный минимум (kind, project_id, url, subject, body, а при недоверенном получателе — тот же обезличенный путь) со своим kind и собственными дополнительными полями:
- Сводка подавленных уведомлений (
kind=suppressed_digest) —count: сколько уведомлений подавлено с прошлой сводки. - Регрессия производительности (
kind=n_plus_one/slow_db_query/http_flood) —perf_issue_id,title,culprit,count,regression(булево:true— регрессия закрылась,false— новая находка). - Тестовое уведомление (кнопка «Тест» у канала) —
kind=channel_test, дополнительных полей нет.
Смотрите также
- Оповещения по метрикам — пороговые правила по числовым метрикам, тот же набор каналов.
- Проблемы — что такое issue, регрессия, статусы.
- Конфигурация — переменные SMTP и
GOTCHA_EXTERNAL_CHANNEL_DETAILS_ENABLED. - Команды и роли — кто такой оператор проекта и полная таблица того, что доступно оператору, а что — только owner/admin.