Monitoring Rails: metryki, które mają znaczenie
Nie naprawisz tego, czego nie widzisz. Przewodnik po monitorowaniu aplikacji Rails na produkcji — garść metryk, które naprawdę mają znaczenie, śledzenie błędów, ustrukturyzowane logi i alarmowanie na objawy, które czują użytkownicy, a nie szum.
Jest przewidywalny moment w życiu każdej produkcyjnej aplikacji: coś jest wolne albo zepsute, klient zgłasza, a ty uświadamiasz sobie, że nie masz pojęcia, co naprawdę dzieje się w twoim działającym systemie. Monitoring jest tym, co zamienia ten bezradny moment w szybką diagnozę. Ale łatwo zrobić go źle — utonąć w dashboardach pełnych liczb, na które nikt nie patrzy, albo być pagowanym o 3 nad ranem o rzeczy, które nie mają znaczenia. Oto pragmatyczny przewodnik po monitorowaniu aplikacji Rails: kilka metryk, które naprawdę coś mówią, i jak alarmować na nich rozsądnie.
Metryki, które naprawdę mają znaczenie
Możesz mierzyć tysiąc rzeczy; niemal wszystkie to szum. Sygnały, które naprawdę mówią, czy twoja aplikacja jest zdrowa, są nieliczne — użytecznym ujęciem są „cztery złote sygnały” z praktyki SRE Google, dostosowane do aplikacji Rails:
- Opóźnienie — jak długo trwają żądania, mierzone w percentylach, nie średniej. Średnia ukrywa wszystko: p50 na 100ms wygląda świetnie, podczas gdy twoje p95 to 4 sekundy, a jeden użytkownik na dwudziestu cierpi. Obserwuj p95 i p99 — ogon to miejsce, gdzie żyją twoi nieszczęśliwi użytkownicy, i to, czego średnia nigdy nie pokaże.
- Przepustowość — żądania na minutę. Nie sygnał zdrowia sam w sobie, ale niezbędny kontekst: skok opóźnień oznacza coś innego przy 10 req/min niż przy 10 000.
- Wskaźnik błędów — procent żądań zwracających 5xx. Rosnący wskaźnik błędów to najbardziej bezpośredni sygnał „coś jest zepsute”, jaki istnieje.
- Saturacja — jak pełne są twoje zasoby: CPU, pamięć, pula połączeń bazy i — specyficznie dla Rails — głębokość kolejki zadań w tle. Kolejka rosnąca szybciej, niż się drenuje, to wczesne ostrzeżenie kłopotu, którego samo opóźnienie nie pokaże.
Jeśli obserwujesz tylko te, złapiesz dużą większość realnych problemów. Wszystko inne to detal, który konsultujesz po tym, jak jeden z nich powie ci, gdzie patrzeć.
APM: zajrzyj do wnętrza żądania
Liczba opóźnienia mówi, że żądanie jest wolne; narzędzie APM (monitoring wydajności aplikacji) mówi dlaczego. Narzędzia jak New Relic, Skylight i Scout instrumentują twoją aplikację i rozbijają żądanie na to, gdzie faktycznie poszedł czas — kontroler, baza, renderowanie widoku, zewnętrzne wywołania HTTP:
GET /products/42 850 ms
├─ ActiveRecord 620 ms ← problem jest tutaj
├─ Renderowanie widoku 180 ms
└─ Kontroler 50 ms
Ten rozkład jest tym, co zamienia „strona produktu jest wolna” w „strona produktu uruchamia zapytanie 600ms” — a APM zwykle wskaże wprost na N+1 albo brakujący indeks to powodujący. APM to pojedyncza inwestycja monitoringu o najwyższej wartości dla aplikacji Rails, bo łączy objaw, który widzisz (wolna strona), z przyczyną, którą możesz naprawić (konkretne wolne zapytanie). Pokazuje też twoje najwolniejsze endpointy i najbardziej czasochłonne zapytania w całym ruchu, co jest gotową listą zadań wydajnościowych.
Śledzenie błędów, osobno od logów
Drugą niezbędną rzeczą jest śledzenie błędów — dedykowana usługa (Sentry, Honeybadger, Rollbar) przechwytująca każdy wyjątek z jego pełnym kontekstem: backtrace, parametry żądania, użytkownik, release. To odrębne od metryk monitoringu i odrębne od logów, a chcesz wszystkich trzech. Tracker błędów agreguje — grupuje ten sam wyjątek przez tysiące wystąpień, mówi ci, że zaczął się po deployu o 14:00, pokazuje, że dotyka 3% prób checkoutu, i powiadamia cię proaktywnie. Grepowanie logów za wyjątkami, dla kontrastu, jest reaktywne i nie daje agregacji. Dyscyplina, która ma znaczenie: tracker błędów działa tylko, jeśli trzymasz szum nisko — triażuj i rozwiązuj albo wyciszaj problemy, bo feed błędów pełen ignorowanych wyjątków to taki, którego nikt nie czyta, a prawdziwy chowa się w nim.
Ustrukturyzowane logi, które faktycznie możesz odpytać
Logi to twój szczegółowy zapis tego, co się stało, ale domyślne logi Rails są zaprojektowane do czytania przez człowieka, jedno żądanie naraz — bezużyteczne do odpowiedzi „ile porażek checkoutu w ostatniej godzinie?” przez flotę serwerów. Dwa ulepszenia czynią logi użytecznymi:
- Uczyń je ustrukturyzowanymi (klucz-wartość albo JSON), ze spójnym ID żądania
przewleczonym przez każdą linię żądania (middleware
ActionDispatch::RequestIdci to daje), byś mógł zrekonstruować pełną historię pojedynczego żądania, nawet gdy wiele się przeplata. - Wyślij je do centralnego składu, który możesz przeszukiwać (stos ELK albo hostowana usługa logów), by „znajdź każde 500 z tym stack trace przez wszystkie serwery w ostatnim dniu” było zapytaniem, a nie wyprawą ssh-i-grep.
Logi to miejsce, do którego idziesz po detal, gdy metryka albo błąd powiedziały ci gdzie patrzeć.
Alarmuj na objawy, nie przyczyny — i tylko na to, co ma znaczenie
To część, którą zespoły robią źle, a zrobienie jej źle jest gorsze niż brak alarmowania, bo produkuje zmęczenie alarmami — tyle pagów, że ludzie przestają je czytać, a prawdziwy incydent jest przegapiony w szumie. Dwie reguły:
- Alarmuj na objawy, które czują użytkownicy, nie na wewnętrzne przyczyny. Paguj na „wskaźnik błędów powyżej 2%” albo „opóźnienie p95 powyżej 2s” — rzeczy oznaczające, że klienci mają zły czas. Nie paguj na „CPU na 80%”, które może być całkiem w porządku; CPU to metryka diagnostyczna, na którą patrzysz po alarmie objawu, nie alarm sam w sobie.
- Paguj tylko na to, co potrzebuje człowieka teraz. Jeśli alarm nie wymaga, by ktoś się obudził i zadziałał, to nie jest pag — uczyń go dashboardem albo dziennym podsumowaniem. Każdy pag powinien być wykonalny i prawdziwy. Test: jeśli nie wstałbyś z łóżka dla tego, nie powinno cię budzić.
Mały zbiór wysokiej jakości, opartych na objawach alarmów, które odpalają się rzadko i zawsze coś oznaczają, bije setkę szumnych za każdym razem.
Werdykt
Monitoring jest tym, co pozwala uruchamiać aplikację Rails z otwartymi oczami, zamiast czekać, aż klienci będą twoim detektorem błędów. Obserwuj kilka metryk, które mają znaczenie — opóźnienie w percentylach, przepustowość, wskaźnik błędów, saturację (w tym głębokość kolejki zadań) — i ignoruj resztę, dopóki jedna z nich cię gdzieś nie skieruje. Używaj APM, by zamienić „jest wolne” w „to zapytanie jest wolne”, dedykowanego trackera błędów (trzymanego wolnym od szumu), by łapać i agregować wyjątki, i ustrukturyzowanych, scentralizowanych logów po detal. Potem alarmuj oszczędnie, na objawy, które czują użytkownicy, by pag, który odpala, zawsze zasługiwał na twoją uwagę. Miej to na miejscu przed incydentem, bo najgorszym czasem na odkrycie, że nie masz widoczności, jest środek awarii, której nie widzisz.