Modul 12 — Monitoring, logging a observabilita
58. Prometheus a Grafana pro monitoring
Jak Prometheus sbírá a ukládá metriky pull modelem, jazyk PromQL pro dotazování a Grafana jako vizualizační vrstva nad nimi.
Úvod a kontext
Minulá lekce představila metriky jako jeden ze tří pilířů
observability. Prometheus je dnes de facto standard pro sběr a
ukládání metrik v cloud-native prostředí (je jedním z prvních
projektů, které po Kubernetes získaly status "graduated" v nadaci
CNCF) a Grafana je nejrozšířenější nástroj pro jejich vizualizaci.
Tato dvojice tvoří páteř monitoringu ve většině moderních Kubernetes
nasazení — připomeňme, že jsme se s ní letmo setkali už v lekci o
ladění Kubernetes clusteru.
Teorie
Pull model sběru dat
Na rozdíl od řady starších monitorovacích nástrojů, které čekají, až
jim aplikace samy pošlou (push) data, Prometheus funguje obráceně:
sám se v pravidelném intervalu (scrape interval, typicky 15–30 s)
dotazuje nakonfigurovaných cílů na HTTP endpointu /metrics a stažené
hodnoty si uloží do vlastní časové databáze (TSDB). Aplikace jen musí
tento endpoint vystavit — knihovny (client libraries) pro Python, Go,
Java a další to zjednodušují na pár řádků kódu.
Formát metrik a typy
Endpoint /metrics vrací prostý text v definovaném formátu:
# HELP http_requests_total Celkový počet HTTP požadavků
# TYPE http_requests_total counter
http_requests_total{method="GET",status="200"} 15230
http_requests_total{method="GET",status="500"} 12
# HELP http_request_duration_seconds Doba zpracování požadavku
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.1"} 8500
http_request_duration_seconds_bucket{le="0.5"} 14800
http_request_duration_seconds_bucket{le="+Inf"} 15242
Základní typy metrik:
- Counter — hodnota, která jen roste (počet požadavků, počet
chyb) — nikdy neklesá, jen se může resetovat na 0 při restartu. - Gauge — hodnota, která může jít nahoru i dolů (aktuální počet
aktivních spojení, využití paměti). - Histogram — rozděluje pozorování do předem daných "košů"
(buckets), typicky pro měření latence — umožňuje spočítat percentily
(např. "95 % požadavků bylo rychlejších než X").
Popisky v {} (tzv. labels, např. method="GET") umožňují stejnou
metriku rozdělit podle libovolného rozměru — metody, stavového kódu,
endpointu — a filtrovat/agregovat podle nich při dotazování.
PromQL
PromQL je dotazovací jazyk Prometheu. Několik základních vzorů:
# aktuální hodnota metriky
http_requests_total
# filtr podle labelu
http_requests_total{status="500"}
# rate (počet za sekundu) za posledních 5 minut z counteru
rate(http_requests_total[5m])
# 95. percentil doby odezvy za posledních 5 minut
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# agregace přes všechny instance dané služby
sum(rate(http_requests_total{job="objednavky"}[5m])) by (status)
rate() je klíčová funkce — counter samotný jen roste, teprve rate()
z něj spočítá smysluplnou hodnotu "kolik za sekundu".
Grafana
Grafana se připojí k Prometheu (i dalším zdrojům dat) jako
datasource a nad daty staví dashboardy — sady panelů (grafy,
čísla, tabulky), z nichž každý má vlastní PromQL dotaz. Grafana také
umí vlastní alerting nad těmito dotazy, i když alerting samotného
Prometheu (přes komponentu Alertmanager) je běžnější volba pro
produkční nasazení (viz příští lekce).
Praktický příklad
Minimální konfigurace Prometheu, která sbírá metriky z vlastní
aplikace a z Kubernetes:
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "objednavky-servis"
static_configs:
- targets: ["objednavky-servis:8080"]
- job_name: "kubernetes-pods"
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
Druhý job využívá service discovery — Prometheus se sám dotáže
Kubernetes API na seznam podů a scrapuje jen ty, které mají anotaci
prometheus.io/scrape: "true", takže není nutné cíle ručně
udržovat při každém škálování.
Vystavení vlastní metriky v Pythonu pomocí knihovny
prometheus_client:
from prometheus_client import Counter, start_http_server
pocet_objednavek = Counter(
"objednavky_zpracovane_total", "Počet zpracovaných objednávek", ["stav"]
)
def zpracuj_objednavku(objednavka):
try:
# ... zpracování ...
pocet_objednavek.labels(stav="ok").inc()
except Exception:
pocet_objednavek.labels(stav="chyba").inc()
raise
start_http_server(8000) # vystaví /metrics na portu 8000
Shrnutí
Prometheus sbírá metriky pull modelem — sám scrapuje endpoint
/metrics cílových aplikací v pravidelném intervalu — a ukládá je do
vlastní časové databáze s podporou service discovery (např. pro
Kubernetes pody). PromQL umožňuje dotazovat, filtrovat podle labelů a
agregovat, s klíčovou funkcí rate() pro převod counterů na hodnoty
za sekundu. Grafana nad těmito daty staví přehledné dashboardy.
Kontrolní otázky
- Jaký je rozdíl mezi pull a push modelem sběru metrik a který z nich
používá Prometheus? - K čemu slouží funkce
rate()a proč ji potřebujeme u counterů? - Jaký je rozdíl mezi typy metrik counter, gauge a histogram?
- Mini cvičení: napište PromQL dotaz, který spočítá počet chybových
(status="500") požadavků za sekundu za posledních 5 minut pro
službujob="objednavky".
Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.