9.9 KiB
9.9 KiB
Мониторинг
Обзор
Мониторинг 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)
}
Рекомендации
Продакшен
- Логирование: Используйте структурированные логи в JSON формате
- Метрики: Настройте Prometheus + Grafana
- Алерты: Настройте уведомления для критических событий
- Ротация логов: Настройте logrotate или отправку в ELK stack
- Мониторинг ресурсов: Отслеживайте CPU, память, диск, сеть
Разработка
- Локальное логирование: Используйте
RUST_LOG=debug - Отладка: Включите trace логи для детальной отладки
- Тестирование: Создайте тесты для проверки метрик
- Документация: Документируйте все кастомные метрики