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.

Odhadovaná délka studia: 55 minut · Stav: nehotovo

Technologie: Prometheus/Grafana

Ú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

  1. Jaký je rozdíl mezi pull a push modelem sběru metrik a který z nich
    používá Prometheus?
  2. K čemu slouží funkce rate() a proč ji potřebujeme u counterů?
  3. Jaký je rozdíl mezi typy metrik counter, gauge a histogram?
  4. 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žbu job="objednavky".

Lekce na sebe nejsou zamčené — libovolnou lekci můžete otevřít i označit jako hotovou v jakémkoliv pořadí.