Alerty telefoniczne Sentry dla błędów krytycznych

Sentry nie ma akcji „zadzwoń”. Przekieruj alerty przez webhook, by telefon dzwonił tylko przy błędach psujących produkcję: konfiguracja, payload i filtry.

Aktualizacja

Spis treści

Sentry nie może do Ciebie zadzwonić. Wyśle maila, napisze na Slacku albo przekaże alert do PagerDuty — ale wbudowanej akcji głosowej nie ma. Sposób, by ją mieć bez kupowania platformy do zarządzania incydentami: wysłać alert Sentry do webhooka, który dzwoni. Tworzysz integrację wewnętrzną, kierujesz ją na kanał telefoniczny Echobell i stawiasz przed nią filtr, żeby przechodziły tylko błędy, które naprawdę psują produkcję.

Ten przewodnik obejmuje całą drogę: integrację, regułę alertu, payload, który Sentry faktycznie wysyła, szablony, które go czytają, i dwie pułapki, przez które ludzie się poddają.

Dlaczego Sentry samo nie zadzwoni

Akcje alertów issue w Sentry to powiadomienia (e-mail, Slack, Discord, Microsoft Teams), tworzenie zgłoszeń (Jira, GitHub, Azure DevOps) i przekazanie do produktu dyżurowego (PagerDuty, Opsgenie). Każda kończy się na ekranie, w który trzeba akurat patrzeć, albo na płatnym miejscu na innej platformie.

O 14:00 to w porządku. O 3:00 wiadomość na Slacku jest nie do odróżnienia od ciszy, a powiadomienie push przegrywa z trybem Nie przeszkadzać. Dla tej niewielkiej grupy błędów, przy których dwie godziny zwłoki kosztują realne pieniądze — checkout zwracający 500, uwierzytelnianie odrzucające wszystkich, worker po cichu gubiący zadania — potrzebujesz urządzenia, które dzwoni.

Webhook jest tym połączeniem. Sentry potrafi wywołać dowolny endpoint HTTPS jako akcję reguły alertu; Echobell zamienia to żądanie HTTP w alert w formie połączenia, który przebija tryb Skupienia w iOS.

Czego potrzebujesz

  • Organizacji w Sentry, w której masz dostęp do Settings → Developer Settings (owner lub manager)
  • Zainstalowanego Echobella (App Store / Google Play)
  • Pięciu minut

Nic po Twojej stronie nie musi być osiągalne z internetu. To Sentry wysyła żądanie wychodzące; Ty je tylko odbierasz.

Krok 1 — Utwórz kanał, który dzwoni

W Echobellu utwórz kanał i ustaw typ powiadomienia na Połączenie. To sedno całej operacji: kanał telefoniczny zachowuje się jak połączenie przychodzące, a nie jak push, więc przechodzi przez tryb Skupienia i Nie przeszkadzać.

Nadaj mu szablony, które będą miały sens o trzeciej w nocy. Payload Sentry jest głęboko zagnieżdżony, więc ścieżki zmiennych są dłuższe niż zwykle:

Tytuł: {{data.event.level}}: {{data.event.metadata.type}}
Treść: {{data.event.title}} — {{data.event.culprit}}

W ustawieniach zaawansowanych ustaw szablon linku, żeby dotknięcie powiadomienia otwierało zgłoszenie:

{{data.event.web_url}}

Skopiuj adres webhooka z widoku szczegółów kanału. Wygląda tak:

https://hook.echobell.one/t/<channel-token>

Krok 2 — Utwórz integrację wewnętrzną w Sentry

Sentry udostępnia webhook jako akcję reguły wyłącznie przez integrację, więc musisz jakąś stworzyć. To formularz, nie usługa — nie piszesz żadnego kodu.

  1. Wejdź w Settings → Developer Settings → Custom Integrations
  2. Create New Integration → Internal Integration
  3. Name: Echobell (tę nazwę wybierzesz potem w regule)
  4. Webhook URL: adres kanału z kroku 1
  5. Włącz przełącznik Alert Rule Action
  6. Permissions: wystarczy Issue & Event → Read
  7. W sekcji Webhooks zostaw wszystkie pola niezaznaczone — patrz pułapka niżej
  8. Zapisz

Integracja wewnętrzna działa tylko w Twojej organizacji i instaluje się sama. Token, który generuje, w tej konfiguracji nie jest potrzebny.

Krok 3 — Dodaj integrację jako akcję reguły

Wejdź w Alerts → Create Alert → Issue Alert albo edytuj istniejącą regułę.

W sekcji Then perform these actions dodaj Send a notification via an integration i wybierz Echobell.

Ustaw Action interval — ogranicznik „jeśli ten alert wyzwolił się więcej niż raz” — na co najmniej 30 minutes. Domyślnie wysyłka następuje przy każdym wyzwoleniu, a błąd lecący 400 razy na minutę będzie wybierał Twój numer, dopóki wszystkiego nie wyłączysz.

Zapisz i uruchom test reguły, żeby zobaczyć prawdziwy payload, zanim na tym polegniesz.

Krok 4 — Poznaj to, co faktycznie przychodzi

Tu psuje się większość konfiguracji, bo payload nie ma kształtu, jakiego się spodziewasz. Sentry wszystko opakowuje:

{
  "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..." }
}

Cztery rzeczy, które warto wiedzieć przed napisaniem choćby jednego szablonu:

  • Wszystko, co przydatne, leży pod data.event. {{title}} nie wyrenderuje nic; {{data.event.title}} wyrenderuje błąd.
  • data.event.project to liczbowe ID, nie slug. Jeśli chcesz czytelnej nazwy projektu w powiadomieniu, wpisz ją jako zwykły tekst w szablonie tytułu i używaj jednego kanału na projekt.
  • Nie ma pola environment. Środowisko przychodzi w data.event.tags jako para ["environment", "production"], a jej pozycja w tablicy nie jest stała — nie odwołuj się po indeksie. Filtruj środowisko w regule Sentry (krok 5).
  • data.triggered_rule to nazwa reguły. Przydaje się w treści, gdy jeden kanał obsługuje kilka reguł.

Nagłówek Sentry-Hook-Resource ma dla alertów issue wartość event_alert. Możesz go wymagać w warunku kanału, żeby nic innego nie mogło go uruchomić:

header["sentry-hook-resource"] == "event_alert"

Krok 5 — Zawęź do tego, co zasługuje na telefon

Kanał telefoniczny dzwoniący przy każdym nowym zgłoszeniu jest gorszy niż brak kanału: w tydzień go wyciszysz, a wtedy nie zadzwoni przy tym jednym, który miał znaczenie. Filtruj w dwóch miejscach.

W Sentry przez conditions i filters reguły:

CelKonfiguracja reguły
Tylko produkcjaUstaw Environment reguły na production
Tylko prawdziwe awarieFiltr: The event's level equals fatal (albo error)
Nie dla jednorazowych skokówWarunek: The issue is seen more than 25 times in 1 hour
Tylko krytyczna ścieżkaFiltr: The event's tags match transaction contains /checkout
Tylko regresjeWarunek: A resolved issue changes state from resolved to unresolved

W Echobellu użyj warunku kanału jako siatki bezpieczeństwa dla tego, czego Sentry nie wyrazi, albo dla zmian, których dziś nie wdrożysz:

data.event.level == "fatal" || data.event.level == "error"

Filtrowanie po poziomie zwykle lepiej wypada w regule Sentry, bo tam mieszka też ograniczanie częstotliwości. W Echobellu lepiej, gdy z jednej reguły Sentry chcesz uzyskać dwa poziomy pilności.

Krok 6 — Daj ostrzeżeniom cichsze drzwi

Sens stopniowania polega na tym, żeby telefon zachował swoje znaczenie. Utwórz drugi kanał Echobell typu Pilne (Time Sensitive), dodaj drugą regułę Sentry z niższym progiem i skieruj ją na drugą integrację wewnętrzną (jedna integracja przechowuje jeden adres webhooka, więc drugi kanał wymaga drugiej integracji).

Konfiguracja, która przetrwa prawdziwy tydzień, wygląda mniej więcej tak:

Reguła SentryPoziom / prógKanał EchobellZachowanie
prod-fatalfatal, produkcjaPołączenieDzwoni przez tryb Skupienia
prod-error-spikeerror, ponad 100 w 1 hPilneLąduje na ekranie blokady, bez dzwonka
new-issue-digestdowolne nowe zgłoszenieNormalneZwykły push, do przeczytania kiedyś

Dzwoń tylko poza godzinami pracy

W ciągu dnia i tak patrzysz w Sentry. Echobell udostępnia warunkom zmienne czasu systemowego w UTC, więc jeden kanał może zachowywać się inaczej zależnie od godziny — bez drugiej reguły w Sentry:

data.event.level == "fatal" && (hour >= 17 || hour < 9)

Dodaj sprawdzenie dnia tygodnia, jeśli weekend naprawdę masz wolny:

data.event.level == "fatal" && (hour >= 17 || hour < 9 || dayOfWeek == 0 || dayOfWeek == 6)

Wszystko jest w UTC, więc przelicz ze swojej strefy, zanim zapiszesz liczby na stałe. Pełną listę zmiennych ma dokumentacja warunków.

Dwie pułapki

Pułapka 1: zaznaczenie pól Webhooks. Integracja wewnętrzna ma dwie niezależne ścieżki webhooków. Przełącznik Alert Rule Action sprawia, że integrację da się wybrać w regułach alertów — o to Ci chodzi. Natomiast pola Webhooks (issue, error, comment) subskrybują każde zdarzenie danego zasobu: każde utworzenie, rozwiązanie, przypisanie, zarchiwizowanie czy zignorowanie zgłoszenia w całej organizacji. Zaznacz issue, a telefon zadzwoni, gdy kolega coś zamknie. Zostaw wszystkie puste, a webhooka odpalą wyłącznie Twoje reguły.

Pułapka 2: użycie starej wtyczki Webhooks. Stara, projektowa wtyczka Legacy Integrations → WebHooks wciąż istnieje i wciąż działa, a wygląda na skrót, bo wklejasz adres bez tworzenia integracji. Jej payload ma inny, bardziej płaski kształt, żądania nie są podpisywane, a samo Sentry kieruje nowe konfiguracje gdzie indziej. Jeśli jej użyjesz, szablony będą potrzebowały innych ścieżek zmiennych niż powyższe. Użyj integracji wewnętrznej.

Rozmiar payloadu, burze błędów i przycinanie

Trzy limity warte poznania, zanim coś pójdzie nie tak przy większej skali:

  • 1 MiB treści. Echobell odrzuca treści wyzwalacza powyżej 1 MiB z kodem HTTP 413. Payload Sentry niesie pełny stack trace i kontekst żądania, co zwykle mieści się w dziesiątkach kilobajtów — ale zdarzenie z dużą treścią żądania może się zbliżyć do granicy. Po stronie Sentry nie ma pokrętła max_alerts, więc rozwiązaniem jest czyszczenie dużych treści żądań w beforeSend Twojego SDK, co i tak warto robić ze względów prywatności.
  • 120 żądań na minutę na token. Powyżej wyzwalacz odpowiada 429 z RATE_LIMIT_EXCEEDED i nagłówkiem Retry-After. To action interval w Sentry trzyma Cię poniżej limitu; 30 minutes z zapasem wystarczy.
  • 1500 bajtów treści powiadomienia. Dłuższy render jest przycinany, zanim dotrze na urządzenie. data.event.title plus culprit mieści się swobodnie; wrzucanie data.event.exception już nie — i tak jest nieczytelne na ekranie blokady. Szczegóły zostaw za szablonem linku.

Dzielenie się z zespołem

Kanał Echobell może subskrybować kilka osób, a każdy subskrybent wybiera własny typ powiadomienia. Ta sama reguła Sentry może więc dzwonić na telefon osoby na dyżurze, a do reszty trafiać jako zwykły push — bez opłat od stanowiska i bez konfigurowania grafiku.

Nie jest to jednak polityka eskalacji. Nie ma czegoś takiego jak „jeśli nikt nie potwierdzi w pięć minut, zadzwoń do następnej osoby”. Jeśli tego potrzebujesz, potrzebujesz prawdziwej platformy dyżurowej; Echobell obsługuje warstwę dostarczania pod nią.

Czego ta konfiguracja nie daje

Lepiej powiedzieć wprost:

  • Brak potwierdzenia. Odebranie połączenia nie mówi Sentry niczego i nie zatrzymuje telefonów pozostałych subskrybentów.
  • Brak grafiku i eskalacji. Albo dostają wszyscy zapisani, albo nikt.
  • Brak deduplikacji poza tą z Sentry. Grupowanie i ograniczanie dzieją się w regule; Echobell dostarcza to, co przyszło.
  • Brak synchronizacji dwukierunkowej. Rozwiązanie zgłoszenia w Sentry niczego nie czyści na telefonie.

Jeśli to dyskwalifikuje, to nie jest właściwe narzędzie. Jeśli naprawdę potrzebujesz „obudź mnie, gdy padnie checkout”, to mniej więcej najtańszy niezawodny sposób.

Rozwiązywanie problemów

Reguła się wyzwala, ale nic nie przychodzi. Sprawdź, czy w integracji włączone jest Alert Rule Action. Jeśli jest wyłączone, integracja w ogóle nie pojawi się na liście akcji — a reguła zapisana przed włączeniem zachowa nieaktualną akcję.

Powiadomienie przychodzi, ale jest puste. Twój szablon czyta klucze najwyższego poziomu. Sentry zagnieżdża wszystko pod data.event.

Dzwoni przy rzeczach, których się nie spodziewasz. Sprawdź pola Webhooks w integracji (pułapka 1), a potem czy środowisko reguły nie zostało na „All Environments”.

Dzwoni wielokrotnie przy jednym błędzie. Podnieś action interval w regule Sentry. Ponawianie w Echobellu to co innego — Ponów nieudane połączenie w ustawieniach aplikacji wybiera ponownie połączenie, które przegapiłeś.

Nigdy nic nie przychodzi, nawet test. Najpierw wyzwól kanał przez curl, żeby wykluczyć stronę Echobella:

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"}}}}'

Jeśli to dzwoni, a Sentry nie, problem leży w integracji, nie w kanale.

Najczęstsze pytania

Czy Sentry potrafi zadzwonić natywnie?

Nie. Akcje alertów Sentry to powiadomienia, tworzenie zgłoszeń i integracje z produktami dyżurowymi. Połączenie głosowe wymaga usługi zewnętrznej — platformy w rodzaju PagerDuty albo odbiornika webhooków, który dzwoni, jak Echobell.

Czy alert Sentry przebije tryb Nie przeszkadzać?

Tylko jeśli dotrze jako alert w formie połączenia. Kanał Echobell typu połączenie zachowuje się jak połączenie przychodzące, a takie iOS przepuszcza przez tryb Skupienia i Nie przeszkadzać. Zwykły push z dowolnej aplikacji — nie.

Czy webhooki wymagają płatnego planu Sentry?

Integracje wewnętrzne i akcje reguł są dostępne od planu Developer wzwyż. Sam webhook nie kosztuje nic dodatkowo.

Dlaczego moja zmienna w szablonie jest pusta?

Prawie zawsze dlatego, że ścieżka jest za krótka. Payload alertu zagnieżdża zdarzenie pod data.event, więc to {{data.event.title}}, a nie {{title}}. Wyzwól kanał raz i sprawdź zapisaną treść żądania w aplikacji, żeby zobaczyć dokładny kształt.

Jak alertować tylko z jednego środowiska?

Ustaw pole Environment w regule alertu Sentry. Nie próbuj czytać go z data.event.tags — to tablica par [klucz, wartość] o niegwarantowanej kolejności.

Czy dwie osoby mogą dostać telefon przy tym samym błędzie?

Tak. Udostępnij kanał i pozwól każdemu zapisać się z wybranym typem powiadomienia. Potwierdzeń nie ma, więc dzwonimy do wszystkich, którzy wybrali „połączenie”.

Filtrować w Sentry czy w Echobellu?

W Sentry, kiedy się da — tam mieszka też ograniczanie częstotliwości i zakres środowiska. W Echobellu, gdy chcesz dwóch poziomów pilności z jednej reguły, gdy potrzebujesz okna czasowego albo gdy reguły nie da się dziś zmienić.

Podsumowanie

Ta konfiguracja to cztery rzeczy: kanał telefoniczny, integracja wewnętrzna z włączonym Alert Rule Action i pustymi polami Webhooks, reguła alertu wystarczająco wąska, by zasłużyć na telefon, oraz szablony czytające data.event. Cała reszta tej strony dotyczy utrzymania jej dostatecznie wąskiej, żeby za miesiąc ten dzwonek wciąż coś znaczył.

Pobierz Echobella na iPhone'a albo weź go z Google Play, a potem wyślij powyższego curla, zanim powierzysz tej ścieżce cokolwiek naprawdę ważnego.

Powiązane artykuły