Monitoring usług i infrastruktury wymaga mechanizmu, który nie tylko zbiera dane z wielu źródeł, ale też potrafi je skutecznie przechowywać, przetwarzać, wizualizować i uruchamiać na ich podstawie alarmy. Prometheus stał się standardem de facto w tym obszarze, bo łączy prostotę modelu działania z dużą wydajnością i elastycznością integracji. Poniżej znajdziesz dogłębną, praktyczną opowieść o tym, jak działa ten system: od architektury, przez pozyskiwanie danych, po reguły, alerty, skalowanie i dobre praktyki, które ułatwią codzienną pracę zespołów inżynierskich.
Fundamenty architektury Prometheus
W centrum rozwiązania stoi proces Prometheus, który działa jako samodzielny serwer. Jego zadania to okresowe odpytywanie źródeł danych, parsowanie ekspozycji, przypisywanie próbek do odpowiednich szeregów czasowych, składowanie ich w lokalnej bazie oraz udostępnianie interfejsu API do zapytań i reguł. Prometheus pełni więc rolę zarówno kolektora, jak i silnika analitycznego.
Model danych opiera się o szeregi czasowe. Każdy szereg identyfikowany jest przez nazwę oraz zestaw par klucz–wartość zwanych etykiety. Dzięki etykietom jedna miara może mieć wiele wymiarów (np. instancja, strefa, wersja aplikacji, ścieżka żądania). Wartości to liczby zmiennoprzecinkowe, a znacznik czasu reprezentuje moment pobrania próbki. Z perspektywy użytkownika takie podejście daje ogromną swobodę filtrowania, agregacji i porównywania danych, ale wymaga świadomego projektowania wymiarów.
Prometheus komunikuje się przez HTTP. Wystawia własny interfejs do zadawania zapytań, inspekcji zdrowia oraz pobiera dane z końcówek wystawiających metryki w ustalonym formacie. Nie potrzebuje zewnętrznej bazy SQL czy brokerów komunikatów — całą logikę ma w jednym procesie i własnym formacie magazynu.
Ważnym założeniem jest izolacja od miejsca, w którym uruchomione są badane usługi. Prometheus nie musi być współlokowany z aplikacjami; może znajdować się w innym segmencie sieci, a gdy potrzeba — działa w trybie wysokiej dostępności w parach lub z rozwiązaniami warstw wyższych, które agregują wiele instancji.
Model pozyskiwania danych i ekspozycja metryk
Prometheus preferuje model „pull”: samodzielnie odpyta cele monitoringu w regularnych odstępach, pobierając strony HTTP z danymi pomiarowymi. Taki model upraszcza kontrolę nad harmonogramem, timeoutami, wersjonowaniem i bezpieczeństwem, a także redukuje ryzyko przeciążenia procesów po stronie monitorowanych usług. Alternatywnie dostępny jest most push (gateway), używany głównie w wyjątkowych scenariuszach (np. krótkotrwałe joby), ale to nie on stanowi standardowy mechanizm.
Aplikacje mogą wystawiać własne metryki wprost dzięki bibliotekom klienckim dla popularnych języków (Go, Java, Python, Ruby, .NET, Rust i inne). Tam, gdzie nie mamy kodu aplikacji lub nie chcemy go modyfikować, z pomocą przychodzą eksportery — procesy pośredniczące, które pobierają dane z systemów zewnętrznych i wystawiają je w formacie akceptowanym przez Prometheus (np. Node Exporter dla systemu operacyjnego, Blackbox Exporter do sprawdzania punktów HTTP/TCP/ICMP, czy eksportery dedykowane dla baz danych, kolejek i urządzeń sieciowych).
Format danych jest prosty tekstowo. Każda próbka zawiera nazwę serii, opcjonalne etykiety oraz wartość. Dodatkowo Prometheus rozpoznaje cztery główne typy metryk: counter (licznik rosnący), gauge (bieżąca wartość, rośnie i maleje), histogram i summary. Histograms i summaries służą do badania rozkładów (np. czasów odpowiedzi), jednak ich semantyka i koszty różnią się. Histogramy generują kubełki (buckets) z liczbami zliczeń i sumą, summaries wyliczają percentyle po stronie procesu. W praktyce najczęściej stosuje się histogramy, bo dobrze współpracują z zapytaniami o stopy zmian i percentyle liczone po stronie Prometheus.
Proces pobierania danych — scraping — odbywa się według harmonogramu zdefiniowanego w konfiguracji. Każdy „job” może mieć własny interwał, limit czasu, nagłówki, TLS, a także relabeling dla porządkowania etykiet. Ważne jest, by tak dobrać częstotliwość, aby uchwycić dynamikę obserwowanych zjawisk i jednocześnie nie przeciążyć ani monitorowanych usług, ani samego serwera Prometheus.
Odkrywanie usług i konfiguracja zadań
Prometheus musi wiedzieć, które cele (targets) odpytywać. Może to być lista statyczna adresów, ale w nowoczesnych środowiskach stosuje się automatyczne odkrywanie usług. System oferuje bogaty zestaw mechanizmów discovery: Kubernetes, Consul, EC2, Azure, GCE, DNS, pliki, Marathon i inne. Dzięki temu nie trzeba ręcznie aktualizować konfiguracji po każdej zmianie skali klastra.
W procesie odkrywania powstają etykiety meta, które następnie podlegają regułom relabelingu. Relabeling służy do przepisywania, kopiowania, łączenia, usuwania etykiet, filtrowania celów oraz kształtowania końcowego zestawu etykiet przypisywanych do próbek. To potężne narzędzie, które pozwala budować spójne nazewnictwo i odrzucać dane o niskiej jakości, zanim trafią do magazynu.
Kluczowe parametry konfiguracyjne obejmują m.in. częstotliwość scrape’ów, limit czasu, limity próbek na jeden scraping, a także nagłówki i metody uwierzytelniania (basic auth, bearer token, TLS). Dobrą praktyką jest zróżnicowanie ustawień per job: inne dla metryk infrastrukturalnych, inne dla aplikacyjnych, jeszcze inne dla zewnętrznych endpointów SLA.
W środowisku Kubernetes powszechnie używa się operatora, który upraszcza definicję celów poprzez obiekty CRD (ServiceMonitor, PodMonitor). Takie podejście spina deklaratywny model klastra z konfiguracją Prometheus: dodanie adnotacji lub etykiety do usługi automatycznie powoduje objęcie jej monitoringiem.
Jeśli monitorujemy wiele stref czy regionów, warto rozdzielić joby, aby unikać problemów z latencją sieciową. Z kolei dla środowisk on-prem przydaje się discovery oparte o serwery DHCP/DNS lub rejestry CMDB, które mogą generować pliki w formacie file_sd.
Magazyn danych TSDB, spójność i retencja
Sercem przechowywania danych jest wbudowana baza TSDB (time series database). W przeciwieństwie do ogólnego silnika klucz–wartość, TSDB w Prometheus jest zoptymalizowana pod zapisy próbek w czasie oraz szybkie skany po wybranych etykietach. Dane napływają do pamięci (head), a także do dziennika write-ahead (WAL), który zabezpiecza przed utratą danych w razie awarii.
WAL rejestruje kolejne próbki i mutacje. W tle działają procesy kompaktujące — z pamięci tworzone są bloki na dysku (zwykle segmenty dwugodzinne). Każdy blok posiada pliki zawierające serię, indeks etykiet i próbki. Kompakcja scala bloki w większe oraz usuwa serie oznaczone jako usunięte (tombstones). Taki mechanizm łączy wysoką wydajność zapisu z rozsądnym kosztem odczytu.
Retencja kontroluje, jak długo dane są trzymane. Można zdefiniować limit czasowy (np. 15, 30, 90 dni) lub rozmiarowy. Jeżeli potrzebujesz wieloletniej historii, zwykle stosuje się mechanizmy zewnętrzne i integracje warstwy analitycznej, natomiast lokalny TSDB przechowuje okres operacyjny do szybkich zapytań i alertów.
Ważnym aspektem jest spójność metadanych serii. Każda unikatowa kombinacja nazwy i etykiet to nowa seria. Zmiana wartości etykiety powoduje powstanie nowej serii, co wpływa na zużycie pamięci i dysku. Dlatego projektowanie metryk musi uwzględniać redukcję „eksplozji serii”. Nadmierna zmienność etykiet (np. identyfikatory żądań, losowe wartości, parametry w ścieżkach) jest źródłem problemów ze skalą i stabilnością.
Prometheus radzi sobie ze znikającymi seriami poprzez mechanizm „staleness”: gdy cel przestaje zwracać daną serię, Prometheus zaznacza ją jako nieaktualną. Zapobiega to błędnym wnioskom podczas obliczeń agregujących i umożliwia rozpoznawanie braków danych (np. z użyciem funkcji absent).
Gdy wymagane jest wysyłanie danych do zewnętrznego, skalowalnego zaplecza, włącza się remote write. Prometheus potrafi strumieniować próbki do systemów budowanych do długotrwałego przechowywania i globalnych zapytań. W drugą stronę działa remote read, który pozwala wykonywać zapytania na danych trzymanych poza lokalnym dyskiem.
Język zapytań PromQL i analityka
Do analizy danych służy PromQL. To język mapujący się bezpośrednio na model szeregów czasowych, w którym selektory filtrują serie po nazwie i etykietach, a operatory i funkcje przekształcają je w wyniki. Istotne jest rozróżnienie wektorów chwilowych (instant vector) i zakresowych (range vector). Te drugie wskazują przedział czasu (np. [5m]), co pozwala obliczać tempo zmian i funkcje okienne.
Najczęściej używane operacje obejmują:
- rate, irate, increase — tempo zmian liczników, używane do metryk żądań, błędów, bajtów; to fundament SLO i obliczeń przepływów;
- sum, avg, min, max, count, count_values, stddev — agregacje po grupach (by/without), w tym topk i bottomk do identyfikacji elementów odstających;
- predict_linear, deriv, delta — przewidywanie trendu i różnice w czasie;
- avg_over_time, max_over_time, quantile_over_time — statystyki okienne dla wskaźników bieżących;
- absent, absent_over_time — wykrywanie braków danych w danym wymiarze.
Operatory binarne pozwalają łączyć różne zbiory serii z kontrolą dopasowania po etykietach (on/ignoring, group_left/group_right). To ważne, gdy porównujemy np. dwie definicje agregacji lub chcemy wzbogacić dane jednym wymiarem.
Sfera opóźnień i czasów odpowiedzi wymaga pracy na rozkładach. W modelu Prometheus świetnie nadają się do tego histogramy. Aplikacja wystawia kubełki (buckets) z akumulacją zliczeń i sumą wartości, a po stronie zapytań oblicza się percentyle, zwykle z użyciem histogram_quantile na tempie zmian kubełków. Zapewnia to wiarygodne P90, P95, P99 przy zachowaniu stabilności i możliwości agregacji. W nowszych wydaniach pojawiają się natywne histogramy, które kompresują zakresy, zmniejszając narzut pamięciowy i umożliwiając precyzyjniejsze obliczenia dla szerokich rozkładów.
Do pracy z etykietami służą funkcje label_replace i label_join, a także operatory regex w selektorach. Pozwalają one kształtować wymiarowanie bez zmiany źródła metryk. Warto jednak nie nadużywać złożonych wyrażeń, bo mogą obciążać silnik.
W kontekście śledzenia zdarzeń między usługami Prometheus potrafi przechowywać „exemplars” — odnośniki do pojedynczych próbek (np. identyfikatora śladu w systemie tracingu). Dzięki temu można „przeklikać się” z metryki do konkretnego śladu w systemach typu Jaeger czy Tempo, łącząc metryki z diagnostyką na poziomie żądania.
Warte uwagi są także techniki antywzorców. Nadmiernie długie zapytania, szerokie regexy bez ograniczeń czy joiny na ogromnych zbiorach potrafią doprowadzić do wyczerpywania limitów. Parametry bezpieczeństwa zapytań (limity próbek, czas wykonania) należy dobrać w zależności od środowiska i edukować użytkowników, jak budować zapytania kosztowo efektywne.
Reguły, alerty i Alertmanager
Prometheus wspiera reguły obliczeniowe i alertowe. Reguły obliczeniowe generują nowe serie z wynikami kosztownych lub często używanych zapytań — to tzw. recording rules. Dzięki nim odciążamy silnik w godzinach szczytu i zapewniamy stabilną semantykę kluczowych wskaźników (np. poziomy SLO czy długoterminowe średnie). Reguły grupuje się w plikach, a Prometheus ocenia je w cyklicznych odstępach. Błędy w regułach lub zbyt ambitne interwały potrafią zwiększyć obciążenie, dlatego warto wersjonować i testować je na środowiskach pre-produkcyjnych.
Reguły alertowe definiują warunki wysyłania alarmów wraz z czasem trwania (for), aby uniknąć fluktuacji i flappingu. W praktyce oznacza to: najpierw warunek musi utrzymać się np. 5 minut, dopiero wtedy alert przechodzi do stanu aktywnego. Alerty mają etykiety i opisy, które przenoszą kontekst do systemu dystrybucji powiadomień.
Sam Prometheus nie wysyła wiadomości. Robi to dedykowany komponent Alertmanager. Jego rola to deduplikacja, grupowanie, routowanie i tłumienie alertów. Konfiguracja Alertmanagera pozwala:
- tworzyć drzewo trasowania (routing tree) oparte o etykiety alertów;
- definiować zasady grupowania (group_by) i parametry czasowe (group_wait, group_interval, repeat_interval);
- ustawiać reguły inhibicji — jeśli trwa poważny incydent rdzeniowy, alerty o mniej istotnych objawach mogą być wyciszane;
- wprowadzać cisze (silences) na czas planowanych prac lub w celu opanowania „burzy alertów”;
- integrować powiadomienia z e-mail, Slack, PagerDuty, webhookami i innymi kanałami.
W praktyce niezwykle ważne jest nadawanie priorytetów i pisanie czytelnych adnotacji. Opis, etykiety źródłowe, link do dashboardu i instrukcje runbooku skracają MTTR. Ponadto zespoły powinny cyklicznie przeglądać statystyki alertów, eliminując powtarzalny hałas oraz urealniając progi.
Skalowanie, HA, federacja i długoterminowe przechowywanie
Prometheus projektowano jako pojedynczy, autonomiczny proces, ale praktyka wymaga zarówno wysokiej dostępności, jak i szerokiej skali. Wysoką dostępność realizuje się przez uruchomienie dwóch (lub więcej) identycznych instancji skrobiących te same cele. Każda posiada własny lokalny stan i niezależnie ocenia reguły. Alertmanager deduplikuje powiadomienia z wielu replik dzięki etykietom zewnętrznym.
Skalowanie poziome można uzyskać na kilka sposobów:
- sharding po celach — różne instancje Prometheus obsługują różne zbiory jobów lub przestrzenie nazw;
- federacyjny model agregacji — instancje niższego poziomu zbierają dane lokalnie, a instancja wyższego poziomu okresowo odpyta je o zagregowane rezultaty;
- remote write do zaplecza horyzontalnie skalowalnego z warstwą zapytań umożliwiającą globalny widok i długi okres retencji.
Federacja to prosty sposób budowania hierarchii: lokalne instancje odpowiadają za szczegół, instancja centralna za syntetyczne wskaźniki. Taki układ minimalizuje ruch sieciowy i pozwala podejmować decyzje blisko źródła. Warto też oznaczać metryki etykietami regionu, klastra, strefy. W tekstach i konfiguracjach często pada słowo federacja — to właśnie ta technika hierarchicznego łączenia instalacji.
Gdy potrzeba globalnych zapytań ad-hoc, retencji wieloletniej i niezależności od pojedynczych serwerów, stosuje się systemy warstwy analitycznej, które integrują się przez remote write/read oraz stosują własne mechanizmy składowania, indeksowania i pamięci podręcznych. Te systemy oferują rozproszone zapytania, downsampling, replikację między regionami, a także narzędzia do kontroli kosztów.
Wybór strategii skalowania zależy od profilu danych: liczby serii, tempa nowych serii, tempa próbkowania, różnorodności etykiet i wymagań zapytań. Arbitralne zwiększanie scrape interval bez kontroli jakości zwykle kończy się utratą wglądu w zjawiska szybkozmienne, podczas gdy zbyt agresywne skracanie interwałów powoduje nadmierne koszty i kłopoty z kompakcją.
Praktyki wdrożeniowe, Kubernetes, bezpieczeństwo i optymalizacja
W Kubernetes standardem jest użycie operatora do instalacji Prometheus i Alertmanager wraz z CRD, które prowadzą konfigurację w modelu deklaratywnym. Dzięki temu reguły, joby i cele można wersjonować w repozytoriach, poddawać przeglądom i testować tak, jak kod aplikacji. Nadzór nad polityką nazw i etykiet pełni często platform team, który ustala konwencje: prefiksy, schematy i zalecane zestawy etykiet dla poszczególnych domen (aplikacje, bazy, kolejki, bramy, sieć).
Bezpieczeństwo obejmuje kilka warstw:
- kontrola sieci (NetworkPolicies, ACL) — ograniczenie, skąd Prometheus może skrobać metryki i dokąd wysyłać remote write;
- szyfrowanie i uwierzytelnianie — TLS/mTLS do celów, ochrona interfejsu HTTP Prometheus, autoryzacja do paneli;
- higiena relabelingu — blokowanie prywatnych danych w etykietach i redukcja nadmiarowych wymiarów;
- limity wykonywania zapytań i izolacja przestrzeni (np. osobne instancje dla zespołów lub przestrzeni nazw).
W kwestii jakości danych kluczowa jest kardynalność, czyli liczba unikalnych kombinacji etykiet. Jej niekontrolowany wzrost jest jednym z najczęstszych źródeł problemów. Najbardziej kłopotliwe są etykiety o wysokiej zmienności: identyfikatory żądań, użytkowników, losowe tokeny, pełne ścieżki z parametrów. Zamiast tego stosuje się ograniczone słowniki (np. skategoryzowane nazwy tras), a szczegół pojedynczych zdarzeń przenosi się do logów lub systemów tracingu. Nie umieszczaj danych wrażliwych i identyfikatorów osobowych w etykietach metryk — to grozi zarówno wyciekiem, jak i eksplozją liczby serii.
Wydajność i koszty utrzymuje się poprzez:
- sensowne interwały scrape: krótkie dla szybkich zjawisk (np. 5–15 s), dłuższe dla powolnych;
- stosowanie recording rules dla skomplikowanych, często używanych wskaźników;
- pruning etykiet i użycie metrics_relabel_configs do odrzucania niepotrzebnych serii przy wlocie;
- ustawienie limitów: maksymalna liczba serii, próbek na scrape, limity zapytań;
- odseparowanie jobów obciążających do dedykowanych instancji Prometheus;
- kontrolę wersji eksportowanych metryk — zmiany wprowadzaj ewolucyjnie i dokumentuj deprecjacje.
W operacjach dziennych nie zapominaj o samoobserwacji Prometheus. Sam wystawia bogaty zestaw metryk własnych (prefiksy prometheus_ i tsdb_), które pozwalają zobaczyć tempo przyrostu serii, czas trwania kompakcji, rozmiary bloków, wykorzystanie pamięci oraz koszty zapytań. To one podpowiadają, kiedy pora na sharding, korekty interwałów lub refaktoryzację reguł.
Przemyślana strategia retencji i harmonogramów backupu jest równie ważna. Prometheus udostępnia snapshoty, które można przesłać do zewnętrznej przestrzeni, ale przy bardzo dużej skali i długiej retencji zwykle lepiej polegać na systemach rozproszonych zaprojektowanych do trwałej archiwizacji i globalnych zapytań.
Strategie projektowania metryk, SLO i wzorce operacyjne
Dobry system monitoringu zaczyna się od właściwego modelu metryk. Dla aplikacji serwujących ruch HTTP warto wyznaczyć trzy klasy: wolumen (żądania/s), jakość (odsetek błędów 5xx/4xx lub specyficznych kodów) i opóźnienia (percentyle czasów odpowiedzi). Ten „złoty sygnał” to fundament, nad którym buduje się SLI, SLO i budżety błędów. Zestaw ustandaryzowanych metryk ułatwia skalowanie zespołów i utrzymanie spójnych dashboardów.
Praktyczny wzorzec to obliczanie błędów w ruchu w oparciu o liczniki z podziałem na kody statusu. Wówczas definiujemy agregacje po wymiarach istotnych biznesowo (np. usługa, endpoint kategoryzowany, region) i stosujemy funkcje rate/increase dla wybranych okien czasowych. Dla SLO często używa się wielookienkowych zapytań „burn rate”, łączących krótki i długi horyzont, aby łapać zarówno nagłe skoki, jak i powolne dryfy.
W dziedzinie opóźnień metryki histogramowe należy projektować z głową: dobrać granice kubełków tak, by odzwierciedlały oczekiwane klasy opóźnień. Zbyt wąski zakres zawęzi wgląd, zbyt szeroki utrudni uzyskanie precyzyjnych percentyli. Natywne histogramy ułatwiają tę sztukę, ale wciąż warto zacząć od podstaw: rozsądna liczba kubełków, spójna między usługami.
W obszarze zarządzania konfiguracją wdrożeniową warto:
- używać rozsądnych nazw jobów i etykiet, zgodnych z konwencjami zespołu;
- zapewnić przejrzystą mapę odpowiedzialności — kto utrzymuje reguły, dashboardy, alarmy;
- prowadzić przeglądy zmian w rekordach i alertach z udziałem zainteresowanych zespołów;
- udokumentować standardy metryczne: nazewnictwo, typy, zestawy minimalne i rozszerzone.
Wreszcie, przy incydentach operacyjnych niezwykle pomocne jest połączenie metryk z logami i tracingiem. Metryki wskażą, że coś jest nie tak i od kiedy, ale to ślady i logi pozwolą dojść do sedna. Exemplars potrafią zredukować przeskok poznawczy: z P99 opóźnień klikasz do konkretnego śladu requestu w czasie, co skraca dochodzenie.
Podsumowując, sukces Prometheus bierze się z harmonii pomiędzy prostotą i wydajnością: klarowny model serii czasowych, czytelny język zapytań, wydajny lokalny magazyn i potężny ekosystem integracji. Aby w pełni wykorzystać jego potencjał, należy świadomie projektować metryki, kontrolować wymiarowanie etykiet, stosować reguły i alerty z umiarem oraz wdrażać strategie skalowania na miarę potrzeb. Dzięki temu Prometheus staje się nie tylko narzędziem monitoringu, ale fundamentem inżynierii niezawodności systemów.