Files
quoter/docs/monitoring.md
Untone 6c3262edbe
Some checks failed
Deploy / deploy (push) Has been skipped
CI / lint (push) Failing after 8s
CI / test (push) Failing after 3m57s
simpler-auth+no-overlay
2025-09-01 20:36:15 +03:00

9.9 KiB
Raw Blame History

Мониторинг

Обзор

Мониторинг Quoter включает в себя логирование, метрики производительности и отслеживание состояния системы.

Логирование

Уровни логирования

Quoter использует библиотеку log с различными уровнями:

  • error - Критические ошибки, требующие немедленного внимания
  • warn - Предупреждения, которые могут указывать на проблемы
  • info - Информационные сообщения о нормальной работе
  • debug - Отладочная информация для разработчиков
  • trace - Максимальная детализация для глубокой отладки

Настройка логирования

# Только ошибки
RUST_LOG=error cargo run

# Предупреждения и ошибки
RUST_LOG=warn cargo run

# Информационные сообщения (рекомендуется для продакшена)
RUST_LOG=info cargo run

# Отладка
RUST_LOG=debug cargo run

# Максимальная детализация
RUST_LOG=trace cargo run

Структура логов

Загрузка файла

[INFO] Started
[WARN] file abc123.jpg uploaded to storj, incrementing quota by 1048576 bytes
[WARN] New quota for user user123: 2097152 bytes

Получение файла

[WARN] >>> GET image_300.jpg [START]
[WARN] detected file extension: jpg
[WARN] base_filename: image
[WARN] requested width: 300
[WARN] Found stored path in DB: production/image/image.jpg
[WARN] File exists in Storj: production/image/image.jpg
[WARN] Processing image file with width: 300
[WARN] Calculated closest width: 300 for requested: 300
[WARN] serve existed thumb file: image_300.jpg

Ошибки

[ERROR] Failed to upload to Storj: image.jpg - Error: Network error
[ERROR] Database error while getting path: image.jpg - Full error: Connection timeout
[ERROR] unsupported file format

Метрики

Основные метрики для мониторинга

Производительность

  • Requests per second (RPS) - количество запросов в секунду
  • Response time - время ответа API
  • Error rate - процент ошибок
  • Upload success rate - процент успешных загрузок

Ресурсы

  • Memory usage - использование памяти
  • CPU usage - использование процессора
  • Disk I/O - операции с диском
  • Network I/O - сетевой трафик

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

  • Files uploaded - количество загруженных файлов
  • Quota usage - использование квот пользователями
  • Thumbnail generation - количество сгенерированных миниатюр
  • Storage usage - использование хранилища

Prometheus метрики

Добавьте в Cargo.toml:

[dependencies]
prometheus = "0.13"
actix-web-prom = "0.6"

Настройте в main.rs:

use actix_web_prom::{PrometheusMetrics, PrometheusMetricsBuilder};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let prometheus = PrometheusMetricsBuilder::new("quoter")
        .endpoint("/metrics")
        .build()
        .unwrap();

    HttpServer::new(move || {
        App::new()
            .wrap(prometheus.clone())
            // ... остальные настройки
    })
    .bind(addr)?
    .run()
    .await
}

Кастомные метрики

use prometheus::{Counter, Histogram, Registry};

lazy_static! {
    pub static ref UPLOAD_COUNTER: Counter = Counter::new(
        "quoter_uploads_total",
        "Total number of file uploads"
    ).unwrap();
    
    pub static ref UPLOAD_SIZE: Histogram = Histogram::new(
        "quoter_upload_size_bytes",
        "File upload size in bytes"
    ).unwrap();
    
    pub static ref QUOTA_USAGE: Histogram = Histogram::new(
        "quoter_quota_usage_bytes",
        "Author quota usage in bytes"
    ).unwrap();
}

Алерты

Критические алерты

  • Service down - сервис недоступен
  • High error rate - высокий процент ошибок (>5%)
  • High response time - медленные ответы (>2s)
  • Memory usage high - высокое использование памяти (>80%)
  • Redis connection failed - потеря соединения с Redis

Предупреждения

  • Quota usage high - пользователи приближаются к лимиту квоты
  • Storage usage high - высокое использование хранилища
  • Thumbnail generation slow - медленная генерация миниатюр

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

groups:
- name: quoter
  rules:
  - alert: QuoterServiceDown
    expr: up{job="quoter"} == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Quoter service is down"
      
  - alert: HighErrorRate
    expr: rate(http_requests_total{job="quoter",status=~"5.."}[5m]) > 0.05
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "High error rate detected"
      
  - alert: HighResponseTime
    expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{job="quoter"}[5m])) > 2
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High response time detected"

Дашборды

Grafana дашборд

Создайте дашборд с панелями:

Обзор системы

  • Статус сервиса (up/down)
  • Количество запросов в секунду
  • Время ответа (p50, p95, p99)
  • Процент ошибок

Загрузка файлов

  • Количество загрузок в час/день
  • Размер загружаемых файлов
  • Успешность загрузок
  • Использование квот

Ресурсы

  • Использование CPU и памяти
  • Сетевой трафик
  • Операции с диском
  • Соединения с Redis

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

  • Топ пользователей по использованию квоты
  • Популярные размеры миниатюр
  • Использование хранилища по типам файлов

Пример запроса для Grafana

-- Количество загрузок по часам
SELECT 
  time_bucket('1 hour', timestamp) AS time,
  COUNT(*) as uploads
FROM quoter_uploads 
WHERE timestamp > NOW() - INTERVAL '24 hours'
GROUP BY time
ORDER BY time;

Здоровье системы

Health check endpoint

Добавьте endpoint для проверки здоровья:

async fn health_check() -> HttpResponse {
    // Проверка Redis
    let redis_ok = check_redis_connection().await;
    
    // Проверка S3
    let s3_ok = check_s3_connection().await;
    
    if redis_ok && s3_ok {
        HttpResponse::Ok().json(json!({
            "status": "healthy",
            "timestamp": chrono::Utc::now(),
            "services": {
                "redis": "ok",
                "s3": "ok"
            }
        }))
    } else {
        HttpResponse::ServiceUnavailable().json(json!({
            "status": "unhealthy",
            "timestamp": chrono::Utc::now(),
            "services": {
                "redis": if redis_ok { "ok" } else { "error" },
                "s3": if s3_ok { "ok" } else { "error" }
            }
        }))
    }
}

Kubernetes liveness/readiness probes

livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 5
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  timeoutSeconds: 3
  failureThreshold: 3

Трассировка

Distributed tracing

Для отслеживания запросов через микросервисы:

[dependencies]
opentelemetry = "0.20"
tracing = "0.1"
tracing-opentelemetry = "0.20"

Логирование с контекстом

use tracing::{info, warn, error, instrument};

#[instrument(skip(state))]
async fn upload_handler(
    req: HttpRequest,
    payload: Multipart,
    state: web::Data<AppState>,
) -> Result<HttpResponse> {
    let user_id = get_user_id(&req).await?;
    info!(user_id = %user_id, "Starting file upload");
    
    // ... логика загрузки
    
    info!(user_id = %user_id, filename = %filename, "File uploaded successfully");
    Ok(response)
}

Рекомендации

Продакшен

  1. Логирование: Используйте структурированные логи в JSON формате
  2. Метрики: Настройте Prometheus + Grafana
  3. Алерты: Настройте уведомления для критических событий
  4. Ротация логов: Настройте logrotate или отправку в ELK stack
  5. Мониторинг ресурсов: Отслеживайте CPU, память, диск, сеть

Разработка

  1. Локальное логирование: Используйте RUST_LOG=debug
  2. Отладка: Включите trace логи для детальной отладки
  3. Тестирование: Создайте тесты для проверки метрик
  4. Документация: Документируйте все кастомные метрики