Hot Reload и Система Алертов

Hot Reload и Система Алертов

🔄 Hot Reload Конфигурации

Обзор

Система hot reload позволяет изменять конфигурацию приложения без перезапуска. Изменения в файле configs/config.yaml автоматически применяются в реальном времени.

Архитектура Hot Reload

sequenceDiagram
    participant User as Пользователь
    participant FS as Файловая система
    participant Watcher as Config Watcher
    participant Manager as Config Manager
    participant Validator as Config Validator
    participant Subscribers as Подписчики
    
    User->>FS: Изменяет config.yaml
    FS->>Watcher: Событие изменения
    Watcher->>Manager: Обнаружено изменение
    Manager->>FS: Чтение файла
    Manager->>Validator: Валидация конфигурации
    alt Валидация успешна
        Validator->>Manager: OK
        Manager->>Subscribers: Уведомление об изменениях
        Subscribers->>Subscribers: Обновление конфигурации
    else Валидация не прошла
        Validator->>Manager: Ошибка
        Manager->>Manager: Откат изменений
    end

Возможности

  • Автоматическое отслеживание изменений в файле конфигурации
  • Валидация конфигурации перед применением
  • Уведомления подписчиков об изменениях
  • Graceful применение изменений без прерывания работы

Использование

1. Изменение конфигурации

# Редактируем конфигурацию
vim configs/config.yaml

# Изменения применяются автоматически
# Логи покажут результат применения

2. Подписка на изменения

// Подписываемся на изменения конфигурации
configManager.Subscribe("worker_pool", func(oldConfig, newConfig *model.Config) error {
    // Обновляем worker pool с новыми настройками
    workerPool.UpdateConfig(newConfig.SystemSetup.WorkerPool)
    return nil
})

3. Принудительная перезагрузка

// Принудительно перезагружаем конфигурацию
err := configManager.Reload()
if err != nil {
    log.Error("Ошибка перезагрузки конфигурации", slog.String("error", err.Error()))
}

Валидация конфигурации

Система автоматически валидирует:

  • Положительные значения для портов и размеров
  • Обязательные поля (URL, hostnames)
  • Корректность структуры данных
  • Наличие хотя бы одной биржи

Логирование

✅ ConfigManager инициализирован config_path=configs/config.yaml
🔍 Мониторинг изменений конфигурации file=configs/config.yaml
📝 Обнаружено изменение конфигурации file=configs/config.yaml operation=WRITE
✅ Конфигурация успешно перезагружена

🚨 Система Алертов

Обзор

Система алертов обеспечивает мониторинг состояния приложения и уведомления о проблемах через различные каналы.

Архитектура системы алертов

graph TB
    subgraph "Система алертов"
        RULES[Alert Rules]
        EVALUATOR[Rule Evaluator]
        MANAGER[Alert Manager]
    end
    
    subgraph "Каналы уведомлений"
        LOG[Log Channel]
        CONSOLE[Console Channel]
        FILE[File Channel]
        WEBHOOK[Webhook Channel]
        SLACK[Slack Channel]
    end
    
    subgraph "Источники данных"
        METRICS[Prometheus Metrics]
        HEALTH[Health Checks]
        SYSTEM[System Stats]
    end
    
    METRICS --> RULES
    HEALTH --> RULES
    SYSTEM --> RULES
    RULES --> EVALUATOR
    EVALUATOR --> MANAGER
    MANAGER --> LOG
    MANAGER --> CONSOLE
    MANAGER --> FILE
    MANAGER --> WEBHOOK
    MANAGER --> SLACK

Уровни алертов

  • Info - информационные сообщения
  • Warning - предупреждения
  • Error - ошибки
  • Critical - критические проблемы

Каналы уведомлений

1. Логирование

// Автоматически настроен
logChannel := alerts.NewLogChannel(log)
alertingService.AddChannel(logChannel)

2. Консоль

consoleChannel := alerts.NewConsoleChannel("[{{.Time}}] {{.Level}} - {{.Name}}: {{.Message}}")
alertingService.AddChannel(consoleChannel)

3. Файл

fileChannel, err := alerts.NewFileChannel("logs/alerts.log")
if err == nil {
    alertingService.AddChannel(fileChannel)
}

4. Webhook

export ALERT_WEBHOOK_URL="https://api.example.com/alerts"
// Автоматически добавляется при наличии переменной окружения
webhookChannel := alerts.NewWebhookChannel(webhookURL, 10*time.Second)

5. Slack

export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export SLACK_CHANNEL="#alerts"
// Автоматически добавляется при наличии переменных окружения
slackChannel := alerts.NewSlackChannel(webhookURL, channel, "Quotes Worker", 10*time.Second)

Готовые правила алертов

Системные правила

  • high_memory_usage - высокое потребление памяти (>80%)
  • high_goroutines - много горутин (>1000)

Circuit Breaker правила

  • circuit_breaker_open_name - Circuit Breaker открыт
  • circuit_breaker_high_errors_name - много ошибок (>10)

Data Manager правила

  • data_manager_stale_data - данные устарели (>1 час)
  • data_manager_high_memory - много памяти (>1GB)
  • data_manager_low_data - мало данных (<1000 записей)

База данных

  • database_unavailable - БД недоступна

Создание пользовательских правил

1. Простое правило

rule := &alerts.AlertRule{
    Name:        "custom_rule",
    Description: "Описание правила",
    Level:       alerts.AlertLevelWarning,
    Condition: func() (bool, error) {
        // Логика проверки
        return someCondition, nil
    },
    Duration: 5 * time.Minute,
    Labels: map[string]string{
        "component": "custom",
        "type":      "monitoring",
    },
}
alertingService.AddRule(rule)

2. Правило с пороговым значением

rule := ruleFactory.CreateThresholdRule(
    "high_error_rate",
    "Высокий процент ошибок",
    alerts.AlertLevelError,
    func() (float64, error) {
        return getErrorRate(), nil
    },
    5.0, // 5%
    ">",
    2*time.Minute,
)

3. Правило с метриками

rule := ruleFactory.CreateCustomRule(
    "slow_response_time",
    "Медленное время ответа",
    alerts.AlertLevelWarning,
    func() (bool, error) {
        avgResponseTime := getAverageResponseTime()
        return avgResponseTime > 1000*time.Millisecond, nil
    },
    1*time.Minute,
    map[string]string{
        "component": "api",
        "type":      "performance",
    },
)

Метрики алертов

Prometheus метрики

  • alerts_total{level,status} - общее количество алертов
  • alerts_active{level} - активные алерты
  • alert_duration_seconds{level} - длительность алертов
  • alert_rule_evaluations_total{rule_name,result} - оценки правил
  • alert_rule_errors_total{rule_name} - ошибки правил

Пример запроса Grafana

# Количество активных алертов по уровням
alerts_active

# Длительность алертов
histogram_quantile(0.95, alert_duration_seconds_bucket)

# Частота срабатывания правил
rate(alert_rule_evaluations_total[5m])

API для алертов

Получение активных алертов

activeAlerts := alertingService.GetActiveAlerts()
for _, alert := range activeAlerts {
    fmt.Printf("Активный алерт: %s - %s\n", alert.Name, alert.Message)
}

Статистика

stats := alertingService.GetStats()
fmt.Printf("Правил: %d, Каналов: %d, Активных алертов: %d\n",
    stats["rules_count"], stats["channels_count"], stats["active_alerts"])

Конфигурация через переменные окружения

Каналы уведомлений

# Webhook
export ALERT_WEBHOOK_URL="https://api.example.com/alerts"

# Slack
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export SLACK_CHANNEL="#alerts"

# Email (заглушка)
export ALERT_EMAIL_TO="admin@example.com"
export ALERT_EMAIL_FROM="alerts@example.com"
export ALERT_SMTP_URL="smtp://localhost:587"

Настройки алертов

# Интервал проверки правил (по умолчанию 30с)
export ALERT_CHECK_INTERVAL="30s"

# Уровень логирования алертов
export ALERT_LOG_LEVEL="info"

Мониторинг и отладка

Логи алертов

🚀 Система алертов запущена
✅ Каналы уведомлений настроены
✅ Правила алертов настроены
🚨 Алерт сработал rule=high_memory_usage level=warning alert_id=high_memory_usage_1234567890
✅ Алерт разрешен rule=high_memory_usage alert_id=high_memory_usage_1234567890 duration=5m30s

Проверка состояния

# Проверка активных алертов
curl http://localhost:8080/metrics | grep alerts_active

# Статистика системы алертов
curl http://localhost:8080/health | jq '.alerting_service'

Интеграция с существующими компонентами

ServiceContainer

// Автоматическая инициализация
configManager, err := config.NewConfigManager("configs/config.yaml", log)
alertingService := alerts.NewAlertingService(log, 30*time.Second)

// Настройка в HotStart
serviceContainer.setupAlertChannels()
serviceContainer.setupAlertRules()
alertingService.Start()

Graceful shutdown

// Автоматическое завершение
defer serviceContainer.Close()
// Останавливает ConfigManager и AlertingService

Примеры использования

1. Мониторинг производительности

// Правило на медленные запросы
rule := ruleFactory.CreateThresholdRule(
    "slow_queries",
    "Медленные запросы к БД",
    alerts.AlertLevelWarning,
    func() (float64, error) {
        return getAverageQueryTime().Milliseconds(), nil
    },
    1000.0, // 1 секунда
    ">",
    1*time.Minute,
)

2. Мониторинг доступности

// Правило на недоступность внешних сервисов
rule := ruleFactory.CreateCustomRule(
    "external_service_down",
    "Внешний сервис недоступен",
    alerts.AlertLevelCritical,
    func() (bool, error) {
        return !isExternalServiceAvailable(), nil
    },
    30*time.Second,
    map[string]string{
        "component": "external_api",
        "type":      "connectivity",
    },
)

3. Мониторинг бизнес-метрик

// Правило на низкую производительность торговли
rule := ruleFactory.CreateThresholdRule(
    "low_trading_performance",
    "Низкая производительность торговли",
    alerts.AlertLevelWarning,
    func() (float64, error) {
        return getTradingSuccessRate(), nil
    },
    0.8, // 80%
    "<",
    5*time.Minute,
)

Troubleshooting

Проблемы с hot reload

  1. Файл не отслеживается: Проверьте путь к файлу конфигурации
  2. Ошибки валидации: Проверьте синтаксис YAML и обязательные поля
  3. Подписчики не уведомляются: Проверьте логи на ошибки в callback

Проблемы с алертами

  1. Алерты не срабатывают: Проверьте логику условий в правилах
  2. Уведомления не отправляются: Проверьте настройки каналов
  3. Много ложных срабатываний: Настройте Duration для правил

Заключение

Система hot reload и алертов обеспечивает:

  • Гибкость - изменение конфигурации без перезапуска
  • Надежность - мониторинг состояния системы
  • Производительность - быстрая реакция на проблемы
  • Масштабируемость - легко добавлять новые правила и каналы

Все компоненты интегрированы в существующую архитектуру и работают автоматически.