Monitorowanie skryptów produkcyjnych: alerty, logi i metryki, które pozwalają spać spokojniej w nocy

0
35
Rate this post

Nawigacja:

Dlaczego skrypty produkcyjne są groźniejsze niż wyglądają

Niewinne „małe skrypty”, duże konsekwencje

Większość kłopotów z produkcją nie bierze się z wielkich, głośnych systemów, tylko z małych, niepozornych skryptów, które „ktoś kiedyś napisał na szybko”. Najczęściej zaczyna się od prostego zadania: przenieść plik, wygenerować raport, wyczyścić tabelę pomocniczą, zsynchronizować dane raz dziennie. Skrypt ląduje w cronie na jednym serwerze, działa, nikt o nim nie myśli. Po roku okazuje się, że od tego zadania zależy fakturowanie, codzienny import zamówień czy SLA z zewnętrznym partnerem.

Problem w tym, że takie skrypty prawie nigdy nie przechodzą formalnego cyklu tworzenia: nie ma backlogu, SLO, przeglądu architektury, nie ma też wymagań obserwowalności. Jest tylko plik .sh lub .py, czasem z kilkoma echo albo print. Dopóki działa, wszyscy są zadowoleni. Gdy przestanie – nagle wychodzi na jaw, że to wąskie gardło poważnego procesu biznesowego, a nikt nie wie, co się dzieje, bo nie ma logów, metryk, ani nawet prostego powiadomienia o awarii.

Groźne jest nie to, że skrypt jest skomplikowany, tylko że jest niewidzialny. Nie widać go na dashboardach, nie wchodzi do standardowego monitoring stacku (Prometheus, Grafana, ELK), nie jest objęty procesem on-call. To, że coś „działa od lat”, zwykle oznacza tylko tyle, że awarie jeszcze nie zostały odkryte lub ich efekt jest rozsmarowany w czasie i dawno przestał być kojarzony ze źródłem problemu.

W praktyce mały skrypt, który dorasta do roli krytycznej integracji, staje się najbardziej ryzykownym komponentem całego procesu. Im później to zostanie zauważone, tym większe zdziwienie, gdy nagle przestaje być „mały”.

Ręczne „odhaczanie” vs automatyczne czujniki

W wielu firmach wciąż funkcjonuje model „monitoringu” polegający na tym, że ktoś rano sprawdza, czy pojawił się plik, czy raport przyszedł na maila albo czy w bazie danych jest nowa porcja danych. Ten człowiek jest tak naprawdę systemem monitoringu – tyle że żywym. Działa to do momentu, aż ta osoba ma urlop, jest chora lub zawalimy się kolejnymi obowiązkami i checklista przestaje być realizowana tak skrupulatnie.

Ręczne odhaczanie ma jeszcze jeden problem: reaguje dopiero wtedy, gdy skutek jest już widoczny. Jeśli raport powinien być gotowy o 6:00, a o 9:00 ktoś zauważa, że go nie ma, to jesteśmy co najmniej trzy godziny spóźnieni z reakcją. Automatyczne czujniki – metryki, logi i alerty – pozwalają złapać problemy w chwili, gdy skrypt się wykoleja, a nie wtedy, gdy kolejny system zaczyna zgłaszać brak danych.

Popularny scenariusz: batch nocny w cronie, który z jakiegoś powodu utknął. Bez monitoringu dowiadujesz się o tym wtedy, gdy system sprzedaży nie może pobrać nowych cenników rano. Z monitorowaniem skryptów produkcyjnych dostajesz alert o wydłużonym czasie trwania joba już kilka minut po tym, jak przekroczył on normalny czas pracy, i masz szansę go zrestartować, zanim ktokolwiek z biznesu cokolwiek zauważy.

Automatyczny monitoring działa też wtedy, gdy nikt nie patrzy na ekran. Nawet najlepszy człowiek nie wygra z prostym, dobrze skonfigurowanym czujnikiem, który policzy czas trwania, sprawdzi wolumen danych i da sygnał, gdy coś odstaje od normy.

Gdzie ukrywają się skrypty bez obserwowalności

Skrypty produkcyjne żyją w zaskakującej liczbie miejsc, często poza głównym radarem zespołu SRE czy DevOps:

  • Cron na pojedynczych serwerach – klasyka. Jeden serwer „narzędziowy”, na nim kilkanaście crontabów różnych osób. Nikt nie ma pełnej inwentaryzacji, co się tam naprawdę uruchamia.
  • Pipeline’y CI/CD – skrypty migracyjne, generatory artefaktów, dodatkowe kroki post-deploy. Jeśli deployment jest monitorowany, to same skrypty wewnątrz pipeline’u często już nie.
  • Orkiestratory zadań typu Airflow, Luigi, Prefect – dają pewien poziom wglądu, ale tylko pod warunkiem, że developerzy zadbali o logi, retry i sensowne metryki. Sam fakt użycia Airflow nie oznacza jeszcze dobrego monitoringu.
  • Funkcje serverless (AWS Lambda, GCP Cloud Functions, Azure Functions) – wyzwalane eventami, teoretycznie dobrze zintegrowane z monitoringiem chmurowym, ale łatwo w nich napisać logikę, która nie raportuje poprawnie błędów biznesowych i cichych awarii.

Wspólny mianownik: brak systematycznego podejścia do observability. Dla usług HTTP przyjmuje się standard: logi, metryki, trace’y, SLO, dashboard. Dla skryptów – często tylko „uruchom i trzymaj kciuki”. Dopóki to się nie zmieni, nocne wybudzenia będą nieproporcjonalnie często wynikiem drobnych, zaniedbanych procesów wsadowych.

Konsekwencje braku monitoringu skryptów

Gdy skrypt nie ma żadnego monitoringu, najgorsze nie jest to, że przestaje działać. Najgorsze jest to, że nikt tego nie zauważa na czas. Typowe skutki:

  • Cichy brak wykonywania – cron wyłączony, uprawnienia zmienione, serwer zrestartowany i nikt nie włączył crona z powrotem. Skrypt nie działa tygodniami, a problem ujawnia się dopiero przy audycie lub dużym incydencie.
  • Stopniowa degradacja danych – np. skrypt importujący dane działa, ale przetwarza tylko część plików z powodu zmienionego formatu. Dane wyglądają „prawie” dobrze, ale w raportach brakuje części rekordów.
  • Kaskadowe awarie kolejnych systemów – brak danych wejściowych dla kolejnych etapów pipeline’u ETL, błędne przeliczenia, rozjechane raporty, blokada zamówień. Zwykle wtedy pierwsze pytanie brzmi: „dlaczego nikt tego nie zauważył wcześniej?”.
  • Brak możliwości root cause analysis – bez logów i metryk ciężko odpowiedzieć, czy problem pojawił się wczoraj, tydzień temu czy pół roku temu. Trzeba rekonstruować historię z backupów, snapshotów lub strzępów informacji od użytkowników.

Monitoring skryptów produkcyjnych nie eliminuje błędów, ale sprawia, że błędy są szybciej wychwytywane, lepiej zrozumiane i można je powtórzyć na testach. To często wystarcza, żeby noc zamieniła się z „paniki o 3:00” w „spokojne sprawdzenie alertu rano”.

Co to znaczy „monitorować skrypt” – trzy filary, nie jeden

Status wykonania to dopiero początek

Monitoring skryptów wielu osobom kojarzy się z jednym pytaniem: „czy się wykonał?”. To tylko mały fragment obrazu. W praktyce liczą się trzy poziomy:

  • Dostępność – czy skrypt w ogóle się uruchomił i zakończył (jakim kodem wyjścia).
  • Poprawność – czy zrobił to, co powinien, a wynik jest biznesowo sensowny.
  • Wydajność – ile czasu, pamięci, CPU i I/O zużył, oraz czy mieści się w oknie czasowym.

Skrypt, który kończy się kodem 0, ale importuje tylko połowę danych z powodu zmiany formatu pliku, jest z punktu widzenia biznesu równie zły, jak skrypt, który w ogóle się nie uruchomił. Z kolei zadanie, które co prawda działa poprawnie, ale zamiast 10 minut trwa 2 godziny, może blokować kolejne kroki, wywoływać timeouty lub zjadać zasoby innych systemów.

Dlatego pełne monitorowanie skryptów produkcyjnych oznacza mierzenie nie tylko wyniku technicznego (exit code), ale też kwalifikowanego wyniku biznesowego (np. liczba poprawnie przetworzonych rekordów względem oczekiwanej liczby) oraz obserwację kluczowych parametrów wydajnościowych.

Trzy filary: logi, metryki, alerty

Dobry monitoring skryptów opiera się na trzech filarach:

  • Logi – dają kontekst. Odpowiadają na pytania „co dokładnie się działo?”, „na którym kroku to padło?”, „jakie parametry wejściowe zostały użyte?”. Bez logów analiza incydentu sprowadza się do zgadywania.
  • Metryki – dostarczają trendów i liczb. Pozwalają zobaczyć, że czas wykonania rośnie od tygodni, liczba rekordów spada od kilku dni albo nagle pojawił się skok błędów. To one budują dashboardy i wykresy.
  • Alerty – zapewniają reakcję. Bez nich możemy co najwyżej ręcznie przeglądać wykresy. Alert mówi: „tu i teraz dzieje się coś, co wymaga interwencji człowieka lub automatu”.

Popularną praktyką jest skupienie się tylko na jednym filarze, np. na alertach e-mail opartych na kodzie wyjścia. Taki model działa, dopóki coś się po prostu wywraca. Gdy problem jest subtelny – np. skrypt zaczyna robić mniej, wolniej lub „ciut inaczej” – alerty oparte wyłącznie na exit code milczą. Z kolei same logi, choć bogate w informacje, bez metryk i alertów wymagają kogoś, kto będzie je aktywnie przeglądał.

Zestaw logi + metryki + alerty jest potrzebny nawet w małych zespołach. Różnica między korporacją a małym startupem nie polega na tym, czy te trzy filary są, tylko jak są zrealizowane: prostszymi narzędziami, mniejszą liczbą metryk, ale dalej w tej samej logice.

Dlaczego „exit code + e-mail” często przestaje działać

Starsza szkoła mówi: „w skrypcie ustaw set -e, jak się wywali, wyślij maila do admina i po sprawie”. To podejście bywa kuszące, bo jest szybkie i tanie. Tam, gdzie zadanie jest rzadkie (raz w tygodniu), niekrytyczne i proste – może to wystarczyć. Jednak w kilku scenariuszach takie rozwiązanie regularnie się sypie:

  • Zadania częste – jeśli skrypt odpala się co kilka minut, to w razie błędu zalewa skrzynkę falą maili. Zespół bardzo szybko zaczyna ignorować powiadomienia albo zakłada filtry. W efekcie prawdziwe problemy toną w spamie alarmów.
  • Zadania wrażliwe na flapping – chwilowe problemy sieciowe, sporadyczne błędy API, tymczasowy brak pliku. Skrypt raz działa, raz nie działa. Alerty przychodzą i znikają, nikt nie wie, czy to realny problem, czy „tak bywa”.
  • Duże wolumeny – jeśli skrypt przetwarza dużo danych, to może się zdarzyć, że 99% rekordów jest poprawnych, a 1% błędnych. Kod wyjścia 0, bo skrypt uznaje, że „jest dobrze”. Tylko że ten 1% to twardy limit akceptowany przez biznes, którego nikt nie nadzoruje.

Lepszą alternatywą jest warstwowy monitoring:

  • najpierw metryki (czas, liczba rekordów, liczba błędów),
  • na nich progi alertowania (np. odchylenie od mediany, zmiana trendu),
  • dopiero na końcu powiadomienie przez centralny system (PagerDuty, Opsgenie, Slack, MS Teams, e-mail).

Taki model pozwala oddzielić drobne problemy techniczne od realnych incydentów, nie zabijać ludzi spamem i jednocześnie mieć wystarczająco dużo danych, by po incydencie coś poprawić, a nie tylko „ręcznie odpalić jeszcze raz”.

Monitoring dostępności, poprawności i wydajności w praktyce

Żeby nie skończyć z dziesiątkami mierników, które nic nie wnoszą, warto trzymać się prostego podziału:

  • Dostępność:
    • metryka: liczba wykonań w określonym przedziale czasu,
    • metryka: status ostatniego wykonania (sukces/porażka),
    • alert: brak wykonania w oknie czasowym (np. brak joba w ciągu 2h).
  • Poprawność:
    • metryka: liczba przetworzonych rekordów,
    • metryka: liczba odrzuconych/niepoprawnych rekordów,
    • alert: przekroczenie progu błędów (np. >5% rekordów odrzuconych) lub podejrzanie mała liczba rekordów względem mediany.
  • Wydajność:
    • metryka: czas trwania skryptu,
    • metryka: zużycie pamięci/CPU (opcjonalnie, jeśli jest to realny problem),
    • alert: czas trwania powyżej X minut lub powyżej 2x mediany z ostatniego tygodnia.

Nawet tak ograniczony zestaw metryk, jeśli jest konsekwentnie stosowany, znacząco podnosi poziom kontroli nad skryptami produkcyjnymi, bez zamieniania się w pełny zespół SRE.

Inżynierka monitoruje serwery i logi na laptopie w serwerowni
Źródło: Pexels | Autor: Christina Morillo

Jak zaprojektować prosty, ale sensowny model monitoringu

Od inwentaryzacji do mapy krytyczności

Jak policzyć, co naprawdę jest krytyczne

Klasyczne „priorytetyzowanie” często kończy się tym, że wszystko jest „high”. Żeby model monitoringu miał sens, trzeba rozróżnić skrypty, które mogą się wywalić bez większych konsekwencji, od tych, które wprowadzają firmę w tryb pożarowy.

Praktyczna mapa krytyczności opiera się na trzech pytaniach:

  • Wpływ na biznes – co się stanie, jeśli skrypt nie zadziała przez 24 godziny? Utrata przychodu, kary umowne, ręczne obejścia czy tylko brzydszy raport?
  • Częstotliwość i wolumen – jak często się wykonuje i ile danych dotyka? Rzadki, ale masowy proces może być groźniejszy niż częsty, ale drobny.
  • Czas wykrycia ręcznego – jak szybko ktoś zorientuje się, że coś jest nie tak, bez monitoringu? Godzina, dzień, miesiąc?

Z tych odpowiedzi da się złożyć prostą klasyfikację:

  • Krytyczne – bez nich proces biznesowy staje, a ręczne obejścia są bardzo drogie lub nierealne.
  • Ważne – wpływają na jakość danych, SLA raportów, komfort pracy zespołów, ale awaria przez kilka godzin nie ruinuje dnia.
  • Pomocnicze – skrypty techniczne, porządkujące, ułatwiające życie, ale nie decydujące o niczym istotnym.

Typową radą jest „monitoruj wszystko tak samo”. To nie działa, bo kończy się albo inflacją alertów, albo całkowitym brakiem zaufania do systemu powiadomień. Zamiast tego lepiej przyjąć, że:

  • skrypty krytyczne dostają najbogatszy monitoring (logi + metryki + ostre alerty, integracja z on-callem),
  • ważne – solidne metryki i mniej agresywne alerty, często ograniczone do godzin pracy,
  • pomocnicze – tylko metryki i logi, a reakcji oczekuje się ad hoc (np. podczas przeglądu dashboardów).

Minimalny zestaw pytań przed wdrożeniem monitoringu

Zamiast od razu instalować kolejne agenty i eksportery, sensowniej zacząć od krótkiej rozmowy o każdym ważniejszym skrypcie. Pięć prostych pytań wystarczy, żeby zaprojektować monitoring bez przeintelektualizowania tematu:

  1. Kiedy ten skrypt „naprawdę” musi się wykonać? (konkretne okno czasowe, a nie „w nocy”).
  2. Po czym poznajemy, że wynik jest dobry? (typowo jakaś liczba, zakres, stosunek, nie „bo nie ma błędu”).
  3. Po czym poznamy, że jest źle, ale jeszcze nie katastrofalnie? (strefa ostrzegawcza, zanim wszystko się rozsypie).
  4. Jak długo możemy „nie wiedzieć”, że jest problem? (to wprost definiuje okno SLA na alert).
  5. Kto ma prawo zignorować alert? (konkretna rola, nie „ktoś z zespołu”).

Te odpowiedzi można wprost przełożyć na metryki i progi, bez skomplikowanych wzorów. Jeśli skrypt musi się zakończyć do godziny 5:00, to monitoring nie powinien czekać z alertem do 9:00 „bo tak wygodniej”. Jeśli codziennie przetwarza około 100 tys. rekordów, to podejrzanie niską liczbą nie jest 90 tys., tylko np. 20 tys. – i to powinno mieć osobny próg.

Unikanie pułapki „monitoringu z Excela”

Częsta rada w korporacjach brzmi: „stwórz arkusz z listą jobów, właścicielem, priorytetem i opisem”. Sam arkusz nie jest problemem, dopóki nie próbuje udawać monitoringu. Lista w Excelu nie powie, że skrypt się wywalił przez brak miejsca na dysku; powie tylko, do kogo zadzwonić, gdy ktoś inny już ten problem wykryje.

Excel przydaje się jako punkt startowy inwentaryzacji, ale monitoring żyje dopiero tam, gdzie są automatyczne sygnały z systemów, a nie ręcznie aktualizowane pola. Zdrowa praktyka:

  • używać arkusza tylko do opisu (co robi skrypt, krytyczność, RPO/RTO, właściciel),
  • linkować z niego do konkretnych dashboardów i reguł alertowych,
  • co jakiś czas porównać listę z rzeczywistymi jobami (np. z crona, Airflow, systemu CI/CD), żeby nie monitorować duchów i nie pominąć nowości.

Logi, które pomagają, a nie tylko zajmują dysk

Struktura ponad „print debug”

Najpopularniejsza rada brzmi: „loguj dużo, wszystko się przyda”. W praktyce kończy się to tysiącami linii tekstu, gdzie najważniejsza informacja ginie w szumie, a narzędzia typu Elasticsearch zaczynają kosztować realne pieniądze.

Dużo skuteczniejsze jest podejście odwrotne: loguj mniej, ale w sposób strukturalny. Zamiast losowych echo "tu jestem" w kilku miejscach, lepiej zdefiniować jasne kategorie zdarzeń i trzymać się ich konsekwentnie:

  • START – rozpoczęcie zadania, z parametrami wejściowymi (daty, zakres, środowisko, wersja skryptu).
  • CHECKPOINT – kluczowe kroki z krótką informacją: co zostało zrobione i w jakiej skali (np. „wczytano 15 plików z katalogu X”).
  • WARNING – sytuacje nietypowe, ale jeszcze nie krytyczne (np. pominięty plik z powodu braku uprawnień).
  • ERROR – błędy, które wpływają na końcowy wynik lub zmuszają do przerwania procesu.
  • SUMMARY – końcowy podsumowujący log z liczbami (czas trwania, liczba rekordów, liczba błędów).

W skryptach shellowych da się to zrobić, stosując prostą funkcję logującą, np.:

log() {
  local level="$1"; shift
  local msg="$*"
  echo "$(date -Iseconds) level=$level msg="$msg""
}

log INFO "START job=my_job date_from=$DATE_FROM date_to=$DATE_TO"

Takie podejście ułatwia późniejsze parsowanie i wyszukiwanie, nawet jeśli logi lądują w prostym syslogu czy pliku tekstowym.

Logowanie w formacie przyjaznym maszynie

Człowiek lubi zdania, maszyna – klucze i wartości. Dla monitoringu ważniejszy bywa log z polami niż pięknie napisany opis. Zamiast:

Przetworzono 10234 rekordów, z czego 23 z błędami

lepiej:

SUMMARY processed=10234 errors=23 duration_sec=57

Taki log można łatwo przekonwertować na metryki (np. Prometheusa), nawet prostymi narzędziami typu awk czy logstash. Dzięki temu jeden fragment informacji służy jednocześnie do analizy „po ludzku” i do automatycznego monitoringu.

Jakie informacje naprawdę ratują życie przy incydencie

Nadmierne logowanie kusi, ale w krytycznym momencie liczy się kilka konkretów. Dobrą heurystyką jest pytanie: „co muszę wiedzieć, żeby odtworzyć ten przypadek na testach?”. Typowo są to:

  • Identyfikatory danych wejściowych – nazwy plików, zakres dat, ID batcha, wersja schematu.
  • Środowisko wykonania – host, wersja skryptu, commit SHA, ścieżki, ważne zmienne środowiskowe.
  • Kluczowe liczby – wolumen danych na wejściu i wyjściu, liczba błędów, liczba retry.
  • Fragmenty błędnych danych – próbka rekordów, które poleciały z błędem (z anonimizacją, jeśli trzeba).

To one robią różnicę między szybkim „aha, to przez ten jeden plik CSV z innym separatorem” a tygodniem grzebania w backupach.

Czego nie logować, jeśli ma się ograniczony budżet na przechowywanie

Popularna rada mówi: „loguj wszystko, storage jest tani”. Tani jest tylko do momentu, aż ktoś wystawi fakturę za klaster logów. Gdy budżet jest ograniczony, sensowniej przyjąć kilka prostych zasad:

  • Nie loguj powtarzalnych, masowych komunikatów typu „przetwarzam rekord X” dla każdego rekordu. Lepiej logować podsumowania per 1000 rekordów.
  • Traktuj DEBUG jako luksus, a nie domyślny poziom. Można go włączyć czasowo przy konkretnym incydencie.
  • Rozdziel logi operacyjne od śmieci – logi HTTP czy SQL z poziomu frameworka często można przyciąć, zostawiając tylko błędy i ostrzeżenia.
  • Ustal krótszy retention dla szczegółowych logów, a dłuższy dla podsumowań (np. metryk).

Dobrą praktyką jest też generowanie osobnych plików lub strumieni logów dla ERROR i SUMMARY, które są zbierane priorytetowo, gdy trzeba ograniczyć resztę.

Błędy, które powinny „krzyczeć” w logach

Nie każdy error musi trafiać do alertu, ale niektóre powinny być widoczne od razu. Kilka typowych kategorii, które zasługują na wyróżnienie:

  • Błędy trwałe – np. niepoprawny format pliku, brak wymaganej kolumny w bazie, błędna konfiguracja. Tu retry zwykle nie pomoże, konieczna jest interwencja człowieka.
  • Błędy „ciszej degradujące dane” – pomijanie rekordów, domyślne wartości w miejsce brakujących, ciche obcinanie stringów. Jeśli zachodzą masowo, jakość danych spada, choć job technicznie „się udał”.
  • Błędy bezpieczeństwa i uprawnień – odmowy dostępu, nieudane loginy do baz, próby korzystania z zasobów spoza whitelisty.

Te kategorie warto od razu oznaczać w logach wyraźnymi tagami, np. error_type=PERMANENT, error_type=DATA_QUALITY. Ułatwia to późniejsze budowanie alertów opartych nie tylko na liczbie błędów, ale też na ich charakterze.

Metryki skryptów: czas trwania, wolumen, błędy i nieoczywiste sygnały

Dlaczego pojedyncza metryka to za mało

Popularnym podejściem jest „zmierz czas wykonania i tyle”. W stabilnych, prostych skryptach rzeczywiście może to wystarczyć. Problem pojawia się, gdy skrypt działa na zmiennym wolumenie danych albo jego zadanie ma charakter sezonowy.

Sam czas trwania bywa mylący. Skrypt, który nagle robi się dwa razy wolniejszy, ale przetwarza trzy razy więcej danych, nie jest problemem wydajnościowym, tylko sukcesem biznesowym. Z kolei job, który wykonuje się szybciej niż zwykle, może oznaczać, że przetwarza drastycznie mniej danych niż powinien.

Dlatego metryki trzeba patrzeć parami lub w małych zestawach, np.:

  • czas trwania + liczba rekordów,
  • liczba rekordów + liczba błędów,
  • wolumen danych + rozmiar outputu.

Podstawowe metryki techniczne i biznesowe

Dla większości skryptów wystarczy kilka technicznych metryk uzupełnionych jedną–dwiema biznesowymi. Typowy zestaw:

  • Techniczne:
    • job_duration_seconds – czas od startu do końca, najlepiej z podziałem na etapy (load, transform, save).
    • job_runs_total – liczba wykonań w danym okresie, z etykietą status=success|failure.
    • job_retries_total – ile razy skrypt próbował ponownie wykonać krok.
    • job_memory_max_bytes, job_cpu_seconds – tylko tam, gdzie zasoby są realnym wąskim gardłem.
  • Biznesowe / domenowe:
    • records_processed_total – liczba rekordów wejściowych.
    • records_output_total – liczba rekordów wynikowych (po filtrach, agregacjach).
    • records_error_total – liczba rekordów błędnych/odrzuconych.
    • files_processed_total – liczba plików, paczek, raportów użytych jako wejście.

W prostych skryptach te metryki można generować nawet bez zaawansowanych bibliotek – zwykłe wypchnięcie liczb do stdout w formacie zrozumiałym dla kolektora metryk bywa w zupełności wystarczające.

Ustalanie progów: nie stałe liczby, lecz odniesienie do historii

Typowa rada głosi: „jeśli czas wykonania > X minut, to alert”. Problem w tym, że X zwykle jest wymyślany na oko i szybko przestaje mieć sens. Przy zmieniającym się wolumenie dane progi statyczne albo będą zbyt niskie (ciągłe fałszywe alarmy), albo zbyt wysokie (prawdziwą degradację zauważymy za późno).

Bardziej odporne podejście to porównywanie do własnej historii:

Jak kalibrować alerty na podstawie historii, a nie życzeń

Porównanie do historii nie oznacza od razu zaawansowanych algorytmów. Na początek wystarczy prosty model „średnia + margines bezpieczeństwa”, ale policzony z danych, a nie z przeczucia. Przykładowo:

  • zbierasz przez miesiąc metryki job_duration_seconds i records_processed_total dla danego joba,
  • liczysz typowy czas trwania przy danym wolumenie (np. medianę w podziale na „dni robocze / weekend”),
  • ustawiasz alert, gdy czas odbiega o określony procent od mediany, np. duration > 2 * median_duration_for_last_30_runs.

Bazowanie na medianie, a nie średniej, lepiej znosi pojedyncze, ekstremalne przypadki (np. jednorazowy awaria bazy). Proporcjonalny próg („2× mediany”) jest też bardziej odporny na stopniowo rosnący wolumen.

Kluczowa rzecz: progi powinny być per job, nie „globalne”. Skrypt, który normalnie działa 10 sekund, może wymagać progu 30 sekund, podczas gdy pipeline ETL liczący się zwykle godzinę potrzebuje widełek typu 2–3 godziny. Jeden uniwersalny limit „jak job idzie dłużej niż godzinę, to źle” prowadzi prosto do inflacji alertów.

Relacje między metrykami zamiast pojedynczych progów

Same progi to połowa historii. Druga to relacje między metrykami. Najprostszy i często bardzo skuteczny wskaźnik to czas na rekord (lub plik, batch, fakturę – zależnie od domeny):

processing_time_per_record = job_duration_seconds / records_processed_total

Tu widać różnicę między skryptem, który faktycznie zwolnił, a takim, który po prostu dostał więcej pracy. Alert typu „processing_time_per_record skoczył o 50% względem mediany z ostatnich 7 dni” bywa znacznie cichszy, a przy tym bardziej trafny niż „job_duration_seconds > X”.

Podobnie da się zbudować inne relacje:

  • error_rate = records_error_total / records_processed_total – procent błędów, a nie absolutna liczba.
  • compression_ratio = records_output_total / records_processed_total – ile danych „przeżywa” filtrację i agregacje.
  • avg_file_size = input_volume_bytes / files_processed_total – wzrost średniego rozmiaru pliku często zapowiada kłopoty z czasem lub pamięcią.

Relacje metryk szczególnie pomagają w systemach sezonowych. Jeśli sprzedaż w Black Friday rośnie pięć razy, wzrost job_duration_seconds o 4× nie jest problemem – ale processing_time_per_record skaczący dwa razy już nim jest.

Rozpoznawanie „dni specjalnych” i sezonowości

Popularna rada: „porównuj do średniej z ostatnich 30 dni” sprawdza się tylko tam, gdzie wolumen jest w miarę równy. W systemach finansowych, retailu czy serwisach B2C dzień miesiąca, dzień tygodnia, a nawet godzina potrafią mieć ogromne znaczenie.

Zamiast jednej globalnej historii przydaje się podział na „koszyki porównań”:

  • dni tygodnia – osobny baseline dla pon–pt i osobny dla weekendu,
  • kalendarz biznesowy – dni robocze vs. święta, zamknięcia miesiąca, zamknięcia kwartału,
  • pory dnia – job uruchamiany co godzinę będzie miał inne typowe zachowanie o 3:00 w nocy niż o 12:00.

Jeśli nie ma czasu na zaawansowany system, prosty trick to tagowanie metryk etykietami typu day_of_week, is_month_end=true|false, a następnie budowanie osobnych dashboardów/alertów dla tych etykiet. Ten sam job, ale z inną etykietą, może mieć zupełnie inne progi.

Sygnatury awarii: co obserwować poza czasem i błędami

Gdy monitoring opiera się tylko na czasie i liczbie błędów, część problemów przechodzi bokiem. Jest kilka sygnałów, które często wyprzedzają awarię, a są tanie do zebrania:

  • wzrost liczby retry – jeśli metryka job_retries_total rośnie, ale finalnie status jest „success”, to jest to wczesny sygnał niestabilności.
  • zmiana struktury błędów – nagłe pojawienie się nowych typów błędów (error_type, kody SQL, HTTP) to wskazówka, że coś w otoczeniu się zmieniło.
  • fluktuacje rozmiaru wejścia/wyjścia – np. brak plików z jednego źródła, nagły wzrost liczby rekordów z konkretnego systemu.
  • czas poszczególnych etapów – wzrost czasu w jednej fazie (np. tylko „save to DB”) pomaga szybko wskazać wąskie gardło.

Dobrym pomysłem jest relacjonowanie tych sygnałów z innymi komponentami. Jeśli rośnie job_retries_total na etapie zapisu do bazy i jednocześnie system bazodanowy zgłasza wysoki czas odpowiedzi, diagnoza znacznie przyspiesza.

Alerty „ciche” i „głośne”: dwa poziomy reakcji

Kolejny mit: każdy problem z jobem musi natychmiast wysyłać powiadomienie na telefon. W praktyce to prosty przepis na ignorowanie alertów. Lepszy model zakłada dwa poziomy:

  • alert cichy – widoczny na dashboardzie, oznacza „coś jest nie tak, ale system nadal dostarcza dane”; może to być wzrost czasu na rekord, lekki wzrost error_rate, pojedyncze retry,
  • alert głośny – powiadomienie na kanał zespołu / pager; zarezerwowany dla zdarzeń typu „job nie zakończył się przed SLA”, „brak danych z całego źródła”, „error_rate przekroczył bezpieczny próg”.

Warunek, aby taki podział działał: definicja, co jest „głośne”, powinna być spisana, a nie ustalana ad hoc przy każdym incydencie. Zmiany w definicji dobrze powiązać z retrospektywami po awariach: jeśli alert był za cichy lub za głośny, zmiana powinna trafić do konfiguracji, a nie tylko do pamięci zespołu.

Metryki a SLA: kiedy skrypt spóźnia się naprawdę

Nie każdy poślizg joba ma znaczenie biznesowe. Skrypt, który miał się zakończyć do 3:00 w nocy, a kończy o 3:10, może nie stanowić problemu, jeśli raporty dla użytkowników generowane są dopiero po 6:00. Jednocześnie 10 minut opóźnienia joba, który musi skończyć się przed otwarciem giełdy, to czasem katastrofa.

Dlatego metryki skryptów warto łączyć z SLA lub SLO na dane:

  • definiujesz godzinę, do której dane mają być dostępne (np. reports_ready_by=06:00),
  • dla krytycznych jobów liczysz metrykę typu job_delay_seconds = max(0, job_end_time - deadline_time),
  • alert budujesz na job_delay_seconds > 0 dla jobów oznaczonych critical=true.

Taki model jest bliżej realnego wpływu na biznes niż gołe „trwa dłużej niż zwykle”. Skrypt o podwójnym czasie wykonania, który nadal kończy się przed SLA, może generować jedynie alert „cichy” – sygnał do optymalizacji, nie do wybudzania kogoś w nocy.

Podgląd „ostatniego dobrego przebiegu” jako punkt odniesienia

Ludzką naturą jest porównywanie „jak było, gdy działało”. Monitoring może to ułatwić, utrzymując łatwo dostępne dane z ostatniego poprawnego przebiegu skryptu:

  • czas trwania,
  • liczbę rekordów wejściowych i wyjściowych,
  • wskaźniki błędów,
  • wersję skryptu i głównych zależności.

W praktyce często wystarczy osobna metryka lub dokument w bazie z tagiem last_success, aktualizowana tylko po pełnym, udanym przebiegu. Przy incydencie porównanie „obecny run vs. last_success” jest szybsze niż przeglądanie wykresu z 90 dni.

Przykład z życia: zespół integracyjny miał problem z jobem, który przestał ładować dane z jednego z partnerów. Liczba rekordów ogółem wyglądała poprawnie, bo inne źródła wciąż dostarczały dane. Dopiero porównanie do „ostatniego dobrego przebiegu” na poziomie per partner ujawniło, że dla jednego z nich wolumen nagle wynosi zero.

Metryki „na wejściu” i „na wyjściu” – dwie pieczenie przy jednym ogniu

Częstym błędem jest monitorowanie tylko końcowego rezultatu joba („czy się powiódł”, „ile trwał”). Tymczasem wiele problemów wynika z tego, co dzieje się przed i po skrypcie: czy dane w ogóle dotarły, czy kolejny etap je odebrał. Prosty sposób na zamknięcie tej luki to metryki i logi „input” oraz „output”:

  • na wejściu – liczba plików/rekordów/wiadomości odebranych z każdego źródła,
  • na wyjściu – liczba artefaktów, które skrypt wygenerował i gdzie je umieścił (katalog, bucket, schema w bazie).

To otwiera furtkę do kontrolowania zgodności: czy job B dostał tyle danych, ile job A wyprodukował. Jeśli job A raportuje records_output_total=100k, a job B widzi records_processed_total=80k dla tego samego okresu, problemem nie jest żaden z nich z osobna, tylko „szczelina” między nimi.

Łączenie metryk skryptów z monitoringiem infrastruktury

Analiza joba w oderwaniu od CPU, pamięci czy I/O serwera to proszenie się o błąd w diagnozie. Gdy skrypt nagle zwalnia, odruchowo podejrzewa się zmiany w kodzie. Tymczasem przyczyną bywa współdzielony serwer batchowy, na którym ktoś uruchomił dodatkową intensywną aplikację.

Rozsądny kompromis wygląda tak:

  • metryki skryptów zawsze zawierają etykiety typu host, node lub pod,
  • dashboard skryptu pokazuje obok metryk joba podstawowe metryki infrastruktury dla tego hosta (CPU, I/O wait, użycie dysku),
  • alerty wydajnościowe joba zawierają odnośnik lub korelację do stanu hosta w tym samym czasie.

Nie chodzi o to, aby każdy zespół biznesowy został ekspertem od kernelowych statystyk. Wystarczy zdolność szybkiego stwierdzenia: „to nie kod, to środowisko”. Taka informacja oszczędza godziny grzebania w patchach i commitach.

Jak nie utonąć w metrykach: minimalny, ewoluujący zestaw

Popularna pułapka: „skoro metryki są tanie, mierzmy wszystko”. W teorii brzmi kusząco, w praktyce kończy się tablicą z setkami linii, z których większość nikt nigdy nie spojrzy. Rozsądniejsze podejście to:

  1. Zacznij od 3–5 metryk na job: czas trwania, status, liczba rekordów wejścia/wyjścia, liczba błędów.
  2. Po każdym poważniejszym incydencie zadaj pytanie: „jaką jedną metrykę chcielibyśmy mieć, aby następnym razem wykryć to szybciej?”. Dodaj tylko ją.
  3. Raz na kwartał przeglądaj metryki, które nie były użyte w żadnym incydencie ani analizie. Te naprawdę zbędne wyłącz.

Ten prosty cykl „dodaj minimalnie po incydencie, usuwaj nieużywane” lepiej skaluje się niż próba zaprojektowania idealnego zestawu metryk na starcie. Najważniejsze, aby decyzje o nowych metrykach wynikały z realnych zdarzeń, a nie z abstrakcyjnych scenariuszy.

Najczęściej zadawane pytania (FAQ)

Dlaczego małe skrypty w produkcji są tak ryzykowne?

Małe skrypty zwykle powstają „na szybko”, poza oficjalnym procesem wytwarzania oprogramowania. Nie mają backlogu, przeglądu architektury, SLO ani wymagań dotyczących logów i metryk. Po roku okazuje się, że taki plik .sh czy .py obsługuje fakturowanie, import zamówień albo kluczową integrację z partnerem.

Ryzyko nie wynika z ich złożoności, tylko z niewidzialności. Nie widać ich na dashboardach, nie są objęte on-callem, często nikt nawet nie wie, gdzie dokładnie działają. Gdy przestają się wykonywać, problem ujawnia się dopiero wtedy, gdy biznes widzi skutki – np. brak danych, błędne raporty, opóźnione zamówienia.

Jak monitorować skrypty w cronie, żeby szybko wykrywać awarie?

Sam cron oraz kod wyjścia procesu to za mało. Podstawą jest centralizacja logów i proste metryki: czas startu, czas trwania, liczba przetworzonych rekordów, liczba błędów. Te dane można wysłać np. do Prometheusa, InfluxDB czy systemu logowania (ELK, Loki, chmurowy logging), a na bazie metryk zbudować alerty.

Popularna rada „wystarczy mail z crona” działa tylko w małych środowiskach i dopóki ktoś naprawdę czyta te maile. Gdy skryptów jest kilkanaście, skrzynka zamienia się w spam. Lepsze jest podejście: jeden dashboard, kilka rozsądnych alertów (np. brak uruchomienia, czas trwania powyżej X, liczba rekordów poniżej oczekiwanej wartości).

Czy logi wystarczą do monitoringu skryptów produkcyjnych?

Same logi są przydatne przy analizie incydentu, ale słabo nadają się do wczesnego wykrywania problemów. Przekopywanie się przez pliki logów rano, żeby „zobaczyć, czy coś padło”, to tylko przeniesienie ręcznego odhaczania z excela do terminala.

Skuteczniejsze jest traktowanie logów jako źródła kontekstu, a nie czujnika. Czujnikami są metryki (czas trwania, liczba rekordów, status wykonania), na których budujesz automatyczne alerty. Dopiero gdy alert się odpali, zaglądasz w logi, żeby ustalić przyczynę i dokładny krok, na którym skrypt się wykoleił.

Jakie metryki są kluczowe przy monitorowaniu skryptów batchowych?

Trzy najważniejsze grupy metryk to: dostępność, poprawność biznesowa i wydajność. Minimalny zestaw to:

  • czy skrypt w ogóle się uruchomił i zakończył (status, kod wyjścia),
  • czas trwania joba i ewentualne timeouty,
  • liczba przetworzonych rekordów vs oczekiwana liczba lub zakres.

Dodatkowo w wielu przypadkach sensowne są metryki zasobów (CPU, pamięć, I/O) oraz prosty sygnał „częściowy sukces”, np. liczba odrzuconych rekordów. Skrypt, który kończy się kodem 0, ale przetwarza tylko połowę plików z powodu zmiany formatu, z perspektywy biznesu jest realną awarią, mimo że technicznie „się wykonał”.

Jak odróżnić poprawne wykonanie skryptu od cichej awarii biznesowej?

Zamiast patrzeć tylko na exit code, trzeba monitorować wynik biznesowy. Dla importu danych będzie to liczba nowych rekordów i liczba błędów parsowania; dla generowania raportu – liczba wierszy w raporcie i zakres dat; dla integracji – liczba przesłanych i zaakceptowanych komunikatów.

Typowy błąd to traktowanie „exit 0” jako dowodu sukcesu. W praktyce skrypt może przejść bez wyjątku, ale nie przetworzyć nic – np. z powodu pustego katalogu lub nowego formatu pliku. Prosty warunek: jeśli metryka biznesowa jest podejrzanie niska albo równa zero w stosunku do historii, alert powinien się uruchomić nawet przy poprawnym kodzie wyjścia.

Czy ręczne sprawdzanie raportów i plików ma jeszcze sens przy dobrym monitoringu?

Ręczne sprawdzanie wyniku (czy raport doszedł, czy plik się pojawił) bywa przydatne na bardzo wczesnym etapie projektu lub przy jednorazowych zadaniach. W stałej produkcji szybko zamienia się w pracę strażnika, który sam w sobie jest „systemem monitoringu” – podatnym na urlopy, zmęczenie i przeoczenia.

Rozsądny kompromis to: automatyczny monitoring jako podstawa, a ręczne sanity checki tylko w okresach podwyższonego ryzyka (np. zaraz po dużej zmianie, migracji formatu pliku, przełączeniu na nowego dostawcę danych). Jeżeli ręczny check jest codzienny i krytyczny, to sygnał, że powinien zostać zautomatyzowany i włączony w metryki oraz alerty.

Co warto zapamiętać

  • Największe ryzyko niosą „małe, jednorazowe” skrypty, które po cichu stają się kluczową integracją biznesową, ale nigdy nie przeszły normalnego cyklu wytwórczego ani nie dostały wymagań dotyczących obserwowalności.
  • Problemem nie jest złożoność skryptu, tylko jego niewidzialność: brak go na dashboardach, poza standardowym monitoringiem i procesem on-call sprawia, że awarie wychodzą na jaw dopiero wtedy, gdy biznes odczuwa skutki.
  • Ręczne „odhaczanie”, czy raport się pojawił lub dane się załadowały, działa tylko do pierwszego urlopu lub przeładowania obowiązkami; dodatkowo reaguje dopiero na skutki, a nie na moment wykolejenia się skryptu.
  • Automatyczne czujniki (logi, metryki, alerty) umożliwiają wychwycenie problemów na poziomie czasu trwania joba, wolumenu danych czy nietypowych błędów, zanim brak danych zablokuje kolejne systemy lub procesy biznesowe.
  • Skrypty bez obserwowalności ukrywają się w wielu miejscach: od pojedynczych crontabów na „narzędziowym” serwerze, przez pipeline’y CI/CD, po funkcje serverless, które często raportują tylko błędy techniczne, a pomijają ciche błędy biznesowe.
  • Brak monitoringu prowadzi do cichych zatrzymań, powolnej degradacji danych i kaskadowych awarii, a bez logów i metryk trudno nawet ustalić, od kiedy problem istnieje i co było jego faktyczną przyczyną.
  • Opracowano na podstawie

  • Site Reliability Engineering: How Google Runs Production Systems. O'Reilly Media (2016) – Praktyki SRE, monitoring, alerting, SLO, incydenty produkcyjne
  • Seeking SRE: Conversations About Running Production Systems at Scale. O'Reilly Media (2018) – Eseje o praktykach operacyjnych, on-call, observability i kulturze SRE
  • Google Cloud Architecture Framework: Operations Excellence. Google Cloud – Zalecenia dot. monitoringu, logów, metryk i zarządzania incydentami
  • AWS Well-Architected Framework – Operational Excellence Pillar. Amazon Web Services – Wytyczne AWS dla monitoringu, automatyzacji i obsługi zadań produkcyjnych