Monitoring i Observability - Pytania Rekrutacyjne i Kompletny Przewodnik 2026

Sławomir Plamowski 27 min czytania
devops elk grafana monitoring observability prometheus pytania-rekrutacyjne sre

"Jak monitorujesz swoje systemy w produkcji?" - to pytanie pada na każdej rozmowie DevOps i SRE. Monitoring i observability to fundament utrzymania niezawodnych systemów. Bez nich lecisz na ślepo - dowiesz się o problemach od użytkowników zamiast z alertów.

W tym przewodniku znajdziesz 50+ pytań rekrutacyjnych z odpowiedziami, od podstaw monitoringu po zaawansowane tematy jak distributed tracing, SLI/SLO i incident management.

Monitoring vs Observability - Podstawy

Odpowiedź w 30 sekund

"Monitoring to zbieranie predefiniowanych metryk i alertowanie na znane problemy - odpowiada 'co się zepsuło'. Observability to zdolność do debugowania nieznanych problemów na podstawie trzech filarów: logs, metrics i traces - odpowiada 'dlaczego się zepsuło'. W nowoczesnych systemach rozproszonych potrzebujesz obu."

Odpowiedź w 2 minuty

Tradycyjny monitoring działa dobrze dla monolitów - definiujesz metryki, ustawiasz progi, dostajesz alert. Ale w świecie mikroserwisów i Kubernetes problem może być w interakcji między serwisami, której nie przewidziałeś. Tu wchodzi observability.

┌─────────────────────────────────────────────────────────────────┐
│                  MONITORING vs OBSERVABILITY                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  MONITORING (Known Unknowns)                                   │
│  ┌─────────────────────────────────────────┐                   │
│  │  "CPU > 80%? → Alert!"                  │                   │
│  │  "Error rate > 1%? → Alert!"            │                   │
│  │  "Disk > 90%? → Alert!"                 │                   │
│  │                                          │                   │
│  │  ✓ Co się zepsuło                       │                   │
│  │  ✗ Dlaczego się zepsuło                 │                   │
│  └─────────────────────────────────────────┘                   │
│                                                                 │
│  OBSERVABILITY (Unknown Unknowns)                              │
│  ┌─────────────────────────────────────────┐                   │
│  │         METRICS                          │                   │
│  │    (What is happening?)                  │                   │
│  │            │                             │                   │
│  │            ▼                             │                   │
│  │  ┌─────────────────┐                    │                   │
│  │  │     LOGS        │◀── TRACES          │                   │
│  │  │ (Why it failed) │   (Where it failed)│                   │
│  │  └─────────────────┘                    │                   │
│  │                                          │                   │
│  │  ✓ Debug unknown problems               │                   │
│  │  ✓ Correlate across services            │                   │
│  └─────────────────────────────────────────┘                   │
└─────────────────────────────────────────────────────────────────┘

Trzy filary observability:

Filar Opis Narzędzia
Metrics Numeryczne pomiary agregowane w czasie Prometheus, InfluxDB, Datadog
Logs Rekordy zdarzeń z timestampem ELK, Loki, Splunk
Traces Ścieżka requestu przez system Jaeger, Zipkin, OpenTelemetry

Prometheus - Pytania Rekrutacyjne

1. Jak działa Prometheus i jaka jest jego architektura?

Słaba odpowiedź: "Prometheus zbiera metryki z aplikacji."

Mocna odpowiedź:

Prometheus to pull-based monitoring system - aktywnie pobiera metryki z endpointów, zamiast czekać aż aplikacje je wyślą.

┌─────────────────────────────────────────────────────────────────┐
│                  PROMETHEUS ARCHITECTURE                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────────────────────────────────────────┐          │
│  │              PROMETHEUS SERVER                    │          │
│  │  ┌────────────┐  ┌────────────┐  ┌────────────┐ │          │
│  │  │ Retrieval  │  │   TSDB     │  │ HTTP API   │ │          │
│  │  │ (scraper)  │  │ (storage)  │  │ (PromQL)   │ │          │
│  │  └─────┬──────┘  └────────────┘  └─────┬──────┘ │          │
│  └────────┼─────────────────────────────────┼───────┘          │
│           │                                 │                   │
│    ┌──────▼──────┐                   ┌──────▼──────┐           │
│    │   Targets   │                   │   Grafana   │           │
│    │ ┌─────────┐ │                   │  Alertmgr   │           │
│    │ │ App 1   │ │                   └─────────────┘           │
│    │ │ /metrics│ │                                             │
│    │ ├─────────┤ │     ┌─────────────────────────┐             │
│    │ │ App 2   │ │     │     ALERTMANAGER        │             │
│    │ │ /metrics│ │◀────│  ┌─────┐ ┌─────┐       │             │
│    │ ├─────────┤ │     │  │Slack│ │Email│       │             │
│    │ │ Node    │ │     │  └─────┘ └─────┘       │             │
│    │ │Exporter │ │     └─────────────────────────┘             │
│    │ └─────────┘ │                                             │
│    └─────────────┘                                             │
│                                                                 │
│  Service Discovery: Kubernetes, Consul, DNS, File SD           │
└─────────────────────────────────────────────────────────────────┘

Kluczowe komponenty:

Komponent Rola
Prometheus Server Scraping, storage, querying
TSDB Time Series Database (local storage)
Alertmanager Routing, grouping, silencing alertów
Pushgateway Dla short-lived jobs (batch)
Exporters Adaptery dla systemów bez native metrics

Data model - labels są kluczowe:

http_requests_total{method="GET", status="200", service="api"} 1234
http_requests_total{method="POST", status="500", service="api"} 5
│                   │                                           │
metric name         labels (key-value pairs)                   value

Na co zwraca uwagę rekruter:

  • Pull vs push model (Prometheus pulls)
  • Znaczenie labels dla dimensional data
  • Service discovery w Kubernetes

2. Napisz zapytanie PromQL które znajdzie serwisy z error rate > 1%

Odpowiedź:

# Error rate jako procent wszystkich requestów
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
> 0.01

# Bardziej czytelna wersja z pomocniczymi metrykami
# Zakładając że mamy http_requests_total z label status

# Krok 1: Rate błędów (5xx) per service
sum by (service) (
  rate(http_requests_total{status=~"5.."}[5m])
)

# Krok 2: Podziel przez total rate
/ ignoring(status)
sum by (service) (
  rate(http_requests_total[5m])
)

# Krok 3: Filtruj > 1%
> 0.01

Wyjaśnienie operatorów PromQL:

Operator Opis
rate() Per-second rate w oknie czasowym
sum by () Agregacja z grupowaniem
{status=~"5.."} Regex match
ignoring() Ignoruj label przy join
[5m] Range vector 5 minut

Inne przydatne zapytania:

# P99 latency per endpoint
histogram_quantile(0.99,
  sum(rate(http_request_duration_seconds_bucket[5m])) by (le, endpoint)
)

# Memory usage per pod
container_memory_usage_bytes{namespace="production"}
/ on(pod)
kube_pod_container_resource_limits{resource="memory"}

# Pods restarting frequently
increase(kube_pod_container_status_restarts_total[1h]) > 3

# CPU throttling
rate(container_cpu_cfs_throttled_seconds_total[5m])
/ rate(container_cpu_cfs_periods_total[5m]) > 0.2

3. Jak skonfigurować alerting w Prometheus?

Odpowiedź:

Alerting w Prometheus składa się z dwóch części: reguły alertów w Prometheus i routing w Alertmanager.

prometheus.yml - alert rules:

groups:
  - name: service-alerts
    rules:
      # High error rate
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
          /
          sum(rate(http_requests_total[5m])) by (service)
          > 0.01
        for: 5m  # Alert fires after 5m of condition being true
        labels:
          severity: critical
        annotations:
          summary: "High error rate on {{ $labels.service }}"
          description: "Error rate is {{ $value | humanizePercentage }}"

      # Service down
      - alert: ServiceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.job }} is down"

      # High latency
      - alert: HighLatency
        expr: |
          histogram_quantile(0.99,
            sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
          ) > 0.5
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "P99 latency > 500ms on {{ $labels.service }}"

alertmanager.yml - routing:

global:
  slack_api_url: 'https://hooks.slack.com/services/...'
  resolve_timeout: 5m

route:
  receiver: 'default'
  group_by: ['alertname', 'service']
  group_wait: 30s       # Wait before sending first notification
  group_interval: 5m    # Wait before sending updates
  repeat_interval: 4h   # Re-send if not resolved

  routes:
    # Critical alerts → PagerDuty + Slack
    - match:
        severity: critical
      receiver: 'pagerduty-critical'
      continue: true  # Also send to next matching route

    - match:
        severity: critical
      receiver: 'slack-critical'

    # Warning alerts → Slack only
    - match:
        severity: warning
      receiver: 'slack-warnings'

receivers:
  - name: 'default'
    slack_configs:
      - channel: '#alerts'

  - name: 'pagerduty-critical'
    pagerduty_configs:
      - service_key: '<pagerduty-key>'

  - name: 'slack-critical'
    slack_configs:
      - channel: '#alerts-critical'
        title: '🔥 {{ .CommonAnnotations.summary }}'

  - name: 'slack-warnings'
    slack_configs:
      - channel: '#alerts-warnings'

# Silencing example - mute during maintenance
inhibit_rules:
  - source_match:
      alertname: 'ServiceDown'
    target_match:
      severity: 'warning'
    equal: ['service']

Alert states:

  • Inactive - condition not met
  • Pending - condition met, waiting for for duration
  • Firing - alert active, notification sent

4. Prometheus vs InfluxDB vs Datadog - kiedy który?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│              MONITORING SOLUTIONS COMPARISON                    │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│              │  PROMETHEUS  │   INFLUXDB   │     DATADOG        │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Model        │ Pull         │ Push         │ Agent (push)       │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Query        │ PromQL       │ InfluxQL/    │ Custom + SQL       │
│ Language     │              │ Flux         │                    │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Storage      │ Local TSDB   │ Local/Cloud  │ Managed            │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Cardinality  │ Medium       │ High         │ Very High          │
│ Support      │ (labels)     │ (tags)       │ (managed)          │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Long-term    │ Thanos/      │ Built-in     │ Included           │
│ Storage      │ Cortex/Mimir │              │                    │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Cost         │ Free (infra) │ Free/Paid    │ $$$$ per host      │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Ops overhead │ Medium-High  │ Medium       │ None (SaaS)        │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ K8s native   │ ✅ Best      │ Good         │ Good               │
├──────────────┼──────────────┼──────────────┼────────────────────┤
│ Best for     │ Cloud-native,│ IoT, time    │ Enterprise,        │
│              │ K8s, DevOps  │ series data  │ full-stack obs.    │
└──────────────┴──────────────┴──────────────┴────────────────────┘

Decision guide:

Scenariusz Wybór
Kubernetes native Prometheus + Grafana
IoT / time series heavy InfluxDB
No ops team / enterprise Datadog
Cost sensitive Prometheus
Need APM + infra + logs Datadog or Elastic
High cardinality metrics VictoriaMetrics or Datadog

Grafana i Dashboards

5. Jak zaprojektować efektywny dashboard w Grafana?

Odpowiedź:

Dobry dashboard opowiada historię - od high-level overview do szczegółów. Stosuj zasadę USE (Utilization, Saturation, Errors) i RED (Rate, Errors, Duration).

┌─────────────────────────────────────────────────────────────────┐
│                    DASHBOARD STRUCTURE                          │
├─────────────────────────────────────────────────────────────────┤
│  ROW 1: Golden Signals (overview)                              │
│  ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐       │
│  │ Request   │ │  Error    │ │  Latency  │ │Saturation │       │
│  │   Rate    │ │   Rate    │ │   p99     │ │  (queue)  │       │
│  │  1.2k/s   │ │   0.1%    │ │   45ms    │ │   23%     │       │
│  └───────────┘ └───────────┘ └───────────┘ └───────────┘       │
│                                                                 │
│  ROW 2: Resource Utilization                                   │
│  ┌─────────────────────────────┐ ┌─────────────────────────┐   │
│  │       CPU Usage             │ │     Memory Usage        │   │
│  │  ████████████░░░░ 75%       │ │  ██████████░░░░░ 65%   │   │
│  └─────────────────────────────┘ └─────────────────────────┘   │
│                                                                 │
│  ROW 3: Service-specific metrics                               │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              Request Rate by Endpoint                    │   │
│  │  /api/users    ████████████████████  800/s              │   │
│  │  /api/orders   ████████████  400/s                      │   │
│  │  /api/products ████████  200/s                          │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ROW 4: Dependencies                                           │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  Database latency │ Cache hit rate │ External API       │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

Best practices:

# Dashboard design principles
1. Start with overview:
   - Single stat panels for key metrics
   - Red/yellow/green thresholds
   - Trends (vs yesterday, vs last week)

2. Progressive disclosure:
   - Click to drill down
   - Variables for filtering (namespace, service)
   - Links to detailed dashboards

3. Use appropriate visualizations:
   - Time series: trends over time
   - Gauge: current value vs threshold
   - Heatmap: latency distribution
   - Table: top N / bottom N

4. Consistent layout:
   - Same metric types aligned
   - Consistent colors (red = bad)
   - Standard time ranges

Przykładowy dashboard JSON (fragment):

{
  "panels": [
    {
      "title": "Request Rate",
      "type": "stat",
      "targets": [{
        "expr": "sum(rate(http_requests_total[5m]))",
        "legendFormat": "req/s"
      }],
      "fieldConfig": {
        "defaults": {
          "thresholds": {
            "steps": [
              {"color": "green", "value": null},
              {"color": "yellow", "value": 1000},
              {"color": "red", "value": 5000}
            ]
          }
        }
      }
    }
  ]
}

6. Jak zaimplementować RED i USE metrics?

Odpowiedź:

RED Method (dla serwisów):

  • Rate - requests per second
  • Errors - failed requests per second
  • Duration - latency distribution

USE Method (dla zasobów):

  • Utilization - % czasu resource jest zajęty
  • Saturation - queue length, pending work
  • Errors - error count
# RED Metrics dla HTTP serwisu

# Rate
sum(rate(http_requests_total[5m])) by (service)

# Errors (jako rate)
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)

# Errors (jako procent)
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/ sum(rate(http_requests_total[5m])) by (service)

# Duration (percentyle z histogramu)
histogram_quantile(0.50, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
histogram_quantile(0.90, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
# USE Metrics dla CPU

# Utilization
avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance)

# Saturation (load average vs cores)
node_load1 / count(node_cpu_seconds_total{mode="idle"}) by (instance)

# Errors
rate(node_cpu_guest_seconds_total[5m])  # or hardware errors if available
# USE Metrics dla pamięci

# Utilization
1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)

# Saturation (swap usage indicates saturation)
node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes

# Errors
rate(node_vmstat_oom_kill[5m])

Golden Signals (Google SRE):

  • Latency
  • Traffic
  • Errors
  • Saturation

Logging - ELK i Loki

7. ELK Stack vs Loki - kiedy który wybrać?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│                    ELK vs LOKI COMPARISON                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ELK STACK                        GRAFANA LOKI                 │
│  ┌─────────────┐                  ┌─────────────┐              │
│  │   Kibana    │                  │   Grafana   │              │
│  └──────┬──────┘                  └──────┬──────┘              │
│         │                                │                      │
│  ┌──────▼──────┐                  ┌──────▼──────┐              │
│  │Elasticsearch│                  │    Loki     │              │
│  │ (full-text  │                  │ (labels     │              │
│  │  indexing)  │                  │  only)      │              │
│  └──────┬──────┘                  └──────┬──────┘              │
│         │                                │                      │
│  ┌──────▼──────┐                  ┌──────▼──────┐              │
│  │  Logstash/  │                  │  Promtail   │              │
│  │   Beats     │                  │             │              │
│  └─────────────┘                  └─────────────┘              │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│  Feature          │    ELK         │    Loki                   │
├───────────────────┼────────────────┼───────────────────────────┤
│  Indexing         │ Full content   │ Labels only              │
│  Query            │ Lucene/KQL     │ LogQL (PromQL-like)      │
│  Storage cost     │ High           │ Low (S3/GCS)             │
│  Ops complexity   │ High           │ Low                       │
│  Search speed     │ Fast (indexed) │ Slower (grep-like)       │
│  K8s integration  │ Good           │ Excellent                │
│  Memory usage     │ High           │ Low                       │
│  Existing stack   │ Standalone     │ Grafana ecosystem        │
└─────────────────────────────────────────────────────────────────┘

Kiedy ELK:

  • Potrzebujesz full-text search w logach
  • Complex analytics i aggregations
  • Security/compliance wymagania (SIEM)
  • Duży zespół z dedykowanymi ops

Kiedy Loki:

  • Już używasz Prometheus + Grafana
  • Kubernetes native environment
  • Cost-sensitive
  • Proste use cases (debug, tail logs)

Loki query example (LogQL):

# Logi z błędami dla konkretnego serwisu
{namespace="production", app="api"} |= "error"

# Parse JSON i filtruj
{app="api"} | json | status_code >= 500

# Metryki z logów (jak Prometheus)
sum(rate({app="api"} |= "error" [5m])) by (pod)

8. Jak skonfigurować centralne logowanie w Kubernetes?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│            KUBERNETES LOGGING ARCHITECTURE                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Option 1: Node-level agent (DaemonSet)                        │
│  ┌───────────────────────────────────────────────────────────┐ │
│  │  Node                                                      │ │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐                   │ │
│  │  │  Pod A  │  │  Pod B  │  │  Pod C  │                   │ │
│  │  └────┬────┘  └────┬────┘  └────┬────┘                   │ │
│  │       │            │            │                         │ │
│  │       ▼            ▼            ▼                         │ │
│  │  ┌─────────────────────────────────────────────────────┐ │ │
│  │  │  /var/log/containers/*.log                          │ │ │
│  │  └───────────────────────┬─────────────────────────────┘ │ │
│  │                          │                                │ │
│  │  ┌───────────────────────▼─────────────────────────────┐ │ │
│  │  │  Fluent Bit / Promtail (DaemonSet)                  │ │ │
│  │  └───────────────────────┬─────────────────────────────┘ │ │
│  └──────────────────────────┼────────────────────────────────┘ │
│                             │                                   │
│                             ▼                                   │
│               ┌─────────────────────────────┐                  │
│               │   Elasticsearch / Loki      │                  │
│               └─────────────────────────────┘                  │
│                                                                 │
│  Option 2: Sidecar container                                   │
│  ┌───────────────────────────────────────────────────────────┐ │
│  │  Pod                                                       │ │
│  │  ┌─────────────┐     ┌─────────────┐                      │ │
│  │  │    App      │────▶│  Sidecar    │────▶ Backend         │ │
│  │  │  Container  │     │ (Fluent Bit)│                      │ │
│  │  └─────────────┘     └─────────────┘                      │ │
│  │        │ shared volume │                                   │ │
│  │        └───────────────┘                                   │ │
│  └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Fluent Bit DaemonSet configuration: ```yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: fluent-bit namespace: logging spec: selector: matchLabels: app: fluent-bit template: spec: containers: - name: fluent-bit image: fluent/fluent-bit:2.1 volumeMounts: - name: varlog mountPath: /var/log - name: config mountPath: /fluent-bit/etc/ resources: limits: memory: 200Mi cpu: 200m volumes: - name: varlog hostPath: path: /var/log - name: config configMap: name: fluent-bit-config

apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-config data: fluent-bit.conf: | [SERVICE] Flush 1 Log_Level info Parsers_File parsers.conf

[INPUT]
    Name             tail
    Path             /var/log/containers/*.log
    Parser           docker
    Tag              kube.*
    Refresh_Interval 5
    Mem_Buf_Limit    50MB

[FILTER]
    Name                kubernetes
    Match               kube.*
    Kube_URL            https://kubernetes.default.svc:443
    Kube_CA_File        /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    Kube_Token_File     /var/run/secrets/kubernetes.io/serviceaccount/token
    Merge_Log           On
    K8S-Logging.Parser  On

[OUTPUT]
    Name            es
    Match           *
    Host            elasticsearch
    Port            9200
    Index           k8s-logs
    Type            _doc

**Structured logging best practice:**
```javascript
// Application should log JSON
logger.info({
  message: "Order processed",
  orderId: "12345",
  userId: "user-789",
  duration_ms: 150,
  status: "success"
});

// Not plain text
logger.info("Order 12345 processed for user-789 in 150ms");

Distributed Tracing

9. Jak działa distributed tracing i kiedy go używać?

Odpowiedź:

Distributed tracing śledzi request przez wszystkie serwisy w systemie rozproszonym. Każdy request dostaje unikalne trace ID.

┌─────────────────────────────────────────────────────────────────┐
│                    DISTRIBUTED TRACE                            │
├─────────────────────────────────────────────────────────────────┤
│  Request: GET /api/orders/123                                   │
│  Trace ID: abc123                                               │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ API Gateway (span-1)                     [0ms - 250ms]  │   │
│  │ ┌─────────────────────────────────────────────────────┐ │   │
│  │ │ Order Service (span-2)                [10ms - 200ms]│ │   │
│  │ │ ┌───────────────────────────────────────────────┐   │ │   │
│  │ │ │ User Service (span-3)         [20ms - 50ms]   │   │ │   │
│  │ │ └───────────────────────────────────────────────┘   │ │   │
│  │ │ ┌───────────────────────────────────────────────┐   │ │   │
│  │ │ │ Database Query (span-4)       [60ms - 150ms]  │   │ │   │
│  │ │ └───────────────────────────────────────────────┘   │ │   │
│  │ └─────────────────────────────────────────────────────┘ │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Total: 250ms                                                   │
│  Bottleneck: Database Query (90ms)                             │
└─────────────────────────────────────────────────────────────────┘

Kluczowe koncepcje:

Concept Opis
Trace Pełna ścieżka requestu (tree of spans)
Span Pojedyncza operacja z czasem start/end
Trace ID Unikalny identyfikator trace (propagowany)
Span ID Identyfikator pojedynczego span
Parent Span Span który wywołał bieżący span
Baggage Key-value data propagowana przez trace

OpenTelemetry instrumentation (Node.js):

const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');

// Setup provider
const provider = new NodeTracerProvider();
provider.addSpanProcessor(
  new SimpleSpanProcessor(new JaegerExporter({
    endpoint: 'http://jaeger:14268/api/traces'
  }))
);
provider.register();

// Auto-instrument HTTP and Express
registerInstrumentations({
  instrumentations: [
    new HttpInstrumentation(),
    new ExpressInstrumentation(),
  ],
});

// Manual span creation
const tracer = provider.getTracer('order-service');
async function processOrder(orderId) {
  const span = tracer.startSpan('processOrder');
  span.setAttribute('order.id', orderId);

  try {
    // ... processing logic
    span.setStatus({ code: SpanStatusCode.OK });
  } catch (error) {
    span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
    span.recordException(error);
    throw error;
  } finally {
    span.end();
  }
}

Context propagation (HTTP headers):

# W3C Trace Context (standard)
traceparent: 00-abc123-span456-01
tracestate: vendor=value

# Jaeger format
uber-trace-id: abc123:span456:parent789:1

10. Jaeger vs Zipkin vs OpenTelemetry - co wybrać?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│                TRACING SOLUTIONS COMPARISON                     │
├───────────────┬───────────────┬───────────────┬─────────────────┤
│               │    JAEGER     │    ZIPKIN     │ OPENTELEMETRY   │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ Origin        │ Uber          │ Twitter       │ CNCF (merged    │
│               │               │               │ OpenTracing +   │
│               │               │               │ OpenCensus)     │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ Type          │ Full platform │ Full platform │ Standard/SDK    │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ Storage       │ Cassandra,    │ MySQL,        │ N/A (exports    │
│               │ Elasticsearch,│ Cassandra,    │ to backends)    │
│               │ Kafka         │ Elasticsearch │                 │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ UI            │ ✅ Built-in   │ ✅ Built-in   │ ❌ Need backend │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ K8s support   │ Excellent     │ Good          │ Excellent       │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ Sampling      │ Advanced      │ Basic         │ Configurable    │
├───────────────┼───────────────┼───────────────┼─────────────────┤
│ Future        │ Adopting OTel │ Adopting OTel │ THE standard    │
└───────────────┴───────────────┴───────────────┴─────────────────┘

Rekomendacja 2026:

OpenTelemetry SDK (instrumentation)
         │
         ├──▶ Jaeger (backend + UI)         # Self-hosted
         ├──▶ Grafana Tempo (backend)       # Grafana ecosystem
         ├──▶ AWS X-Ray                     # AWS native
         └──▶ Datadog APM                   # SaaS

OpenTelemetry to standard - używaj OTel SDK do instrumentacji, a backend wybierz według potrzeb. Jaeger i Zipkin adoptują OTel jako źródło danych.


SLI, SLO, SLA i Error Budgets

11. Wyjaśnij różnicę między SLI, SLO i SLA

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│                    SLI → SLO → SLA                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  SLI (Service Level Indicator)                                 │
│  ─────────────────────────────                                 │
│  METRYKA mierząca jakość usługi                                │
│  Przykłady:                                                    │
│  • Request latency p99                                         │
│  • Error rate (5xx / total)                                    │
│  • Availability (successful / total requests)                  │
│                                                                 │
│           ↓                                                     │
│                                                                 │
│  SLO (Service Level Objective)                                 │
│  ─────────────────────────────                                 │
│  CEL dla SLI (wewnętrzny)                                      │
│  Przykłady:                                                    │
│  • "99.9% requestów < 200ms"                                   │
│  • "Error rate < 0.1%"                                         │
│  • "99.95% availability per month"                             │
│                                                                 │
│           ↓                                                     │
│                                                                 │
│  SLA (Service Level Agreement)                                 │
│  ─────────────────────────────                                 │
│  KONTRAKT z klientem (zewnętrzny, z konsekwencjami)           │
│  Przykłady:                                                    │
│  • "99.9% uptime, otherwise refund"                           │
│  • "Response time < 500ms, penalty for breach"                │
│                                                                 │
│  SLA < SLO (zawsze zostawiaj bufor!)                          │
└─────────────────────────────────────────────────────────────────┘

Dobre SLI - zasady:

SLI powinno być:
  - Mierzalne: konkretna metryka, nie "działa dobrze"
  - User-facing: co odczuwa użytkownik, nie internal metrics
  - Actionable: możesz coś z tym zrobić
  - Owned: wiesz kto jest odpowiedzialny

Przykłady dobrych SLI:
  availability: "successful requests / total requests"
  latency: "requests served < 200ms / total requests"
  throughput: "requests processed per second"
  correctness: "valid responses / total responses"

Przykłady złych SLI:
  - "CPU usage < 80%" (internal, nie user-facing)
  - "No bugs" (nie mierzalne)
  - "System is fast" (nie konkretne)

12. Co to jest Error Budget i jak go używać?

Odpowiedź:

Error Budget to "budżet" na błędy wynikający z SLO. Jeśli SLO = 99.9% availability, masz 0.1% error budget.

┌─────────────────────────────────────────────────────────────────┐
│                    ERROR BUDGET CONCEPT                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  SLO: 99.9% availability per month                             │
│                                                                 │
│  Month = 43,200 minutes (30 days)                              │
│  Error Budget = 43,200 × 0.001 = 43.2 minutes downtime         │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  Month Progress:  [████████████████████░░░░░] 80%       │   │
│  │  Error Budget:    [████████░░░░░░░░░░░░░░░░░] 30%       │   │
│  │                                                          │   │
│  │  Used: 30 min / 43.2 min                                │   │
│  │  Remaining: 13.2 min for rest of month                  │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  DECISIONS BASED ON ERROR BUDGET:                              │
│                                                                 │
│  Budget > 50% remaining:                                       │
│    ✅ Ship new features                                        │
│    ✅ Run experiments                                          │
│    ✅ Risky deployments allowed                                │
│                                                                 │
│  Budget < 20% remaining:                                       │
│    ⚠️  Feature freeze                                          │
│    ⚠️  Focus on reliability                                    │
│    ⚠️  Only critical fixes                                     │
│                                                                 │
│  Budget exhausted:                                             │
│    🛑 Full freeze                                              │
│    🛑 All hands on reliability                                 │
│    🛑 No deployments until next period                        │
└─────────────────────────────────────────────────────────────────┘

Error budget policy:

error_budget_policy:
  burn_rate_alerts:
    - name: "2% budget burn in 1h"
      window: 1h
      burn_rate: 14.4  # 100% / (30*24) * 14.4 = 2% per hour
      severity: critical
      action: "Page on-call"

    - name: "5% budget burn in 6h"
      window: 6h
      burn_rate: 6
      severity: warning
      action: "Slack notification"

  exhaustion_actions:
    25_percent_remaining:
      - "Review all pending deployments"
      - "Increase testing requirements"

    10_percent_remaining:
      - "Feature freeze"
      - "Cancel non-critical releases"

    0_percent:
      - "Full deployment freeze"
      - "Incident review required"
      - "Reliability sprint"

Prometheus alert dla burn rate:

# Multi-window, multi-burn-rate alert (Google SRE)
groups:
  - name: slo-alerts
    rules:
      - alert: ErrorBudgetBurn
        expr: |
          (
            # Fast burn (2% in 1h)
            (1 - avg_over_time(up[1h])) > 14.4 * 0.001
            and
            (1 - avg_over_time(up[5m])) > 14.4 * 0.001
          )
          or
          (
            # Slow burn (5% in 6h)
            (1 - avg_over_time(up[6h])) > 6 * 0.001
            and
            (1 - avg_over_time(up[30m])) > 6 * 0.001
          )
        labels:
          severity: critical
        annotations:
          summary: "Error budget burning too fast"

Incident Management

13. Jak zorganizować proces on-call?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│                    ON-CALL STRUCTURE                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ESCALATION LEVELS                                             │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ L1: Primary On-Call                                      │   │
│  │     • First responder                                    │   │
│  │     • Acknowledge in 5 min                               │   │
│  │     • Start investigation                                │   │
│  │     │                                                    │   │
│  │     ▼ (escalate if no response in 15 min)               │   │
│  │ L2: Secondary On-Call                                    │   │
│  │     • Backup engineer                                    │   │
│  │     • Different timezone often                           │   │
│  │     │                                                    │   │
│  │     ▼ (escalate for major incidents)                    │   │
│  │ L3: Engineering Lead / Manager                           │   │
│  │     • P1 incidents                                       │   │
│  │     • Customer-facing issues                             │   │
│  │     │                                                    │   │
│  │     ▼ (escalate for business impact)                    │   │
│  │ L4: Executive                                            │   │
│  │     • PR/communication decisions                         │   │
│  │     • Major outages                                      │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ROTATION BEST PRACTICES:                                      │
│  • Weekly rotation (not daily - context switching)             │
│  • Handoff meeting at rotation                                 │
│  • Follow-the-sun for global teams                            │
│  • Compensatory time off                                       │
│  • Max 25% of time on-call (sustainable)                      │
│  • Runbooks for common issues                                  │
└─────────────────────────────────────────────────────────────────┘

PagerDuty / Opsgenie configuration:

escalation_policy:
  name: "API Service"
  rules:
    - targets:
        - type: schedule
          id: "primary-on-call"
      escalation_delay_in_minutes: 15

    - targets:
        - type: schedule
          id: "secondary-on-call"
      escalation_delay_in_minutes: 15

    - targets:
        - type: user
          id: "engineering-manager"
      escalation_delay_in_minutes: 30

schedules:
  - name: "primary-on-call"
    rotation_type: weekly
    start_time: "09:00"
    users:
      - alice
      - bob
      - charlie
    restrictions:
      - type: week_restriction
        start_day: monday
        end_day: friday

Runbook template:

# Alert: HighErrorRate on API Service

## Symptoms
- Error rate > 1% for 5+ minutes
- Users may see 500 errors

## Quick Checks (< 5 min)
1. Check Grafana dashboard: [link]
2. Check recent deployments: `kubectl rollout history deployment/api`
3. Check dependent services: Database, Redis, External APIs

## Common Causes & Fixes
### Database Connection Issues
- Check: `kubectl exec -it api-pod -- pg_isready -h db-host`
- Fix: Restart connection pool / Scale DB

### Memory Pressure
- Check: Pod memory usage in Grafana
- Fix: `kubectl rollout restart deployment/api`

### Bad Deploy
- Check: Recent releases in deployment history
- Fix: `kubectl rollout undo deployment/api`

## Escalation
- If not resolved in 30 min → Escalate to L2
- If customer impact → Notify #incidents channel

14. Jak przeprowadzić postmortem / incident review?

Odpowiedź:

Postmortem to blameless analiza incydentu skupiona na systemie, nie ludziach.

┌─────────────────────────────────────────────────────────────────┐
│                    POSTMORTEM TEMPLATE                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  INCIDENT SUMMARY                                               │
│  ───────────────                                                │
│  Date: 2026-01-12                                              │
│  Duration: 45 minutes (14:30 - 15:15 UTC)                      │
│  Severity: P1 (customer-facing, >10% users affected)           │
│  Services affected: API, Checkout                              │
│                                                                 │
│  IMPACT                                                        │
│  ──────                                                        │
│  • 15% of checkout requests failed                             │
│  • ~500 users affected                                         │
│  • Estimated revenue loss: $X                                  │
│  • Error budget consumed: 35% of monthly budget                │
│                                                                 │
│  TIMELINE                                                      │
│  ────────                                                      │
│  14:15 - Deploy v2.3.1 to production                          │
│  14:28 - Monitoring detects error rate spike                   │
│  14:30 - Alert fires, on-call paged                           │
│  14:35 - On-call acknowledges, starts investigation           │
│  14:45 - Root cause identified (DB connection leak)           │
│  14:50 - Rollback initiated                                   │
│  15:00 - Rollback complete, error rate dropping               │
│  15:15 - Incident resolved, monitoring back to normal         │
│                                                                 │
│  ROOT CAUSE                                                    │
│  ──────────                                                    │
│  Database connection pool leak introduced in v2.3.1            │
│  New feature didn't properly release connections               │
│  Pool exhausted after ~15 min of traffic                       │
│                                                                 │
│  CONTRIBUTING FACTORS                                          │
│  ────────────────────                                          │
│  • No connection pool monitoring in staging                    │
│  • Canary deployment only ran for 5 min (leak needs 15 min)   │
│  • Connection timeout was set to 30s (too long)               │
│                                                                 │
│  ACTION ITEMS                                                  │
│  ────────────                                                  │
│  □ Add connection pool metrics to Grafana (Owner: Alice, ETA: │
│    2026-01-15)                                                 │
│  □ Extend canary deployment to 30 min (Owner: Bob, ETA:       │
│    2026-01-14)                                                 │
│  □ Reduce connection timeout to 5s (Owner: Charlie, ETA:      │
│    2026-01-13)                                                 │
│  □ Add load test for connection pool (Owner: Alice, ETA:      │
│    2026-01-20)                                                 │
│                                                                 │
│  LESSONS LEARNED                                               │
│  ───────────────                                               │
│  • What went well: Fast detection, quick rollback              │
│  • What went poorly: Missed in code review, short canary      │
│  • Where we got lucky: Low traffic period                      │
└─────────────────────────────────────────────────────────────────┘

5 Whys example:

Problem: Checkout failed for 15% of users

Why 1: Database connections were exhausted
Why 2: New code didn't release connections properly
Why 3: Connection release was in finally block that wasn't reached
Why 4: Exception path wasn't tested
Why 5: No integration test for error scenarios

Root cause: Insufficient test coverage for error handling paths

Cloud-Native Monitoring

15. Jak monitorować aplikacje w Kubernetes?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│              KUBERNETES MONITORING STACK                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌───────────────────────────────────────────────────────────┐ │
│  │                      GRAFANA                               │ │
│  │  Dashboards │ Alerting │ Explore                          │ │
│  └──────┬─────────────┬──────────────┬───────────────────────┘ │
│         │             │              │                          │
│         ▼             ▼              ▼                          │
│  ┌────────────┐ ┌──────────┐ ┌────────────┐                    │
│  │ Prometheus │ │   Loki   │ │   Tempo    │                    │
│  │  (metrics) │ │  (logs)  │ │  (traces)  │                    │
│  └─────┬──────┘ └────┬─────┘ └─────┬──────┘                    │
│        │             │             │                            │
│  ┌─────▼─────────────▼─────────────▼──────┐                    │
│  │         KUBERNETES CLUSTER              │                    │
│  │                                         │                    │
│  │  ┌─────────────────────────────────┐   │                    │
│  │  │    kube-prometheus-stack        │   │                    │
│  │  │  • Prometheus Operator          │   │                    │
│  │  │  • Node Exporter (DaemonSet)    │   │                    │
│  │  │  • kube-state-metrics           │   │                    │
│  │  │  • Alertmanager                 │   │                    │
│  │  └─────────────────────────────────┘   │                    │
│  │                                         │                    │
│  │  ┌─────────────────────────────────┐   │                    │
│  │  │         Applications            │   │                    │
│  │  │  /metrics (Prometheus format)   │   │                    │
│  │  │  stdout (JSON logs)             │   │                    │
│  │  │  OpenTelemetry (traces)         │   │                    │
│  │  └─────────────────────────────────┘   │                    │
│  └─────────────────────────────────────────┘                    │
└─────────────────────────────────────────────────────────────────┘

kube-prometheus-stack installation:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install kube-prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --set grafana.adminPassword=admin \
  --set prometheus.prometheusSpec.retention=30d \
  --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi

ServiceMonitor for custom app:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: api-service
  namespace: monitoring
  labels:
    release: kube-prometheus
spec:
  selector:
    matchLabels:
      app: api
  namespaceSelector:
    matchNames:
      - production
  endpoints:
    - port: metrics
      interval: 30s
      path: /metrics

Key Kubernetes metrics:

# Pod CPU usage vs requests
sum(rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) by (pod)
/
sum(kube_pod_container_resource_requests{resource="cpu", namespace="production"}) by (pod)

# Pod memory usage vs limits
sum(container_memory_usage_bytes{namespace="production"}) by (pod)
/
sum(kube_pod_container_resource_limits{resource="memory", namespace="production"}) by (pod)

# Pod restart count
increase(kube_pod_container_status_restarts_total{namespace="production"}[1h])

# Deployment replicas available vs desired
kube_deployment_status_replicas_available / kube_deployment_spec_replicas

# PVC usage
kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes

16. AWS CloudWatch vs Prometheus - kiedy który?

Odpowiedź:

┌─────────────────────────────────────────────────────────────────┐
│            CLOUDWATCH vs PROMETHEUS                             │
├──────────────────────┬──────────────────────────────────────────┤
│      CLOUDWATCH      │           PROMETHEUS                     │
├──────────────────────┼──────────────────────────────────────────┤
│ AWS-native           │ Cloud-agnostic                          │
│ Managed (no ops)     │ Self-hosted (or managed: Grafana Cloud) │
│ Pay per metric       │ Infrastructure cost only                │
│ AWS integrations     │ K8s native                              │
│ 15-month retention   │ Configurable retention                  │
│ Basic alerting       │ Advanced alerting (Alertmanager)        │
│ Insights (logs)      │ PromQL (powerful)                       │
├──────────────────────┼──────────────────────────────────────────┤
│ Best for:            │ Best for:                               │
│ • AWS services only  │ • Kubernetes                            │
│ • Small teams        │ • Multi-cloud                           │
│ • No K8s             │ • Cost-sensitive                        │
│ • Lambda/Serverless  │ • Advanced queries                      │
└──────────────────────┴──────────────────────────────────────────┘

Hybrid approach (common):

┌─────────────────────────────────────────────────────────────────┐
│  AWS Services              EKS Workloads                       │
│  (RDS, Lambda, etc)        (microservices)                     │
│         │                        │                              │
│         ▼                        ▼                              │
│    CloudWatch              Prometheus                          │
│         │                        │                              │
│         └────────────┬───────────┘                              │
│                      ▼                                          │
│               Grafana (unified view)                           │
│         CloudWatch data source + Prometheus DS                 │
└─────────────────────────────────────────────────────────────────┘

CloudWatch Container Insights (EKS):

# Enable Container Insights
aws eks update-cluster-config \
  --name my-cluster \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'

# CloudWatch agent DaemonSet (automatic with EKS add-on)
eksctl create addon --name aws-cloudwatch-observability --cluster my-cluster

Praktyczne Zadania

Zadanie 1: Debug slow API endpoint

API endpoint /api/orders ma P99 latency > 2s. Jak to zbadasz?

Podejście:

1. Metrics: Sprawdź histogram latency w Grafana
   histogram_quantile(0.99, rate(http_request_duration_seconds_bucket{path="/api/orders"}[5m]))

2. Traces: Znajdź slow traces w Jaeger/Tempo
   - Filter: service=api, operation=/api/orders, duration>2s
   - Analizuj span breakdown

3. Logs: Correlate z trace_id
   {app="api"} |= "trace_id_from_jaeger"

4. Dependencies: Sprawdź latency DB, cache, external APIs
   - Database query time
   - Cache hit rate
   - External API response time

Zadanie 2: Setup alerting for SLO

SLO: 99.9% availability. Skonfiguruj multi-window burn rate alert.

Rozwiązanie:

# Alert jeśli wypalamy 2% budżetu w 1h (fast burn)
# lub 5% w 6h (slow burn)

- alert: SLOBurnRate
  expr: |
    (
      (1 - (sum(rate(http_requests_total{status!~"5.."}[1h])) / sum(rate(http_requests_total[1h])))) > (14.4 * 0.001)
      and
      (1 - (sum(rate(http_requests_total{status!~"5.."}[5m])) / sum(rate(http_requests_total[5m])))) > (14.4 * 0.001)
    )
    or
    (
      (1 - (sum(rate(http_requests_total{status!~"5.."}[6h])) / sum(rate(http_requests_total[6h])))) > (6 * 0.001)
      and
      (1 - (sum(rate(http_requests_total{status!~"5.."}[30m])) / sum(rate(http_requests_total[30m])))) > (6 * 0.001)
    )

Zadanie 3: Zaprojektuj dashboard dla microservice

Rozwiązanie:

Row 1: Golden Signals (stat panels)
- Request rate
- Error rate
- P99 latency
- Saturation (queue depth)

Row 2: RED metrics over time (time series)
- Requests by endpoint
- Errors by type
- Latency histogram heatmap

Row 3: Dependencies
- Database latency
- Cache hit rate
- External API success rate

Row 4: Resources (for debugging)
- CPU usage vs limit
- Memory usage vs limit
- Network I/O

Podsumowanie

Monitoring i observability to fundament niezawodnych systemów. Na rozmowie rekrutacyjnej oczekuj pytań o:

  1. Podstawy - różnica monitoring vs observability, trzy filary
  2. Prometheus - architektura, PromQL, alerting
  3. Grafana - dashboard design, RED/USE metrics
  4. Logging - ELK vs Loki, structured logging
  5. Tracing - distributed tracing, OpenTelemetry
  6. SRE concepts - SLI/SLO/SLA, error budgets
  7. Incident management - on-call, postmortems

Klucz do sukcesu: pokazanie że rozumiesz end-to-end observability - od zbierania danych, przez alerting, po incident response i improvement.


Zobacz też


Artykuł przygotowany przez zespół Flipcards - tworzymy materiały do nauki programowania i przygotowania do rozmów rekrutacyjnych.

Chcesz więcej pytań rekrutacyjnych?

To tylko jeden temat z naszego kompletnego przewodnika po rozmowach rekrutacyjnych. Uzyskaj dostęp do 800+ pytań z 13 technologii.

Kup pełny dostęp Zobacz bezpłatny podgląd
Powrót do blogu

Zostaw komentarz

Pamiętaj, że komentarze muszą zostać zatwierdzone przed ich opublikowaniem.