← Назад к вопросам

Зачем нужны метрики приложения?

2.0 Middle🔥 171 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Метрики приложения

Метрики — это численные данные о здоровье, производительности и использовании приложения. Без метрик ты работаешь вслепую в production.

Основная проблема

Без метрик:

  • Не знаешь, где проблема
  • Узнаёшь о баге только от пользователей
  • Не можешь доказать, что оптимизация помогла
  • Не понимаешь, какая фича была полезна

С метриками:

  • Видишь проблемы в реал-тайме
  • Понимаешь, как улучшить систему
  • Можешь мерить эффект изменений
  • Данные для принятия решений

Три типа метрик

1. RED метрики (для пользователей)

Rate, Errors, Duration — как приложение работает из perspective пользователя:

from prometheus_client import Counter, Histogram, Gauge
import time
from functools import wraps

# Rate — сколько запросов в секунду
request_count = Counter(
    'http_requests_total',
    'Total HTTP requests',
    ['method', 'endpoint', 'status']
)

# Errors — сколько ошибок
error_count = Counter(
    'http_errors_total',
    'Total HTTP errors',
    ['method', 'endpoint', 'error_type']
)

# Duration — сколько времени берет запрос
request_duration = Histogram(
    'http_request_duration_seconds',
    'HTTP request duration',
    ['method', 'endpoint'],
    buckets=(0.01, 0.05, 0.1, 0.5, 1.0, 5.0)
)

def track_request(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        try:
            result = func(*args, **kwargs)
            request_count.labels(
                method='GET',
                endpoint=func.__name__,
                status=200
            ).inc()
            return result
        except Exception as e:
            error_count.labels(
                method='GET',
                endpoint=func.__name__,
                error_type=type(e).__name__
            ).inc()
            raise
        finally:
            duration = time.time() - start
            request_duration.labels(
                method='GET',
                endpoint=func.__name__
            ).observe(duration)
    return wrapper

@track_request
def get_user(user_id):
    return fetch_from_db(user_id)

2. USE метрики (для инфраструктуры)

Utilization, Saturation, Errors — как используются ресурсы:

from prometheus_client import Gauge
import psutil

# Utilization — какой процент CPU/память используется
cpu_usage = Gauge('cpu_usage_percent', 'CPU usage percentage')
memory_usage = Gauge('memory_usage_percent', 'Memory usage percentage')

# Saturation — насколько система перегружена
queue_length = Gauge('queue_length', 'Length of job queue')
db_connections = Gauge('db_connections_active', 'Active DB connections')

# Errors — ошибки на уровне инфраструктуры
disk_errors = Counter('disk_errors_total', 'Total disk errors')
network_errors = Counter('network_errors_total', 'Total network errors')

def update_system_metrics():
    cpu_usage.set(psutil.cpu_percent())
    memory_usage.set(psutil.virtual_memory().percent)

3. Business метрики

Метрики, которые имеют значение для бизнеса:

from prometheus_client import Counter, Gauge

# Revenue
revenue = Counter(
    'revenue_total',
    'Total revenue',
    ['currency', 'product']
)

# Users
active_users = Gauge('active_users_count', 'Active users')
new_users = Counter('new_users_total', 'New users')
churned_users = Counter('churned_users_total', 'Churned users')

# Engagement
logins = Counter('user_logins_total', 'Total logins')
feature_usage = Counter('feature_usage_total', 'Feature usage', ['feature'])

def process_payment(user_id, amount, currency, product):
    # Процесс платежа
    revenue.labels(currency=currency, product=product).inc(amount)

Практический пример: FastAPI с метриками

from fastapi import FastAPI, Request
from prometheus_client import Counter, Histogram, generate_latest
from prometheus_client import REGISTRY
import time

app = FastAPI()

# Счетчики и гистограммы
request_count = Counter(
    'http_requests_total',
    'Total HTTP requests',
    ['method', 'endpoint', 'status']
)

request_duration = Histogram(
    'http_request_duration_seconds',
    'HTTP request duration',
    ['method', 'endpoint']
)

db_query_duration = Histogram(
    'db_query_duration_seconds',
    'Database query duration',
    ['query_type']
)

@app.middleware("http")
async def add_metrics(request: Request, call_next):
    start = time.time()
    response = await call_next(request)
    duration = time.time() - start
    
    # Записываем метрики
    request_count.labels(
        method=request.method,
        endpoint=request.url.path,
        status=response.status_code
    ).inc()
    
    request_duration.labels(
        method=request.method,
        endpoint=request.url.path
    ).observe(duration)
    
    return response

@app.get("/users/{user_id}")
async def get_user(user_id: int):
    start = time.time()
    try:
        # Запрос в БД
        user = await fetch_user_from_db(user_id)
        duration = time.time() - start
        
        db_query_duration.labels(query_type='get_user').observe(duration)
        return user
    except Exception as e:
        duration = time.time() - start
        db_query_duration.labels(query_type='get_user').observe(duration)
        raise

# Exposing metrics для Prometheus
@app.get("/metrics")
async def metrics():
    return generate_latest(REGISTRY)

Инструменты для сбора метрик

1. Prometheus (самый популярный)

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'myapp'
    static_configs:
      - targets: ['localhost:8000']  # Твое приложение
        metrics_path: '/metrics'

Потом запрашиваешь метрики в Prometheus:

# Средняя длительность запроса
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

# Количество ошибок в секунду
rate(http_requests_total{status=~"5.."}[5m])

# Использование памяти
memory_usage_percent

2. Grafana (визуализация)

Графана подключается к Prometheus и показывает красивые графики:

Dashboard Examples:
- Request Rate (5-minute average)
- Error Rate (% of failed requests)
- Response Time (p50, p95, p99 percentiles)
- CPU Usage
- Memory Usage
- DB Connection Pool

3. ELK Stack (Elasticsearch, Logstash, Kibana)

Для более подробного анализа логов и метрик:

import logging
from pythonjsonlogger import jsonlogger

logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
handler.setFormatter(formatter)
logger.addHandler(handler)

# Логирование в JSON формате
logger.info("User login", extra={
    "user_id": 123,
    "method": "password",
    "duration_ms": 245,
    "ip_address": "192.168.1.1"
})

Какие метрики отслеживать

Для веб-приложения:

1. Request metrics
   - Количество запросов в секунду (RPS)
   - HTTP status code распределение
   - Request duration (p50, p95, p99)
   - Error rate

2. Database metrics
   - Query duration
   - Slow queries
   - Connection pool utilization
   - Transaction duration

3. Resource metrics
   - CPU usage
   - Memory usage
   - Disk I/O
   - Network bandwidth

4. Business metrics
   - Active users
   - Revenue
   - Conversion rate
   - Feature usage

Пример: Нахождение проблемы с помощью метрик

Сценарий: Приложение работает медленно

Без метрик:
- Я не знаю, в чём проблема
- Гадаю: может быть БД? Может быть API? Может быть сеть?
- Трачу часы на поиск

С метриками:
- Смотрю http_request_duration_seconds
  → Видим: средняя длительность 5 секунд (нормально 100ms)
- Смотрю, какой endpoint медленный
  → /reports endpoint = 5 сек
- Смотрю db_query_duration_seconds
  → Запрос report_generation занимает 4.9 сек
- Смотрю EXPLAIN этого запроса
  → Нет индекса на колонке created_at
- Добавляю индекс
- Проверяю метрику
  → /reports endpoint = 200ms (25x быстрее!)

SLOs (Service Level Objectives)

Метрики используются для определения SLA/SLO:

SLO для моего приложения:
- 99% запросов должны вернуть ответ за 100ms
- Максимум 0.1% ошибок
- Uptime 99.9% в месяц

Вычисляю по метрикам:
- Если за месяц 2592000 запросов
  и 99.9% должны быть успешными
  → Могу себе позволить ~2592 ошибки

- Если за месяц 2592000 запросов
  и 99% за 100ms
  → Могу себе позволить ~25920 медленных запросов

Обработка Alerts

# Alert rules для Prometheus
groups:
  - name: application_alerts
    rules:
      - alert: HighErrorRate
        expr: rate(http_errors_total[5m]) > 0.01  # > 1% ошибок
        for: 5m
        annotations:
          summary: "High error rate detected"

      - alert: SlowRequests
        expr: histogram_quantile(0.95, http_request_duration_seconds) > 1
        annotations:
          summary: "95% requests slower than 1 second"

      - alert: HighMemory
        expr: memory_usage_percent > 85
        annotations:
          summary: "Memory usage above 85%"

Резюме

Метрики нужны для:

  • Мониторинга — видеть проблемы в реал-тайме
  • Отладки — быстро найти причину проблемы
  • Оптимизации — мерить эффект изменений
  • Бизнеса — понять ценность функций
  • Alerts — получать уведомления о проблемах
  • Плана — спланировать масштабирование

Без метрик ты работаешь как слепой летчик. С метриками ты видишь всю информацию о состоянии приложения.