Jak monitorować działanie aplikacji IT?


pexels.com

Ten wpis jest kolekcją doświadczeń jakie nabyłem podczas wieloletniej pracy przy projektach IT. Jedno jest pewne, nie ważne jak dobrze zaprojektujesz architekturę systemu, jak dobre testy napiszesz i jak wydajną maszynę wykupisz - awarie będą się zdarzały. Najważniejsze jest to aby przygotować się na takie sytuacje, mieć plan działania i móc możliwie jak najszybciej je wykryć i zareagować.

Myśląc o monitoringu aplikacji, należy rozdzielić go na trzy główne dziedziny:

  1. 1. Infrastruktura
  2. 2. Stan aplikacji
  3. 3. Metryki biznesowe

Infrastruktura

IT ma to do siebie, że projekty które tworzymy są zawsze oparte o wykorzystanie tych samych zasobów, są to: procesor (CPU), pamięć (RAM), urządzenia wejścia/wyjścia (I/O) np. dysk HDD, sieć internetowa. Dlatego pierwszym punktem który należy zawsze monitorować bez względu na tematykę projektu są właśnie zasoby. W systemach rozproszonych, takich które działają na wielu fizycznych czy wirtualnych maszynach, jest to jeszcze bardziej istotne gdyż wcześnie wykryta awaria małej części infrastruktury może zapobiec większej awarii całego systemu, co w przypadku poprawnie opracowanej strategii utrzymania jest jak najbardziej w porządku. Dopóki inne metryki nie spadły poniżej założonego poziomu dostępności, awarie mogą się zdarzać w sposób kontrolowany.

Co warto monitorować w przypadku infrastruktury:

  1. - użycie procesora
  2. - użycie pamięci RAM, zarówno zajętość jak i % saturacji pojemności transferowej
  3. - ilość wolnego miejsca dysku HDD, należy pamiętać także o IOPS
  4. - przepustowość kart sieciowych
  5. - ilość działających procesów walczących o dostęp do CPU

Stan aplikacji

Każda budowana aplikacja spełnia inne funkcjonalności i zawiera inną logikę biznesową. Jednak to co mają wspólne to mechanizmy i biblioteki. Na przykład prosty CRM będzie się składał z serwera HTTP, bazy danych, szybkiego cache storage, integracji z kilkoma zewnętrznymi API. Są to elementy praktycznie stałe i to od zespołu deweloperskiego zależy programowanie tych elementów aby razem utworzyły całość wymogów klienta. Podstawowe pytanie to "czy nasza usługa backendowa jest dostępna?". Obserwowanie ilości zapytań do serwera HTTP, stosunek poprawnych/błędnych odpowiedzi, kody odpowiedzi, to wszystko powinniśmy monitorować w naszej aplikacji, oczywiście metryki powinny być zbierane per endpoint. Monitorowanie tych informacji może powiedzieć wiele o stanie systemu operatorowi który nie zna szczegółów działania systemu, może on wyciągnać z nich podstawowe wnioski o stanie aplikacji.

Monitorowanie opóźnień zasługuje na oddzielny akapit. Dla produkcyjnych systemów celem jest utrzymywanie opóźnienia (latency) na odpowiednim poziomie, tak aby końcowi użytkownicy systemu nie odczuwali dyskomfortu spowodowanego zbyt długim oczekiwaniem na zdarzenia w aplikacji. Mierzenie samych średnich nie jest dobrym pomysłem, miara średniej potrafi ukryć wiele istotnych szczegółów i sam osobiście uważam że nie powinno się jej nigdy używać. Dobrym rozwiązaniem jest monitorowanie percentyli, np. p95, p98, p99, p999 - czyli poziomu opóźnienia jakiego doświadcza kolejno 95%, 98%, 99% i 99,9% użytkowników. Dla przykładu miara opóźnienia p95 na poziomie 100ms (0.1 sekundy) i p99 na poziomie 900ms mówi o tym, że 95% użytkowników oczekuje zaledwie 100 ms na odpowiedź aplikacji, podczas gdy 99% oczekuje już 900ms. Oznacza to, że przynajmniej 4% użytkowników doświadcza dużego wzrostu opóźnienia i może to świadczyć o wąskich gardłach w aplikacji które należy zbadać i ewentualnie zoptymalizować (np. zapytanie do bazy danych). Monitorowanie opóźnień zasługuje na osobny artykuł, ciekawych odsyłam do rzetelnego artykułu: https://igor.io/latency/.

Metryki biznesowe

Ostatni aspekt systemu który należy monitorować to swoisty rzut topograficzny aplikacji. Metryki biznesowe powinny odpowiadać na pytania działania biznesu a ich zbieranie powinno być za każdym razem indywidualnie implementowane w kodzie. Miary te powinny rejestrować standardowe zdarzenia systemowe który odbywają się w ramach tzw. "business as usual" - czyli codziennej pracy systemu. Potrzeba na monitorowanie takich cech systemu wyszła z naszego doświadczenia, wielokrotnie zderzaliśmy się z sytuacją gdy miary infrastruktury i aplikacji pokazywały normalne wartości z których nie można było w żaden sposób wnioskować awarii, a po kilku godzinach okazywało się że gdzieś jest problem. Dla przykładu, w działaniu sklepu internetowego przyjmującego płatności online należy rejestrować zdarzenia związane z wykonywaniem płatności przez użytkowników. Do takich miar należą liczba udanych prób płatności, liczba nieudanych prób płatności, suma płatności, statusy providera płatności. Monitorowanie takich zdarzeń pozwoli bardzo szybko wykryć ewentualne problemy z partnerem płatności lub trwającymi próbami tzw. fraudów (czyli oszustw). Zawsze w poszukiwaniu nowych rozwiązań wzorujemy się na dużych firmach które chętnie dzielą się swoją wiedzą, polecam świetny artykuł (jak i cały blog) Ubera na temat "obserwowalności" biznesu.

Powiadomienia

Kiedy już monitorujemy naszą aplikację, należy zastanowić się nad wprowadzeniem protokołów powiadamiania o zdarzeniach i awariach. Nie ma sensu (jeżeli nie obsługujemy setek użytkowników na sekundę) tworzyć własnego centrum monitorowania, gdzie operatorzy 24/7 wpatrują się w monitory. Na początek wystarczy nam ustalenie progów normalnych wartości dla zbieranych przez nas metryk i automatyczne alarmowanie (email, sms) w przypadku przekroczenia tych wartości przez zautomwatyzowane systemy, tzw. czujki. Ustalanie limitów powinno być wyważone, nie chcemy otrzymać powiadomienia zbyt późno, nie chcemy także otrzymywać powiadomień zbyt wcześnie ani często (false positive). Jest to moim zdaniem stały proces (ustawianie progów alarmowania) w którym kalibrujemy i reagujemy. Dla przykładu, ustawienie progu użycia CPU, pamięci, powierzchni dysku na 80% zapewni nam alarmowanie tylko w sytuacjach faktycznie poważnych, lecz na tyle wcześnie że mamy jeszcze sporo czasu na reakcję.

Czego używać do monitorowania?

Monitorowanie to rozległy temat i wielu inżynierów do tej pory zderzyło się z nim w przeszłości, koło zostało już dawno wynalezione i jedyna kwestia to decyzja o dobraniu odpowiednich narzędzi. Nasz stack, sprawdzony przez kilka lat używania zawiera:

  1. 1. Telegraf - napisany w Golangu program uruchamiany jako proces tła na maszynie. Posiada dziesiątki pluginów wejścia oraz wyjścia. Jego zadaniem jest zbieranie metryk, agregacja i interwałowe wysyłanie do zewnętrznej bazy danych. Telegraf potrafi zbierać samodzielnie dane z systemu operacyjnego, zasobów, baz danych, serwerów http. Posiada także plugin przyjmujący dane w formacie StatsD. Dzięki Golangowi, aplikacja kompilowana jest do pojedyńczej binarki i może zostać zainstalowana na serwerze przy pomocy SystemD.
  2. 2. InfluxDB - time series database - pozwala na składowanie milionów metryk, skalowalna baza, świetnie nadająca się do ww. zastosowań. Projekt również napisany w naszym ulubionym języku - Golang.
  3. 3. Kapacitor (ze stajni InfluxData) - framework z własnym językiem (DSL) do programowania powiadomień i wykrywania anomalii w metrykach. Kapacitor stale monitoruje metryki, jeżeli któraś wejdzie w stan alarmowy, wysyła wcześniej zaprogramowane powiadomienia. Potrafi także wykrywać anomalie dzięki zaimplementowanym rozwiązaniom machine learning.
  4. 4. Grafana - narzędzie które potrafi podłączyć się pod InfluxDB i pobrać wszystkie interesujące nas metryki, wyświetlając dane na czytelnych i nowoczesnych dashboardach.

Połączenie tych elementów zapewni nam stały dostęp do informacji o metrykach i pozwoli na ustawienie powiadomień. Elastyczna architektura pozwala dodawać nowe zasoby do monitorowania w kilku komendach, a performatywna baza danych umożliwi skalowanie w przypadku gdy zaczniemy zbierać duże ilości metryk.

Podsumowując, powyższy tekst stanowi jedynie pobieżne zarysowanie tematu, monitorowanie aplikacji systemów IT jest bardzo szerokim pojęciem i wymaga dużej wiedzy i doświadczenia. Jeżeli masz jakieś pytania, napisz do nas.

Piotr Osiński