Utrzymuję kilkanaście stron klientów. Kilka Drupali, sporo WordPressów i parę rzeczy pisanych od zera, które trudno zaszufladkować. Do tego dochodzą stagingi, serwery, poczta i te wszystkie elementy, które nie są stroną, ale bez nich strona nie działa.

Praca w supporcie ma jedną nieprzyjemną właściwość: o problemach dowiadujesz się najpóźniej, jak się da. Klient pisze wtedy, kiedy sam zauważy, a zauważa zwykle po kilku dniach i zwykle najgorszą możliwą wersję sytuacji - „strona nie działa od rana", chociaż leżała od czwartku.

Druga nieprzyjemna właściwość: obwiniany jest zawsze ostatni deploy. Nawet jeśli był dwa tygodnie temu, a w międzyczasie hosting przestawił wersję PHP, autoupdate podmienił wtyczkę, a certyfikat się nie odnowił.

Monitoring rozwiązuje obie te rzeczy. Nie dlatego, że wysyła alerty - to potrafi każdy pinger. Dlatego, że daje oś czasu, na której widać, co się zmieniło i kiedy. Poniżej opisuję, jak to mam ustawione przy pracy z Drupalem, WordPressem i customowymi projektami.

Jak układam monitory na projekt

Każdy klient to osobny projekt, a w projekcie siedzi zwykle taki zestaw:

  • strona główna i dwa-trzy szablony stron, które mają inną ścieżkę renderowania (u WooCommerce: kategoria i karta produktu; w Drupalu: widok z listingiem i node),
  • jedna strona, która zawsze uderza do bazy i nie da się jej scache'ować - koszyk, wyszukiwarka, formularz. To ona pierwsza pokazuje, że coś się dzieje z bazą albo z PHP-FPM,
  • endpoint API, jeśli front cokolwiek z niego bierze,
  • rekordy DNS domeny i poczty,
  • usługi poza HTTP - serwer pocztowy, baza na osobnym hoście, NAS z backupami.

Przy onboardingu nowego klienta dodaję kilkanaście adresów naraz zamiast klikać każdy z osobna. Interwały ustawiam per monitor: rzeczy krytyczne co minutę, mniej istotne co pięć albo piętnaście minut. Zakres jest od jednej minuty do dwunastu godzin, więc dla strony, która i tak stoi na cache'u CDN i zmienia się raz na kwartał, nie ma sensu palić limitu.

Praktyczny drobiazg, który oszczędza jedno nieporozumienie na starcie: adresy IP, z których monitoring odpytuje strony, są wypisane w aplikacji. Wrzucam je na białą listę w firewallu albo w regułach WAF-u, zanim ktoś zdąży zbanować monitoring za „podejrzany ruch co minutę".

Wdrożenie: przed, w trakcie i po

To jest moment, w którym narzędzie zarabia na siebie najbardziej.

Przed. Zerkam na wynik audytu kondycji i na wykres czasu odpowiedzi, żeby wiedzieć, jak wygląda stan sprzed zmiany. Bez tego po wdrożeniu nie mam z czym porównywać i zostaje mi „chyba było szybciej".

W trakcie. Wstrzymuję monitory na czas prac. Okno przerwy zapisuje się w historii i nie jest wliczane do uptime, więc w raporcie dla klienta nie muszę tłumaczyć, skąd 99,1% w miesiącu, w którym robiliśmy migrację.

Po. Tu jest najciekawsza część. Audyt kondycji porównuje każdy przebieg z poprzednim i pokazuje różnicę, a nie kolejny raport od zera. Po wdrożeniu widzę wprost:

  • które sprawdzenia zmieniły status i w którą stronę,
  • czy zmieniła się treść strony i czy zmieniła się struktura HTML,
  • które nagłówki zniknęły, a które doszły oraz jak zmieniły się ich wartości,
  • czy zmienił się serwer (Server: nginx na coś innego to zwykle sygnał, że hosting coś przestawił),
  • o ile procent urósł albo skurczył się HTML,
  • czy zmieniła się liczba przekierowań i czy nie zmienił się docelowy adres po przekierowaniach,
  • czy odnowiono certyfikat TLS.

To jest dokładnie ta lista, którą przy debugowaniu regresji odtwarza się ręcznie przez pół godziny: curl -I na starą wersję, na nową, porównanie nagłówków, sprawdzenie czy cache nadal działa. Tutaj dostaję to gotowe, z datą.

Rzeczy, które łapię tak najczęściej:

  • noindex na produkcji. W WordPressie to jest ptaszek „Proś wyszukiwarki o nieindeksowanie tej witryny" przeniesiony ze stagingu razem z bazą. W Drupalu konfiguracja metatagów albo X-Robots-Tag z konfiguracji serwera. Ten jeden błąd potrafi kosztować klienta kwartał ruchu, a nie widać go absolutnie niczym.
  • Zniknięty Cache-Control. Po zmianie konfiguracji nginxa albo po wyłączeniu page cache w Drupalu „na chwilę, do testów". Audyt sprawdza ten nagłówek osobno, więc wychodzi to następnego dnia, a nie po miesiącu przy rachunku za transfer.
  • Mixed content. Klasyk po migracji, kiedy część zasobów została ze starym http:// w bazie.
  • Zniknięte nagłówki bezpieczeństwa - HSTS, CSP, X-Frame-Options, flagi cookies. Nie znikają same, ale znikają przy każdym większym ruchu w konfiguracji serwera.
  • Wyciek wersji oprogramowania w Server i X-Powered-By. Wraca po każdej przebudowie środowiska, jeśli nikt tego nie zapisał w konfiguracji na stałe.
  • Wydłużony łańcuch przekierowań. Dwa skoki zamiast jednego, bo doszła reguła i nikt nie usunął starej.

Historia audytów jest prowadzona jako dziennik zmian, a nie lista uruchomień: wpis powstaje wtedy, kiedy coś się zepsuło, naprawiło albo zmieniło, plus wpis kontrolny raz na tydzień. Dzięki temu przy pytaniu „kiedy to się zaczęło" nie przeglądam trzydziestu identycznych raportów, tylko widzę pięć dat, w których cokolwiek się ruszyło.

Problemy między wdrożeniami, czyli te najbardziej wkurzające

Support to w dużej mierze awarie, których nikt nie wywołał. Nikt nic nie robił, a przestało działać. Kilka typów, które mam pod kontrolą właśnie dzięki monitoringowi:

Autoupdate. WordPress aktualizuje wtyczki sam, jeśli ktoś kiedyś to włączył. Drupal aktualizuje się rzadziej, ale hosting potrafi podbić wersję PHP bez uprzedzenia. Efekt jest zawsze podobny: coś przestaje się renderować albo strona zaczyna sypać ostrzeżeniami.

Na to mam monitoring treści. Przy każdym monitorze można podać do pięciu fraz w jednym z dwóch trybów:

  • musi zawierać - fragment tekstu z sekcji, która renderuje się dynamicznie. Znika, kiedy szablon się wysypie albo widok przestanie zwracać wyniki.
  • nie może zawierać - i tu wpisuję to, co pojawia się na białym ekranie: Fatal error, Warning:, Deprecated:, „There has been a critical error on this website", „The website encountered an unexpected error".

To jest wykrywanie WSOD-a i cichych błędów PHP, których żaden monitoring dostępności nie zobaczy, bo serwer grzecznie odpowiada kodem 200.

Cron i kolejki. Jeśli w projekcie jest endpoint statusowy albo cokolwiek, co zwraca JSON, wpinam monitor API. Porównuje on kształt odpowiedzi z tym, jaki był w momencie konfiguracji: sprawdza, czy pola nadal istnieją i czy mają ten sam typ, a nie czy zmieniła się ich zawartość. Zmieniony tytuł artykułu nie jest incydentem, zniknięte pole jak najbardziej.

To łapie awarię, której nie widać z zewnątrz: API odpowiada 200, a front, który się nim żywi, przestaje działać. Przy headless Drupalu z jsonapi albo przy WP REST API to jest najczęstszy skutek uboczny aktualizacji modułu czy wtyczki. Dla GraphQL-a można dodatkowo ustawić warunek, że ścieżka errors nie może istnieć - bo GraphQL uprzejmie odpowiada dwusetką również wtedy, kiedy backend leży.

Powolne narastanie. Najbardziej podstępny przypadek: nic nie pada, tylko wszystko robi się wolniejsze. Czas odpowiedzi serwera (TTFB) mierzony jest co minutę i pokazywany jako mediana oraz P95 dzień po dniu. To daje baseline, do którego porównywane są ostatnie dni.

Kiedy mediana skacze z 250 ms na 900 ms i tak zostaje, mam datę. A mając datę, mam też odpowiedź na pytanie, czy to była nasza zmiana, czy coś po stronie hostingu. Zwykle to drugie, i wtedy mam czym argumentować w zgłoszeniu.

Certyfikaty. Automatyczne odnawianie działa do momentu, w którym przestaje. Monitoring certyfikatu ostrzega na 30, 14 i 7 dni przed wygaśnięciem, a błąd certyfikatu oznacza stronę jako niedostępną. Trzydzieści dni to jest realnie tyle, ile potrzeba, żeby dogadać się z hostingiem klienta.

DNS. Rekordy zmienia zwykle ktoś, kto nie jest mną: klient, rejestrator, poprzednia agencja, która „jeszcze coś tam miała". Trzymam monitory na rekord A domeny, MX poczty i TXT ze SPF-em. Tryb dopasowania wybiera się osobno: „zawiera" wymaga obecności zadeklarowanych wartości i toleruje dodatkowe rekordy, „dokładnie" wymaga zgodności co do jednego rekordu - i tylko ten drugi wykryje rekord dodany, czyli to, jak wygląda cudza ingerencja w strefę. Dla MX i SPF trzymam tryb dokładny.

Zniknięty rekord MX to moja ulubiona awaria z gatunku „wszystko działa": strona stoi, panel stoi, tylko formularze kontaktowe od tygodnia wpadają w próżnię.

Rzeczy, które nie są stroną WWW

Do wszystkiego, co nie mówi po HTTP, jest monitor portu TCP: aplikacja otwiera połączenie na wskazany port i mierzy czas nawiązania. Używam tego do serwerów pocztowych, baz stojących na osobnym hoście i NAS-ów z backupami u klientów.

Ma to praktyczną przewagę nad odpytywaniem panelu przez HTTP: interfejsy webowe takich urządzeń potrafią budzić się wolno i generują fałszywe alarmy, mimo że urządzenie cały czas jest dostępne. Port odpowiada natychmiast. A jeśli coś siedzi na wolnym łączu i nadal zdarzają się przekłamania, jest opcja obniżonej czułości - monitor daje wtedy hostowi więcej czasu, zanim uzna go za niedostępny.

Jest też tryb odwrotny: monitor, który pilnuje, żeby adres nie odpowiadał. Trzymam tak stagingi zamknięte na IP oraz panele administracyjne za blokadą. Jeśli staging zacznie odpowiadać publicznie, dostaję alert, zanim zaindeksuje go Google i zanim ktoś znajdzie tam kopię produkcyjnej bazy.

Alerty ustawione tak, żeby nie zaczęły być tłem

Monitoring, który krzyczy o wszystkim, przestaje być czytany po tygodniu. Dlatego alerty ustawiam osobno dla każdego monitora i osobno dla każdego typu zdarzenia: dostępność, wygasający certyfikat, pogorszenie kondycji.

Kanały są trzy: e-mail, powiadomienia push w przeglądarce i powiadomienia na telefon przez ntfy. U mnie push leci na desktop w godzinach pracy, ntfy na telefon przez całą dobę dla monitorów produkcyjnych, a stagingi i rzeczy drugorzędne idą wyłącznie mailem. Godziny w mailach są w mojej strefie czasowej, co przy diagnozie o trzeciej w nocy oszczędza jedną pomyłkę.

Osobno warto wiedzieć, że alert o pogorszeniu kondycji wyzwala tylko ta część wyniku, na którą realnie mam wpływ - wynik samej strony, liczony bez danych Core Web Vitals z CrUX. To sensowna decyzja: CWV potrafią się ruszyć bez żadnej zmiany po naszej stronie i alerty z tego tytułu byłyby zwykłym szumem.

Rano zaglądam na ekran „Wymaga uwagi": co leży, co wróciło, komu wygasa certyfikat. Jeśli jest pusty, mam spokojny dzień.

Klient też może to widzieć, i to jest dobre dla obu stron

Dwie rzeczy, które ustawiam przy każdym większym kliencie.

Konto w zespole. Osoba techniczna po stronie klienta (albo mój współpracownik) dostaje własne konto i jest dodana do zespołu. Udostępniam jej wybrane monitory - widzi statusy i statystyki, ustawia sobie własne alerty i własne kanały, ale domyślnie niczego nie zmienia ani nie kasuje. Jeśli komuś potrzebna jest większa swoboda, jest osobne uprawnienie edytora: może zmieniać ustawienia udostępnionych monitorów, ale nadal nie dodaje nowych i nie usuwa istniejących.

Efekt jest taki, że przestaję być jedynym wąskim gardłem. Alert idzie do dwóch osób, reaguje ta, która akurat może.

Publiczna strona statusów. Zbieram wybrane serwisy klienta na jednej stronie i wysyłam mu link, opcjonalnie zabezpieczony hasłem. Klient sam sprawdza, czy jego strona działa, zamiast pisać do mnie „czy u was też nie działa?". Przy umowach supportowych to też najprostszy dowód, że ktoś tego pilnuje - a przy corocznej rozmowie o stawce jest to argument, który sam się broni.

Do tego dochodzi historia dostępności z ostatnich 90 dni i procent uptime za okres. Przy rozliczaniu supportu albo przy rozmowie „czy zmieniamy hosting" to jedyna waluta, która działa: konkretne daty, czas trwania przerw i powód każdej z nich.

Sensowne minimum na projekt

Jeśli miałbym to sprowadzić do listy, którą odklikuję przy nowym kliencie:

  1. Monitory HTTP na stronę główną i dwa-trzy istotne szablony, co 1-5 minut.
  2. Jeden monitor na stronę, której nie da się scache'ować, bo to on pokaże problem z bazą albo z PHP.
  3. Monitoring treści z frazą, która musi być, i z komunikatem błędu, którego być nie może.
  4. Monitoring certyfikatu SSL z alertem 30/14/7 dni.
  5. Audyt kondycji z alertem o regresji - najlepszy strażnik wdrożeń, jakiego znam.
  6. Monitory DNS na A, MX i TXT (SPF), MX i SPF w trybie dokładnym.
  7. Monitor portu TCP na wszystko, co nie jest stroną: pocztę, bazę, NAS-a.
  8. Monitor API, jeśli front żywi się JSON-em.
  9. Konto w zespole dla osoby po stronie klienta i strona statusów z linkiem w mailu.

To jest kwadrans na projekt. Zwraca się przy pierwszym pytaniu „co się stało z tą stroną", na które odpowiadasz z datą, godziną i listą zmian zamiast obietnicy, że sprawdzisz.