commit
This commit is contained in:
386
MONITORING.md
Normal file
386
MONITORING.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# 📊 Monitoring a observabilita
|
||||
|
||||
## OpenMetrics standard
|
||||
|
||||
OpenMetrics (CNCF sandbox) je de-facto standard pro expozici metrik v cloud-native prostředí:
|
||||
|
||||
- Podpora text representation i Protocol Buffers
|
||||
- Základ pro Prometheus exposition format
|
||||
- Specifikuje: counter, gauge, histogram, summary, gaugehistogram, statefulset
|
||||
- `_total` suffix pro kumulativní hodnoty, `_bucket` pro histogramy
|
||||
- Metadata: HELP, TYPE, UNIT, (časové razítko volitelné)
|
||||
|
||||
Standard se vyvíjí v rámci [OpenObservability](https://github.com/OpenObservability/OpenMetrics).
|
||||
|
||||
## Nové nástroje a trendy (2024–2026)
|
||||
|
||||
| Nástroj | Popis |
|
||||
|---------|-------|
|
||||
| **Grafana Sigil** | AI observability pro LLM agenty (OTel-native) |
|
||||
| **InfraLens** | eBPF-based, zero-instrumentation network observability |
|
||||
| **Ingero** | GPU causal observability (eBPF, CUDA tracing) |
|
||||
| **GreptimeDB** | Unified observability DB — nahrazuje Prometheus + Loki + ES |
|
||||
| **Netdata** | AI-powered full-stack monitoring, 800+ integrations, edge ML |
|
||||
|
||||
## Tři pilíře observability
|
||||
|
||||
1. **Logs** — nestrukturovaná data o událostech (ERROR, WARN, INFO)
|
||||
2. **Metrics** — číselná data v čase (latence, chybovost, vytížení CPU)
|
||||
3. **Traces** — sledování požadavku napříč službami (distributed tracing)
|
||||
|
||||
## SLI / SLO / SLA
|
||||
|
||||
| Termín | Význam | Příklad |
|
||||
|--------|--------|---------|
|
||||
| **SLI** (Service Level Indicator) | Naměřená metrika | Latence p99 = 250ms |
|
||||
| **SLO** (Service Level Objective) | Cílová hodnota | 99.9 % requestů < 300ms |
|
||||
| **SLA** (Service Level Agreement) | Právní závazek | 99.95 % uptime |
|
||||
|
||||
### Error budget
|
||||
|
||||
`Error Budget = 100 % - SLO`
|
||||
- Pokud je SLO 99.9 %, error budget je 0.1 % času
|
||||
- Dokud error budget zbývá, tým může deployovat nové featury
|
||||
- Po vyčerpání — freeze na deploye, priorita je stabilita
|
||||
|
||||
## Pyramid of metrics — RED vs USE vs 4 Golden Signals
|
||||
|
||||
### 4 Golden Signals (Google SRE)
|
||||
|
||||
1. **Latency** — čas zpracování requestu (rozlišovat success vs error latenci)
|
||||
2. **Traffic** — počet requestů / propustnost (RPS, QPS, throughput)
|
||||
3. **Errors** — explicitní chyby (5xx, 4xx) i implicitní (success s chybným výsledkem)
|
||||
4. **Saturation** — jak je služba "plná" (CPU, memory, queue depth, connection pool)
|
||||
|
||||
### USE (pro infrastrukturu)
|
||||
- **U**tilization — jak je resource vytížená (% času je aktivní)
|
||||
- **S**aturation — kolik čeká ve frontě (run queue, I/O wait)
|
||||
- **E**rrors — chyby (dropped packets, disk errors, OOM)
|
||||
|
||||
### RED (pro služby)
|
||||
- **R**ate — počet requestů za sekundu
|
||||
- **E**rrors — počet chybných requestů
|
||||
- **D**uration — latence (distribuce, percentily)
|
||||
|
||||
| Metodologie | Zaměření | Typické metriky |
|
||||
|------------|----------|----------------|
|
||||
| **4 Golden Signals** | Služby + infrastruktura | Latence, RPS, errors, saturation |
|
||||
| **USE** | Infrastruktura | CPU util, I/O saturace, disk errors |
|
||||
| **RED** | Microservices | RPS, error rate, p50/p95/p99 latence |
|
||||
|
||||
## PromQL příklady
|
||||
|
||||
| Výraz | Popis |
|
||||
|-------|-------|
|
||||
| `rate(http_requests_total[5m])` | Počet requestů za sekundu (průměr za 5 min) |
|
||||
| `increase(http_requests_total[1h])` | Celkový nárůst za 1 hodinu |
|
||||
| `sum by (status) (rate(http_requests_total[5m]))` | Requesty agregované podle status kódu |
|
||||
| `histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))` | p99 latence |
|
||||
| `avg_over_time(cpu_usage[1h])` | Průměrné CPU vytížení za hodinu |
|
||||
| `topk(5, sum(rate(http_requests_total[5m])) by (service))` | Top 5 služeb podle RPS |
|
||||
| `max_over_time(memory_usage[24h])` | Maximální memory usage za 24h |
|
||||
| `rate(node_network_drop_total[5m]) > 0` | Sítě s dropped pakety |
|
||||
| `(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])))` | CPU utilization (1 - idle) |
|
||||
| `delta(http_request_duration_seconds_sum[5m]) / delta(http_request_duration_seconds_count[5m])` | Průměrná latence |
|
||||
| `absent(metric)` | Alert když metrika chybí |
|
||||
|
||||
## Recording rules
|
||||
|
||||
Pre-agregace často používaných PromQL dotazů pro snížení zátěže při dotazování.
|
||||
|
||||
### Kdy použít
|
||||
- Složité dotazy používané na více dashboardech
|
||||
- Dotazy nad surovými daty s vysokým kardinality
|
||||
- Často dotazované agregace (např. p99 latence za poslední měsíc)
|
||||
|
||||
### Příklad
|
||||
|
||||
```yaml
|
||||
groups:
|
||||
- name: service_rules
|
||||
interval: 1m
|
||||
rules:
|
||||
- record: job:http_requests:rate5m
|
||||
expr: sum(rate(http_requests_total[5m])) by (job)
|
||||
- record: instance:cpu:utilization
|
||||
expr: (1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance))
|
||||
- record: service:http_latency:p99
|
||||
expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))
|
||||
```
|
||||
|
||||
- **record** — název nové metriky (konvence: `level:metric:aggregation`)
|
||||
- **interval** — jak často se pravidlo vyhodnocuje (typicky 1-5 min)
|
||||
|
||||
## Metriky — nástroje
|
||||
|
||||
### Metrics
|
||||
| Nástroj | Popis |
|
||||
|---------|-------|
|
||||
| Prometheus | Pull-based, time-series DB, silný query language (PromQL) |
|
||||
| Grafana | Vizualizace, dashboardy, alerting |
|
||||
| Datadog | SaaS, APM, logs, metrics v jednom |
|
||||
| New Relic | APM, browser monitoring |
|
||||
| CloudWatch | AWS nativní |
|
||||
| Azure Monitor | Azure nativní |
|
||||
| Google Cloud Ops | GCP nativní |
|
||||
|
||||
### Logging
|
||||
| Nástroj | Popis |
|
||||
|---------|-------|
|
||||
| ELK Stack | Elasticsearch, Logstash, Kibana |
|
||||
| Loki | Grafana Loki — lightweight, Prometheus-like |
|
||||
| Splunk | Enterprise log management |
|
||||
| Fluentd / Fluent Bit | Log collector a forwarder |
|
||||
| Vector | High-performance log/metric collector |
|
||||
|
||||
### Tracing
|
||||
| Nástroj | Popis |
|
||||
|---------|-------|
|
||||
| Jaeger | Open-source distributed tracing |
|
||||
| Zipkin | Open-source distributed tracing |
|
||||
| OpenTelemetry | Standard pro instrumentaci (logs, metrics, traces) |
|
||||
| Datadog APM | SaaS tracing |
|
||||
| AWS X-Ray | AWS tracing |
|
||||
|
||||
## OpenTelemetry detail
|
||||
|
||||
### Span attributes
|
||||
|
||||
```yaml
|
||||
resource:
|
||||
attributes:
|
||||
- service.name: "payment-service"
|
||||
- service.version: "1.2.3"
|
||||
- deployment.environment: "production"
|
||||
scope:
|
||||
name: "io.opentelemetry.payment"
|
||||
spans:
|
||||
- name: "processPayment"
|
||||
kind: SPAN_KIND_INTERNAL
|
||||
attributes:
|
||||
- payment.method: "credit_card"
|
||||
- payment.amount: 2499
|
||||
- payment.currency: "CZK"
|
||||
events:
|
||||
- name: "authorization.complete"
|
||||
timestamp: 1717428000000000000
|
||||
```
|
||||
|
||||
### Context propagation (W3C TraceContext)
|
||||
|
||||
- **`traceparent`** — hlavička nesoucí trace-id, span-id, trace flags
|
||||
- Formát: `00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01`
|
||||
- Version (00) | Trace-ID (32 hex) | Span-ID (16 hex) | TraceFlags (01 = sampled)
|
||||
- **`tracestate`** — vendor-specific data, kompatibilní cross-provider
|
||||
- Propagace probíhá přes HTTP hlavičky, gRPC metadata, message queue properties
|
||||
|
||||
### Sampling
|
||||
|
||||
| Typ | Popis | Use case |
|
||||
|-----|-------|----------|
|
||||
| **Head-based** | Rozhodnutí o sample na začátku trace (na základě ID) | Jednoduchý, deterministický |
|
||||
| **Tail-based** | Rozhodnutí po dokončení trace (podle výsledku, latence) | Kvalitnější sample, komplexnější |
|
||||
|
||||
- Tail-based sampling: často používán pro kritické trace (5xx, p99+, slow traces)
|
||||
- Nástroje: Grafana Tempo (tail-based), Jaeger (head-based), OTel Collector (head + tail)
|
||||
|
||||
## Alerting
|
||||
|
||||
### Principy
|
||||
|
||||
- **Alert na symptom, ne na příčinu** — "500 errors" místo "high CPU"
|
||||
- **Reduce noise** — flapping alerts, alert fatigue
|
||||
- **Runbook pro každý alert** — co dělat když alert pípne
|
||||
- **Alert severity** — P0 (critical), P1 (high), P2 (medium), P3 (low)
|
||||
|
||||
### Alertmanager (Prometheus)
|
||||
|
||||
```yaml
|
||||
route:
|
||||
receiver: "team-pager"
|
||||
group_by: ["alertname", "cluster"]
|
||||
group_wait: 30s
|
||||
group_interval: 5m
|
||||
repeat_interval: 4h
|
||||
routes:
|
||||
- match:
|
||||
severity: critical
|
||||
receiver: "team-pager"
|
||||
repeat_interval: 1h
|
||||
- match:
|
||||
severity: warning
|
||||
receiver: "team-slack"
|
||||
|
||||
receivers:
|
||||
- name: "team-pager"
|
||||
pagerduty_configs:
|
||||
- routing_key: "<KEY>"
|
||||
severity: "{{ .CommonLabels.severity }}"
|
||||
- name: "team-slack"
|
||||
slack_configs:
|
||||
- channel: "#alerts"
|
||||
title: "{{ .GroupLabels.alertname }}"
|
||||
```
|
||||
|
||||
**Koncepty**:
|
||||
- **Grouping** — seskupování alertů podle labelů (snížení noise, např. všechny down instance v clusteru)
|
||||
- **Inhibition** — potlačení méně závažných alertů při existenci závažnějšího (např. nodedown inhibuje pod alerty)
|
||||
- **Silencing** — dočasné potlačení alertu (matching labels + duration)
|
||||
- **Routing tree** — hierarchické routování podle label match (severity, service, team)
|
||||
|
||||
### ESM (Event / Incident Management)
|
||||
|
||||
- PagerDuty, Opsgenie, OnCall (Grafana)
|
||||
- Escalation policies
|
||||
- On-call rotations
|
||||
|
||||
## Strukturované logování
|
||||
|
||||
```
|
||||
{
|
||||
"timestamp": "2026-06-03T10:30:00Z",
|
||||
"level": "ERROR",
|
||||
"service": "payment-service",
|
||||
"trace_id": "abc123",
|
||||
"user_id": "u456",
|
||||
"message": "Payment gateway timeout",
|
||||
"duration_ms": 1200,
|
||||
"error": {
|
||||
"type": "TimeoutError",
|
||||
"message": "Gateway did not respond in 1000ms"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Povinná pole strukturovaného logu
|
||||
|
||||
| Pole | Popis | Příklad |
|
||||
|------|-------|---------|
|
||||
| `timestamp` | ISO 8601 / RFC 3339 | `2026-06-03T10:30:00Z` |
|
||||
| `level` | Log level (RFC 5424) | `ERROR`, `WARN`, `INFO`, `DEBUG` |
|
||||
| `message` | Lidsky čitelná zpráva | `Payment processed` |
|
||||
| `service` | Název služby | `payment-service` |
|
||||
| `trace_id` | Korelace napříč službami | `abc123def456` |
|
||||
|
||||
### RFC 5424 log levels
|
||||
|
||||
| Číslo | Level | Použití |
|
||||
|-------|-------|---------|
|
||||
| 0 | EMERG | Systém nepoužitelný |
|
||||
| 1 | ALERT | Nutná okamžitá akce |
|
||||
| 2 | CRIT | Kritická chyba |
|
||||
| 3 | ERROR | Chyba (ne kritická) |
|
||||
| 4 | WARN | Varování |
|
||||
| 5 | NOTICE | Normální, ale důležitá událost |
|
||||
| 6 | INFO | Informační zpráva |
|
||||
| 7 | DEBUG | Ladění (vypnuto v produkci) |
|
||||
|
||||
### Correlation ID (traceparent)
|
||||
|
||||
- Generován při vstupu do systému (API gateway, frontend, message consumer)
|
||||
- Propagován v HTTP hlavičce `X-Correlation-ID` / `traceparent`
|
||||
- Umožňuje spojit logy napříč microservices (→ Grafana Explore, Kibana Discover)
|
||||
- Implementace: middleware v aplikaci, service mesh (Envoy), API gateway
|
||||
|
||||
## Distributed tracing detail
|
||||
|
||||
### Span kinds
|
||||
|
||||
| Kind | Popis | Příklad |
|
||||
|------|-------|---------|
|
||||
| **CLIENT** | Volání downstream služby (outbound) | HTTP klient volá API |
|
||||
| **SERVER** | Zpracování příchozího požadavku | HTTP handler |
|
||||
| **INTERNAL** | Lokální operace v rámci služby | Výpočet, transformace |
|
||||
| **PRODUCER** | Odeslání zprávy do fronty | Kafka producer |
|
||||
| **CONSUMER** | Příjem zprávy z fronty | Kafka consumer |
|
||||
|
||||
### Trace context chain
|
||||
|
||||
```
|
||||
Trace: abc123
|
||||
├── Span: /checkout (SERVER, root)
|
||||
│ ├── Span: validateCart (INTERNAL)
|
||||
│ ├── Span: POST /orders (CLIENT → payment-service)
|
||||
│ │ └── Span: /processPayment (SERVER)
|
||||
│ │ ├── Span: authorizeCard (INTERNAL)
|
||||
│ │ └── Span: chargeCard (CLIENT → bank-gateway)
|
||||
│ │ └── Span: /charge (SERVER, external)
|
||||
│ └── Span: sendConfirmation (PRODUCER → kafka)
|
||||
│ └── Span: consumeConfirmation (CONSUMER → email-service)
|
||||
```
|
||||
|
||||
- **W3C TraceContext** — standardizace cross-service tracing
|
||||
- **Baggage** — přenos kontextových dat (tenant, user role) mezi spans
|
||||
|
||||
## Grafana
|
||||
|
||||
### Provisioning dashboards as code
|
||||
|
||||
```yaml
|
||||
apiVersion: 1
|
||||
providers:
|
||||
- name: "default"
|
||||
orgId: 1
|
||||
folder: "Services"
|
||||
type: file
|
||||
options:
|
||||
path: /etc/grafana/provisioning/dashboards
|
||||
```
|
||||
|
||||
Dashboards JSON v gitu → CI/CD → automatický import do Grafany.
|
||||
|
||||
### Variables
|
||||
|
||||
- **Query variable** — dynamické hodnoty (např. seznam service names z PromQL: `label_values(up, service)`)
|
||||
- **Interval variable** — `$__auto_interval`, `$__interval` pro proměnlivý time range
|
||||
- **Custom variable** — ruční seznam hodnot (env: prod, staging, dev)
|
||||
- **Chained variable** — závislá proměnná (výběr namespace → zobrazí pody v namespace)
|
||||
|
||||
### Annotations
|
||||
|
||||
- Kreslení událostí do grafu (deploye, incidenty, config změny)
|
||||
- Zdroje: Prometheus alerty, Loki logy, GitHub Actions, custom API
|
||||
- Use case: "Deploy v 14:30 → spike v latenci v 14:31 → korelace"
|
||||
|
||||
## On-call best practices
|
||||
|
||||
### Escalation policies
|
||||
|
||||
```
|
||||
Level 1: Primární on-call (reakce do 5 min)
|
||||
└── timeout 15 min
|
||||
Level 2: Sekundární / senior engineer (reakce do 15 min)
|
||||
└── timeout 15 min
|
||||
Level 3: Engineering manager / incident commander
|
||||
```
|
||||
|
||||
### Incident severity matrix
|
||||
|
||||
| Severity | Popis | Reakce | Komunikace |
|
||||
|----------|-------|--------|------------|
|
||||
| **P0 (Critical)** | Služba kompletně nedostupná, data loss, security breach | Ihned, 24/7 | Status page + Stakeholder update |
|
||||
| **P1 (High)** | Major funkčnost degradovaná, část uživatelů postižena | Do 15 min | Slack channel + Tým lead |
|
||||
| **P2 (Medium)** | Non-critical funkce nefunguje, workaround existuje | Do 1 h | Slack channel |
|
||||
| **P3 (Low)** | Kosmetický problém, žádný dopad na uživatele | Next business day | Jira ticket |
|
||||
|
||||
### Postmortem
|
||||
|
||||
- **Blameless** — cílem je naučit se, ne obviňovat
|
||||
- **Struktura**: Timeline, detection, root cause, resolution, action items
|
||||
- **SRE princip**: každá incident → postmortem → systémové zlepšení
|
||||
- **Nástroje**: Jira, Incident.io, PagerDuty postmortem, Google Docs
|
||||
|
||||
## Logging patterns
|
||||
|
||||
### Best practices
|
||||
|
||||
- **Dashboard pro každou úroveň** — executive, service, troubleshooting
|
||||
- **Syntetické monitoring** — Heartbeat checky, browser tests (Playwright, Cypress)
|
||||
- **APM** — Application Performance Monitoring (databázové query, externí volání)
|
||||
- **Anomaly detection** — ML-based detekce outlierů
|
||||
- **Retention politika** — raw data krátce, agregace dlouhodobě
|
||||
- **Jednotný formát logů** — JSON, strukturovaná data
|
||||
|
||||
## Zdroje
|
||||
|
||||
Odkazy, knihy a standardy: [sources/monitoring/sources.md](sources/monitoring/sources.md)
|
||||
Reference in New Issue
Block a user