2.6 Observability и мониторинг

2.6 Observability и мониторинг #

🎯 Что такое Observability #

Observability (наблюдаемость) — это способность понимать внутреннее состояние системы на основе знаний о её внешних выходных данных. В DevOps это критически важная практика для поддержания надёжности и производительности приложений.

Три столпа Observability: #

  1. Метрики (Metrics) — числовые показатели системы
  2. Логи (Logs) — записи событий в системе
  3. Трассировка (Traces) — отслеживание запросов через систему

📊 Метрики #

Типы метрик: #

Технические метрики:

  • CPU, память, диск, сеть
  • Время отклика приложения
  • Количество запросов в секунду (RPS)
  • Коды ошибок HTTP

Бизнес-метрики:

  • Количество пользователей
  • Доходы
  • Конверсии

Популярные инструменты: #

  • Prometheus — сбор и хранение метрик
  • VictoriaMetrics — более быстрая альтернатива Prometheus
  • Grafana — визуализация данных
  • InfluxDB — временные ряды
  • Datadog — коммерческое решение

Пример настройки Prometheus: #

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'my-app'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: /metrics
    scrape_interval: 5s

⚠️ “Слепые зоны” метрик: что происходит между точками? #

🔥 ВАЖНО: Большинство не думает об этом, но графики могут врать!

Проблема интерполяции:

Время:     10:00    10:05    10:10    10:15
CPU:         20%      25%      30%      20%
График: ────────────────────────────────────
         20% ~~~~ 25% ~~~~ 30% ~~~~ 20%

Что на самом деле могло происходить между 10:05 и 10:10:

Реальность:
10:05 -> 25% CPU
10:06 -> 95% CPU (пик нагрузки!)
10:07 -> 98% CPU (почти предел!)
10:08 -> 40% CPU (нагрузка спала)
10:09 -> 35% CPU
10:10 -> 30% CPU

График покажет: плавный рост с 25% до 30%
Реальность: был критический пик в 95-98%!

Почему это критично: #

  1. Пропущенные инциденты - алерты не сработали
  2. Ложное спокойствие - “всё было хорошо”
  3. Неправильные выводы о производительности
  4. Недооценка нагрузки на систему

Примеры реальных проблем: #

Случай 1: Memory leak

12:00 -> 2GB RAM
12:15 -> 2.1GB RAM  
12:30 -> 2.2GB RAM

График: стабильный рост
Реальность: в 12:20 было 7.8GB (чуть не OOM!)

Случай 2: Database спайки

Query time: 100ms -> 120ms -> 110ms
График: небольшие колебания
Реальность: между точками были запросы по 8 секунд!

Решения: #

1. Уменьшение интервала сбора

# Вместо 15s
scrape_interval: 15s

# Используйте 5s или даже 1s для критических метрик
scrape_interval: 5s

2. Дополнительные метрики

Не ограничивайтесь только средними значениями, которые могут скрывать критические пики нагрузки. Используйте:

  • Максимальные значения - покажут реальные пики нагрузки
  • 95-й перцентиль - показывает типичную высокую нагрузку
  • 99-й перцентиль - помогает обнаружить редкие, но критичные пики

3. Structured logging для деталей

{
  "timestamp": "2024-01-15T12:06:30Z",
  "level": "WARN", 
  "message": "High CPU spike detected",
  "cpu_percent": 97.5,
  "duration_seconds": 30
}

4. Профилирование и трейсинг

# APM инструменты для детального анализа
- Jaeger (трейсинг запросов)
- New Relic (мониторинг производительности приложений)  
- DataDog (мониторинг пользователей)

Практический совет: #

Правило “3-х сигм” - если видите странные паттерны на графиках:

  1. Уменьшите интервал сбора метрик
  2. Добавьте max/p95/p99 метрики
  3. Включите детальное логирование
  4. Используйте профилировщики

💡 Запомните: Графики показывают тренды, но между точками может скрываться ад. Хороший мониторинг = метрики + логи + трейсы!

VictoriaMetrics — более быстрая альтернатива #

VictoriaMetrics — высокопроизводительная система мониторинга, совместимая с Prometheus API, но значительно превосходящая его по скорости и эффективности использования ресурсов.

Преимущества VictoriaMetrics: #

  • В 20x быстрее чем Prometheus при записи данных
  • В 10x меньше потребление RAM и CPU
  • Долгосрочное хранение без внешних зависимостей
  • Горизонтальное масштабирование (VictoriaMetrics Cluster)
  • Полная совместимость с Prometheus API
  • Сжатие данных — до 70% экономии места

Установка VictoriaMetrics: #

# Single node версия
docker run -it --rm -v victoria-metrics-data:/victoria-metrics-data \
  -p 8428:8428 \
  victoriametrics/victoria-metrics:latest

Миграция с Prometheus: #

# docker-compose.yml
version: '3.8'
services:
  victoria-metrics:
    image: victoriametrics/victoria-metrics:latest
    ports:
      - "8428:8428"
    volumes:
      - vmdata:/victoria-metrics-data
    command:
      - '--storageDataPath=/victoria-metrics-data'
      - '--httpListenAddr=:8428'
      - '--retentionPeriod=12'  # 12 месяцев хранения

  vmagent:
    image: victoriametrics/vmagent:latest
    ports:
      - "8429:8429"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--promscrape.config=/etc/prometheus/prometheus.yml'
      - '--remoteWrite.url=http://victoria-metrics:8428/api/v1/write'

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

volumes:
  vmdata:

Grafana настройка для VictoriaMetrics: #

{
  "name": "VictoriaMetrics",
  "type": "prometheus",
  "url": "http://victoria-metrics:8428",
  "access": "proxy",
  "isDefault": true
}

VictoriaMetrics vs Prometheus: #

Метрика Prometheus VictoriaMetrics
RAM usage ~3GB ~300MB
CPU usage ~2 cores ~0.2 cores
Disk IOPS ~1000 ~100
Compression gzip zstd (лучше)
Запросы/сек ~1000 ~10000

Кластерная версия: #

# VictoriaMetrics Cluster
version: '3.8'
services:
  vmstorage:
    image: victoriametrics/vmstorage:cluster
    ports:
      - "8482:8482"
    volumes:
      - vmstorage:/storage
    command:
      - '--storageDataPath=/storage'

  vminsert:
    image: victoriametrics/vminsert:cluster
    ports:
      - "8480:8480"
    depends_on:
      - vmstorage
    command:
      - '--storageNode=vmstorage:8400'

  vmselect:
    image: victoriametrics/vmselect:cluster
    ports:
      - "8481:8481"
    depends_on:
      - vmstorage
    command:
      - '--storageNode=vmstorage:8401'

volumes:
  vmstorage:

📝 Логирование #

Структурированные логи: #

{
  "timestamp": "2024-01-15T10:30:00Z",
  "level": "ERROR",
  "service": "user-service",
  "message": "Failed to authenticate user",
  "user_id": "12345",
  "request_id": "abc-def-123"
}

Централизованное логирование: #

Grafana Loki для логов #

Loki - это система для сбора и запроса логов, разработанная Grafana Labs:

# docker-compose для Loki
version: '3.8'
services:
  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/loki-config.yml
    command: -config.file=/etc/loki/local-config.yaml

  promtail:
    image: grafana/promtail:latest
    volumes:
      - /var/log:/var/log:ro
      - ./promtail-config.yml:/etc/promtail/config.yml
    command: -config.file=/etc/promtail/config.yml

Преимущества Loki #

✅ **Эффективное хранение**: индексирует только метки, не контент
✅ **Grafana интеграция**: native поддержка в Grafana
✅ **LogQL**: мощный язык запросов похожий на PromQL
✅ **Horizontal scaling**: поддержка кластерного развертывания
✅ **Cost effective**: дешевле ELK stack для больших объемов

# Пример LogQL запроса
{job="nginx"} |= "error" | json | status_code >= 400

Grafana Mimir для метрик #

Mimir - высокопроизводительная система хранения метрик:

# Mimir для long-term storage метрик Prometheus
version: '3.8'
services:
  mimir:
    image: grafana/mimir:latest
    ports:
      - "9009:9009"
    volumes:
      - ./mimir.yml:/etc/mimir/mimir.yml
    command:
      - --config.file=/etc/mimir/mimir.yml
      - --target=all

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --enable-feature=remote-write-receiver

Конфигурация Prometheus для отправки в Mimir #

# prometheus.yml
global:
  scrape_interval: 15s

remote_write:
  - url: http://mimir:9009/api/v1/push
    queue_config:
      capacity: 10000
      max_shards: 1000
      min_shards: 1
      max_samples_per_send: 2000

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

Преимущества Mimir #

✅ **Horizontal scaling**: автоматическое масштабирование
✅ **Multi-tenancy**: изоляция данных разных команд
✅ **Long-term storage**: эффективное хранение исторических данных
✅ **Prometheus compatibility**: 100% совместимость с Prometheus API
✅ **Cloud native**: оптимизирован для Kubernetes и облачных хранилищ

ELK Stack (Elasticsearch, Logstash, Kibana):

# docker-compose.yml для ELK
version: '3'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    environment:
      - discovery.type=single-node
    ports:
      - "9200:9200"

  logstash:
    image: docker.elastic.co/logstash/logstash:7.15.0
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    ports:
      - "5000:5000"

  kibana:
    image: docker.elastic.co/kibana/kibana:7.15.0
    ports:
      - "5601:5601"

Альтернативы ELK: #

  • Fluentd + OpenSearch
  • Loki (от Grafana)
  • Splunk (коммерческое)

🔍 Distributed Tracing #

Зачем нужна трассировка: #

  • Отслеживание запросов в микросервисах
  • Поиск узких мест в производительности
  • Понимание зависимостей между сервисами

Популярные решения: #

  • Jaeger
  • Zipkin
  • AWS X-Ray
  • OpenTelemetry (стандарт)

Пример интеграции с OpenTelemetry: #

Настройка трассировки для отслеживания запросов:

  1. Инициализация - настройка поставщика трассировки и создание объекта tracer
  2. Конфигурация экспорта - подключение к Jaeger для отправки данных трассировки
  3. Обработка span’ов - настройка batch обработчика для эффективной отправки
  4. Использование в коде - создание span’ов для отслеживания функций обработки заказов

Эта конфигурация позволяет отслеживать полный путь запроса от валидации до отправки заказа.

🚨 Алертинг #

Принципы качественного алертинга: #

  1. Не шумите — алерты только на критичные проблемы
  2. Действенность — каждый алерт должен требовать действий
  3. Контекст — включайте полезную информацию для решения
  4. Эскалация — система уведомления по уровням

Пример правил в Prometheus: #

# alert.rules.yml
groups:
- name: example
  rules:
  - alert: HighErrorRate
    expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "High error rate on {{ $labels.instance }}"
      description: "Error rate is {{ $value }} requests per second"

  - alert: DiskSpaceLow
    expr: disk_free_percent < 10
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "Disk space is running low"

Инструменты алертинга: #

  • Alertmanager (Prometheus)
  • PagerDuty
  • Opsgenie
  • VictorOps

🏗️ Практический пример: Мониторинг веб-приложения #

1. Настройка метрик в приложении: #

Пример создания Flask приложения с метриками Prometheus:

Приложение выполняет следующие функции:

  1. Определение метрик:

    • Counter для подсчета общего количества запросов по методам и endpoint’ам
    • Histogram для измерения времени отклика запросов
  2. Отслеживание запросов:

    • Фиксация времени начала обработки запроса
    • Увеличение счетчика запросов после обработки
    • Запись времени обработки в гистограмму
  3. Экспорт метрик:

    • Создание endpoint’а /metrics для Prometheus
    • Генерация метрик в формате Prometheus

2. Docker Compose для полного стека: #

version: '3.8'
services:
  app:
    build: .
    ports:
      - "5000:5000"
    
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./alert.rules.yml:/etc/prometheus/alert.rules.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--web.enable-lifecycle'
  
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-storage:/var/lib/grafana
      
  alertmanager:
    image: prom/alertmanager
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml

volumes:
  grafana-storage:

✅ Best Practices #

1. SRE подход: #

  • SLI (Service Level Indicators) — что измеряем
  • SLO (Service Level Objectives) — цели
  • SLA (Service Level Agreements) — договоренности
  • Error Budget — допустимое количество ошибок

2. Golden Signals: #

  • Latency — время отклика
  • Traffic — количество запросов
  • Errors — количество ошибок
  • Saturation — загруженность ресурсов

3. Мониторинг как код: #

# monitoring.tf (Terraform)
resource "aws_cloudwatch_dashboard" "main" {
  dashboard_name = "MyApp-Dashboard"
  
  dashboard_body = jsonencode({
    widgets = [
      {
        type = "metric"
        properties = {
          metrics = [
            ["AWS/ApplicationELB", "RequestCount"],
            ["AWS/ApplicationELB", "TargetResponseTime"]
          ]
          period = 300
          stat = "Sum"
          region = "us-west-2"
          title = "Application Metrics"
        }
      }
    ]
  })
}

🛠️ Альтернативные решения мониторинга #

Zabbix - Enterprise мониторинг #

Zabbix - зрелое enterprise решение для мониторинга инфраструктуры:

# docker-compose для Zabbix
version: '3.8'
services:
  zabbix-server:
    image: zabbix/zabbix-server-mysql:latest
    environment:
      - DB_SERVER_HOST=mysql
      - MYSQL_DATABASE=zabbix
      - MYSQL_USER=zabbix
      - MYSQL_PASSWORD=zabbix_password
    ports:
      - "10051:10051"
    depends_on:
      - mysql

  zabbix-web:
    image: zabbix/zabbix-web-nginx-mysql:latest
    environment:
      - DB_SERVER_HOST=mysql
      - MYSQL_DATABASE=zabbix
      - MYSQL_USER=zabbix
      - MYSQL_PASSWORD=zabbix_password
      - ZBX_SERVER_HOST=zabbix-server
    ports:
      - "8080:8080"

  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_DATABASE=zabbix
      - MYSQL_USER=zabbix
      - MYSQL_PASSWORD=zabbix_password
      - MYSQL_ROOT_PASSWORD=root_password

Преимущества Zabbix #

✅ **SNMP мониторинг**: отличная поддержка сетевого оборудования
✅ **Агенты**: мощные агенты для глубокого мониторинга ОС
✅ **Templates**: готовые шаблоны для популярных систем
✅ **Network discovery**: автоматическое обнаружение устройств
✅ **Notifications**: гибкая система уведомлений

SNMP мониторинг сетевого оборудования #

SNMP (Simple Network Management Protocol) для мониторинга железа:

# Установка SNMP tools
sudo apt install snmp snmp-mibs-downloader

# Проверка SNMP доступности
snmpwalk -v2c -c public 192.168.1.1 1.3.6.1.2.1.1.1.0

# Мониторинг интерфейсов
snmpwalk -v2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.2

# CPU загрузка на Cisco
snmpget -v2c -c public 192.168.1.1 1.3.6.1.4.1.9.2.1.56.0

# Память на Cisco
snmpget -v2c -c public 192.168.1.1 1.3.6.1.4.1.9.2.1.8.0

Prometheus + SNMP Exporter #

# snmp.yml конфигурация для SNMP exporter
modules:
  cisco_router:
    walk:
      - 1.3.6.1.2.1.2.2.1.2    # Interface names
      - 1.3.6.1.2.1.2.2.1.10   # Interface inbound octets
      - 1.3.6.1.2.1.2.2.1.16   # Interface outbound octets
      - 1.3.6.1.4.1.9.2.1.56   # CPU utilization
    metrics:
      - name: snmp_cisco_cpu_utilization
        oid: 1.3.6.1.4.1.9.2.1.56
        type: gauge
      - name: snmp_interface_in_octets
        oid: 1.3.6.1.2.1.2.2.1.10
        type: counter
# prometheus.yml для SNMP мониторинга
scrape_configs:
  - job_name: 'snmp'
    static_configs:
      - targets:
        - 192.168.1.1  # Router IP
        - 192.168.1.2  # Switch IP
    metrics_path: /snmp
    params:
      module: [cisco_router]
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: snmp-exporter:9116

Мониторинг физических серверов #

# Node Exporter для серверного железа
version: '3.8'
services:
  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: unless-stopped
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.rootfs=/rootfs'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
      - '--collector.textfile.directory=/var/lib/node_exporter/textfile_collector'
      - '--collector.systemd'
      - '--collector.processes'
    ports:
      - "9100:9100"

Важные метрики для серверов #

# CPU загрузка
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# Использование памяти
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

# Использование диска
100 - ((node_filesystem_avail_bytes * 100) / node_filesystem_size_bytes)

# Network I/O
rate(node_network_receive_bytes_total[5m])
rate(node_network_transmit_bytes_total[5m])

# Disk I/O
rate(node_disk_read_bytes_total[5m])
rate(node_disk_written_bytes_total[5m])

# Load Average
node_load1
node_load5
node_load15

🎯 Практические задания #

Задание 1: Базовый мониторинг #

  1. Поднимите Prometheus и Grafana через Docker Compose
  2. Создайте простое приложение с метриками
  3. Настройте дашборд в Grafana

Задание 2: Алертинг #

  1. Создайте правила алертинга в Prometheus
  2. Настройте Alertmanager для отправки уведомлений
  3. Протестируйте срабатывание алертов

Задание 3: Логирование #

  1. Настройте ELK stack
  2. Интегрируйте приложение с Logstash
  3. Создайте поисковые запросы в Kibana

📚 Дополнительные ресурсы #


Следующий раздел: 2.9 GitOps