Содержание
- Почему Sentry сам не может позвонить
- Что понадобится
- Шаг 1 — Создайте канал, который звонит
- Шаг 2 — Создайте внутреннюю интеграцию Sentry
- Шаг 3 — Добавьте интеграцию как действие правила
- Шаг 4 — Разберитесь, что приходит на самом деле
- Шаг 5 — Сузьте до того, что заслуживает звонка
- Шаг 6 — Дайте предупреждениям тихую дверь
- Звонить только вне рабочего времени
- Две ловушки
- Размер payload, шторма и обрезка
- Совместная работа
- Чего эта схема не даёт
- Разбор проблем
- Частые вопросы
- Умеет ли Sentry звонить сам?
- Пробьёт ли алерт Sentry режим «Не беспокоить»?
- Нужен ли платный тариф Sentry для вебхуков?
- Почему переменная шаблона пустая?
- Как алертить только по одному окружению?
- Могут ли позвонить двум людям по одной ошибке?
- Где фильтровать — в Sentry или в Echobell?
- Итог
- Похожие статьи
Sentry не может вам позвонить. Он умеет отправить письмо, написать в Slack или передать алерт в PagerDuty — но встроенного голосового действия у него нет. Способ получить его, не покупая платформу управления инцидентами: отправить алерт Sentry в вебхук, который звонит. Создайте внутреннюю интеграцию, направьте её на звонковый канал Echobell и поставьте перед ним фильтр, чтобы проходили только ошибки, которые действительно ломают продакшен.
В этом руководстве — весь путь: интеграция, правило алерта, реальный payload от Sentry, шаблоны, которые его читают, и две ловушки, из-за которых люди бросают эту затею.
Почему Sentry сам не может позвонить
Действия issue-алертов Sentry — это уведомления (почта, Slack, Discord, Microsoft Teams), создание задач (Jira, GitHub, Azure DevOps) и передача в пейджинговый продукт (PagerDuty, Opsgenie). Каждое заканчивается либо экраном, на который надо смотреть, либо платным местом на чужой платформе.
В 14:00 это нормально. В 03:00 сообщение в Slack неотличимо от тишины, а пуш проигрывает режиму «Не беспокоить». Для того небольшого набора ошибок, где два часа задержки стоят реальных денег — чекаут отдаёт 500, авторизация отклоняет всех, воркер молча теряет задачи — нужно устройство, которое звонит.
Вебхук — это стык. Sentry умеет вызывать произвольный HTTPS-эндпоинт как действие правила алерта; Echobell превращает этот HTTP-запрос в оповещение-звонок, которое пробивает режим фокусирования iOS.
Что понадобится
- Организация в Sentry, где вы можете открыть Settings → Developer Settings (owner или manager)
- Установленный Echobell (App Store / Google Play)
- Пять минут
Ничего с вашей стороны не должно быть доступно из интернета. Исходящий запрос делает Sentry; вы только принимаете.
Шаг 1 — Создайте канал, который звонит
В Echobell создайте канал и выберите тип уведомления Звонок. В этом весь смысл: звонковый канал ведёт себя как входящий вызов, а не как пуш, поэтому проходит через режим фокусирования и «Не беспокоить».
Задайте шаблоны, понятные в три часа ночи. Payload Sentry глубоко вложен, поэтому пути к переменным длиннее обычного:
Заголовок: {{data.event.level}}: {{data.event.metadata.type}}
Текст: {{data.event.title}} — {{data.event.culprit}}
В расширенных настройках задайте шаблон ссылки, чтобы нажатие на уведомление открывало issue:
{{data.event.web_url}}
Скопируйте URL вебхука из карточки канала. Он выглядит так:
https://hook.echobell.one/t/<channel-token>
Шаг 2 — Создайте внутреннюю интеграцию Sentry
Sentry отдаёт вебхук как действие правила алерта только через интеграцию, поэтому её придётся создать. Это форма, а не сервис — писать код не нужно.
- Откройте Settings → Developer Settings → Custom Integrations
- Create New Integration → Internal Integration
- Name:
Echobell(это имя вы потом выберете в правиле) - Webhook URL: URL канала из шага 1
- Включите переключатель Alert Rule Action
- Permissions: достаточно
Issue & Event→ Read - В разделе Webhooks оставьте все галочки снятыми — см. ловушку ниже
- Сохраните
Внутренняя интеграция доступна только вашей организации и устанавливается сама. Токен, который она создаёт, для этой схемы не нужен.
Шаг 3 — Добавьте интеграцию как действие правила
Откройте Alerts → Create Alert → Issue Alert или отредактируйте существующее правило.
В блоке Then perform these actions добавьте Send a notification via an integration и выберите Echobell.
Поставьте Action interval — ограничитель «если этот алерт сработал больше одного раза» — минимум на 30 minutes. По умолчанию отправка идёт при каждом срабатывании, и ошибка, летящая 400 раз в минуту, будет набирать ваш номер, пока вы всё не выключите.
Сохраните и запустите тест правила, чтобы увидеть реальный payload до того, как начнёте на это полагаться.
Шаг 4 — Разберитесь, что приходит на самом деле
Здесь ломается большинство схем, потому что форма payload не такая, как кажется. Sentry всё оборачивает:
{
"action": "triggered",
"actor": { "id": "sentry", "name": "Sentry", "type": "application" },
"data": {
"event": {
"event_id": "e4874d664c3540c1a32eab185f12c5ab",
"level": "error",
"title": "ReferenceError: heck is not defined",
"culprit": "?(<anonymous>)",
"platform": "javascript",
"project": 1,
"release": null,
"metadata": { "type": "ReferenceError", "value": "heck is not defined" },
"tags": [["level", "error"], ["browser", "Chrome 75.0.3770"]],
"issue_id": "1117540176",
"issue_url": "https://sentry.io/api/0/issues/1117540176/",
"web_url": "https://sentry.io/organizations/test-org/issues/1117540176/events/e4874.../"
},
"triggered_rule": "Very Important Alert!"
},
"installation": { "uuid": "a8e5d2..." }
}
Четыре вещи, которые стоит знать до написания первого шаблона:
- Всё полезное лежит под
data.event.{{title}}не выведет ничего;{{data.event.title}}выведет ошибку. data.event.project— это числовой ID, а не slug. Если нужно читаемое имя проекта в уведомлении, впишите его текстом в шаблон заголовка и заведите по каналу на проект.- Поля
environmentнет. Окружение приходит внутриdata.event.tagsпарой["environment", "production"], и её позиция в массиве не фиксирована — не обращайтесь по индексу. Фильтруйте окружение в правиле Sentry (шаг 5). data.triggered_rule— имя правила. Полезно в теле, когда один канал обслуживает несколько правил.
Заголовок Sentry-Hook-Resource для issue-алертов равен event_alert. Его можно потребовать в условии канала, чтобы канал не мог зазвонить ни от чего другого:
header["sentry-hook-resource"] == "event_alert"
Шаг 5 — Сузьте до того, что заслуживает звонка
Звонковый канал, который звонит на каждый новый issue, хуже, чем его отсутствие: за неделю вы его заглушите, и тогда он не позвонит на тот единственный, который был важен. Фильтруйте в двух местах.
В Sentry — через conditions и filters правила:
| Цель | Настройка правила |
|---|---|
| Только продакшен | Задайте правилу Environment = production |
| Только настоящие поломки | Фильтр: The event's level equals fatal (или error) |
| Не на разовые всплески | Условие: The issue is seen more than 25 times in 1 hour |
| Только критичный путь | Фильтр: The event's tags match transaction contains /checkout |
| Только регрессии | Условие: A resolved issue changes state from resolved to unresolved |
В Echobell условие канала работает как подстраховка для того, что Sentry выразить не умеет, или для правок, которые сегодня не выкатить:
data.event.level == "fatal" || data.event.level == "error"
Фильтровать по уровню обычно лучше в правиле Sentry — там же живёт троттлинг. В Echobell лучше, когда из одного правила Sentry нужно получить две степени срочности.
Шаг 6 — Дайте предупреждениям тихую дверь
Смысл уровней в том, чтобы звонок сохранял значение. Создайте второй канал Echobell с типом Срочное (Time Sensitive), добавьте второе правило Sentry с более низким порогом и направьте его на вторую внутреннюю интеграцию (в одной интеграции один URL вебхука, поэтому второму каналу нужна вторая интеграция).
Схема, которая переживает настоящую рабочую неделю, выглядит примерно так:
| Правило Sentry | Уровень / порог | Канал Echobell | Поведение |
|---|---|---|---|
prod-fatal | fatal, продакшен | Звонок | Звонит сквозь режим фокусирования |
prod-error-spike | error, более 100 за час | Срочное | Попадает на экран блокировки, без звонка |
new-issue-digest | любой новый issue | Обычное | Обычный пуш, прочитать когда удобно |
Звонить только вне рабочего времени
Днём вы и так смотрите в Sentry. Echobell даёт условиям системные переменные времени в UTC, поэтому один канал может вести себя по-разному в зависимости от часа — без второго правила Sentry:
data.event.level == "fatal" && (hour >= 17 || hour < 9)
Добавьте проверку дня недели, если выходные у вас действительно выходные:
data.event.level == "fatal" && (hour >= 17 || hour < 9 || dayOfWeek == 0 || dayOfWeek == 6)
Всё это UTC, так что пересчитайте из своего часового пояса, прежде чем фиксировать цифры. Полный список переменных — в справочнике по условиям.
Две ловушки
Ловушка 1: отметить галочки Webhooks. У внутренней интеграции два независимых пути вебхука. Переключатель Alert Rule Action делает интеграцию доступной для выбора в правилах алертов — он вам и нужен. А галочки Webhooks (issue, error, comment) подписывают вас на каждое событие этого ресурса: любое создание, решение, назначение, архивирование или игнорирование issue по всей организации. Отметьте issue — и телефон будет звонить, когда коллега что-то закроет. Оставьте все снятыми — и вебхук будут запускать только ваши правила.
Ловушка 2: использовать старый плагин Webhooks. Старый плагин уровня проекта Legacy Integrations → WebHooks всё ещё есть и работает, и выглядит короткой дорогой: URL можно вставить без создания интеграции. Но его payload другой формы, более плоский, запросы не подписываются, и сам Sentry уводит новые настройки в сторону. Если вы его возьмёте, вашим шаблонам понадобятся другие пути к переменным. Используйте внутреннюю интеграцию.
Размер payload, шторма и обрезка
Три ограничения, о которых стоит знать заранее:
- Тело 1 MiB. Echobell отклоняет тела триггера больше 1 MiB с HTTP 413. Payload Sentry несёт полный стектрейс и контекст запроса, обычно это десятки килобайт — но событие с большим телом запроса может подойти к границе. На стороне Sentry нет ручки вроде
max_alerts, поэтому средство защиты — вычищать большие тела запросов вbeforeSendвашего SDK, что и так стоит делать из соображений приватности. - 120 запросов в минуту на токен. Дальше триггер отвечает
429сRATE_LIMIT_EXCEEDEDиRetry-After. Под лимитом вас держит именно action interval в Sentry;30 minutesболее чем достаточно. - 1500 байт тела уведомления. Более длинный результат обрезается до попадания на устройство.
data.event.titleплюсculpritумещаются свободно; вываливатьdata.event.exception— нет, да и на экране блокировки это нечитаемо. Детали оставьте за шаблоном ссылки.
Совместная работа
На канал Echobell могут подписаться несколько человек, и каждый выбирает свой тип уведомления. Одно и то же правило Sentry может звонить дежурному инженеру и приходить обычным пушем всем остальным — без оплаты за место и без настройки ротации.
Но это не политика эскалации. Здесь нет «если за пять минут никто не подтвердил, звони следующему». Если нужно это, нужна настоящая платформа дежурств; Echobell закрывает слой доставки под ней.
Чего эта схема не даёт
Скажем прямо:
- Нет подтверждения. Ответ на звонок ничего не сообщает Sentry и не останавливает телефоны других подписчиков.
- Нет ротации и эскалации. Получают все подписчики либо никто.
- Нет дедупликации сверх той, что делает Sentry. Группировка и троттлинг живут в правиле; Echobell доставляет то, что пришло.
- Нет двусторонней синхронизации. Закрытие issue в Sentry ничего не убирает с вашего телефона.
Если это неприемлемо — инструмент не тот. Если же вам нужно «разбуди меня, когда сломается чекаут», это, пожалуй, самый дешёвый надёжный способ.
Разбор проблем
Правило срабатывает, но ничего не приходит. Проверьте, что в интеграции включён Alert Rule Action. Если он выключен, интеграции вообще не будет в списке действий — а правило, сохранённое до включения, сохранит устаревшее действие.
Уведомление приходит пустым. Ваш шаблон читает ключи верхнего уровня. Sentry вкладывает всё под data.event.
Звонит на то, чего вы не ждали. Проверьте галочки Webhooks в интеграции (ловушка 1), а затем — не осталось ли у правила окружение «All Environments».
Звонит снова и снова по одной ошибке. Поднимите action interval в правиле Sentry. Повтор в Echobell — это другое: Повторять неудавшийся звонок в настройках приложения перезванивает, если вы пропустили вызов.
Не приходит вообще ничего, даже тест. Сначала дёрните канал через curl, чтобы исключить сторону Echobell:
curl -X POST https://hook.echobell.one/t/<channel-token> \
-H 'Content-Type: application/json' \
-d '{"data":{"event":{"level":"fatal","title":"Test error","culprit":"manual test","metadata":{"type":"TestError"}}}}'
Если это звонит, а Sentry нет — проблема в интеграции, а не в канале.
Частые вопросы
Умеет ли Sentry звонить сам?
Нет. Действия issue-алертов Sentry — это уведомления, создание задач и интеграции с пейджинговыми продуктами. Голосовой звонок требует внешнего сервиса: либо платформы вроде PagerDuty, либо приёмника вебхуков, который звонит, — например Echobell.
Пробьёт ли алерт Sentry режим «Не беспокоить»?
Только если придёт как оповещение-звонок. Канал Echobell типа «звонок» ведёт себя как входящий вызов, а такие iOS пропускает через режим фокусирования и «Не беспокоить». Обычный пуш любого приложения — нет.
Нужен ли платный тариф Sentry для вебхуков?
Внутренние интеграции и действия правил доступны начиная с тарифа Developer. Сам вебхук ничего дополнительно не стоит.
Почему переменная шаблона пустая?
Почти всегда потому, что путь слишком короткий. Payload алерта вкладывает событие под data.event, поэтому нужно {{data.event.title}}, а не {{title}}. Дёрните канал один раз и посмотрите записанное тело запроса в приложении — увидите точную форму.
Как алертить только по одному окружению?
Заполните поле Environment в правиле алерта Sentry. Не пытайтесь прочитать его из data.event.tags — это массив пар [ключ, значение] без гарантированного порядка.
Могут ли позвонить двум людям по одной ошибке?
Да. Поделитесь каналом, и пусть каждый подпишется с нужным ему типом уведомления. Подтверждения нет, поэтому звонок получат все, кто выбрал «звонок».
Где фильтровать — в Sentry или в Echobell?
В Sentry, когда можно: там же живут троттлинг и привязка к окружению. В Echobell — когда из одного правила нужны две степени срочности, когда нужно окно по времени или когда правило сегодня не изменить.
Итог
Схема состоит из четырёх вещей: звонковый канал, внутренняя интеграция с включённым Alert Rule Action и снятыми галочками Webhooks, правило алерта, достаточно узкое, чтобы заслужить звонок, и шаблоны, читающие data.event. Всё остальное на этой странице — о том, как удержать её достаточно узкой, чтобы через месяц звонок всё ещё что-то значил.
Скачайте Echobell для iPhone или возьмите в Google Play, а затем отправьте curl выше — до того, как доверите этому пути что-то по-настоящему важное.