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

Какую статистику собираешь во время разработки?

2.2 Middle🔥 191 комментариев
#DevOps и инфраструктура#Кэширование и производительность

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

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

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

Какую статистику собираешь во время разработки?

Статистика и метрики — это глаза и уши разработчика. Без них невозможно знать, хорошо ли работает система. Я собираю несколько типов статистики.

Тип 1: Performance метрики (как быстро работает)

Время ответа (Response Time)

import { performance } from 'perf_hooks';

app.use((req, res, next) => {
  const start = performance.now();
  
  res.on('finish', () => {
    const duration = performance.now() - start;
    console.log(`${req.method} ${req.path} - ${duration.toFixed(2)}ms`);
    
    // Отправлять в мониторинг
    metrics.recordHistogram('http.request.duration', duration, {
      method: req.method,
      path: req.path,
      status: res.statusCode
    });
  });
  
  next();
});

// Типичные значения:
// < 100ms   — отлично (green)
// 100-500ms — приемлемо (yellow)
// > 500ms   — медленно (red)

Throughput (сколько запросов в секунду)

const requestCounter = new Counter('http.requests.total', {
  help: 'Total HTTP requests',
  labelNames: ['method', 'path', 'status']
});

app.use((req, res, next) => {
  res.on('finish', () => {
    requestCounter
      .labels(req.method, req.path, res.statusCode)
      .inc();
  });
  next();
});

// На production обычно:
// - 100-500 req/s на одной Node машине
// - масштабируется до 10,000+ req/s с load balancer

Database query time

// Измеряю время каждого запроса в БД
db.query(sql, params)
  .then(result => {
    const duration = Date.now() - start;
    metrics.histogram('db.query.duration', duration, {
      operation: 'SELECT',
      table: 'users'
    });
    return result;
  });

// Типичные значения:
// Simple SELECT:    1-5ms
// With JOIN:       10-50ms
// Complex query:    50-500ms
// > 1000ms:        SLOW! найти индексы

Slow queries (что медленное)

-- В PostgreSQL
ENABLE log_statement = 'all';
SET log_min_duration_statement = 100; -- логируй все > 100ms

-- Затем анализирую логи
grep "duration:" postgres.log | sort -t: -k3 -nr | head -10

Тип 2: Error метрики (что сломалось)

Error rate (процент ошибок)

const errorCounter = new Counter('errors.total', {
  labelNames: ['type', 'status_code']
});

app.use((err, req, res, next) => {
  errorCounter.labels(err.name, err.status || 500).inc();
  
  console.error('Error:', err);
  res.status(err.status || 500).json({ error: err.message });
});

// Мониторю:
// - 5xx errors > 0.1% = алерт
// - 4xx errors normal (клиент ошибка)
// - 3xx errors (redirects) — на что смотреть

Error types

// Разные типы ошибок дают разную информацию

ErrorCounter.labels('ValidationError', 400).inc(); // Клиент отправил плохие данные
ErrorCounter.labels('AuthenticationError', 401).inc(); // Юзер не авторизован
ErrorCounter.labels('AuthorizationError', 403).inc(); // Юзер не имеет доступа
ErrorCounter.labels('NotFoundError', 404).inc(); // Ресурс не существует
ErrorCounter.labels('DatabaseError', 500).inc(); // База ошибка (ВАЖНО!)
ErrorCounter.labels('ValidationError', 500).inc(); // Внутренняя ошибка

Error tracing

import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 0.1, // 10% ошибок
});

try {
  await riskyOperation();
} catch (err) {
  Sentry.captureException(err, {
    contexts: {
      user: { id: userId, email: userEmail },
      request: { url: req.url, method: req.method }
    }
  });
}

// Sentry дает:
// - Стэк трейс
// - Контекст (юзер, запрос, устройство)
// - Grouping (одинаковые ошибки)
// - Notifications в Slack

Тип 3: Business метрики (что делают пользователи)

User analytics

// Отслеживаю actions пользователей
const analytics = new Analytics();

app.post('/users/signup', async (req, res) => {
  const user = await createUser(req.body);
  
  analytics.track('user_signup', {
    user_id: user.id,
    email: user.email,
    source: req.query.source, // utm_source
    timestamp: new Date()
  });
  
  res.json(user);
});

// Из этого вижу:
// - Сколько новых юзеров в день
// - Откуда приходят (какой источник трафика)
// - Тренды (растёт или падает)

Conversion funnel

// Отслеживаю шаги до покупки
router.post('/products/:id/view', async (req, res) => {
  analytics.track('product_viewed', { product_id: req.params.id });
});

router.post('/cart/add', async (req, res) => {
  analytics.track('product_added_to_cart', { ... });
});

router.post('/checkout', async (req, res) => {
  analytics.track('checkout_started', { ... });
});

router.post('/orders', async (req, res) => {
  analytics.track('purchase_completed', { ... });
});

// Видно где теряем юзеров:
// Viewed: 1000
// Added to cart: 200
// Checkout: 50
// Purchased: 10
// = 90% потеря между view и cart

Revenue metrics

router.post('/orders', async (req, res) => {
  const order = await createOrder(req.body);
  
  metrics.gauge('revenue.total', order.amount, {
    currency: 'USD'
  });
  
  metrics.counter('orders.total').inc();
  metrics.counter('orders.value', order.amount);
  
  // Простая аналитика
  if (order.amount > 1000) {
    analytics.track('high_value_order', { order_id: order.id });
  }
});

// Из этого вижу:
// - Средняя стоимость заказа
// - MRR (monthly recurring revenue)
// - Тренды доходов

Тип 4: Infrastructure метрики (как работает сервер)

CPU и Memory

import os from 'os';

setInterval(() => {
  const cpuUsage = process.cpuUsage();
  const memUsage = process.memoryUsage();
  
  metrics.gauge('process.cpu.user', cpuUsage.user);
  metrics.gauge('process.cpu.system', cpuUsage.system);
  
  metrics.gauge('process.memory.rss', memUsage.rss);
  metrics.gauge('process.memory.heapUsed', memUsage.heapUsed);
  metrics.gauge('process.memory.heapTotal', memUsage.heapTotal);
  
  // Проверка
  if (memUsage.heapUsed > 1000 * 1024 * 1024) { // > 1GB
    console.warn('High memory usage!', memUsage);
  }
}, 10000);

// Здоровые значения:
// RSS: 50-200MB для Node приложения
// HeapUsed: 30-100MB
// HeapTotal: 50-150MB

Database connections

const poolMetrics = pool.on('error', (err) => {
  metrics.counter('db.connection.errors').inc();
});

setInterval(() => {
  metrics.gauge('db.connections.total', pool.totalCount);
  metrics.gauge('db.connections.idle', pool.idleCount);
  metrics.gauge('db.connections.waiting', pool.waitingCount);
}, 10000);

// Мониторю утечки соединений
if (pool.waitingCount > 10) {
  console.warn('Too many waiting connections!');
}

Cache hit rate

const cacheHits = new Counter('cache.hits');
const cacheMisses = new Counter('cache.misses');

function getFromCache(key) {
  const value = cache.get(key);
  if (value) {
    cacheHits.inc();
  } else {
    cacheMisses.inc();
  }
  return value;
}

// Счетаю hit rate
const hitRate = hits / (hits + misses) * 100;
// Healthy: > 80% hit rate
// If < 50%: cache configuration нужно менять

Тип 5: Development metrics (как работают разработчики)

Code coverage

$ npm run test:coverage

File                  | Coverage
────────────────────┼──────────
services/user.ts    | 95%
controllers/auth.ts | 85%
utils/validation.ts | 90%
Total               | 90%

Требую минимум 90% coverage на production коде.

Test execution time

$ npm test

Test Suites: 12 passed, 12 total
Tests:       234 passed, 234 total
Time:        15.234s

# Если растёт > 30 сек = добавлять параллелизм

Build time

$ npm run build

build complete in 34.5 seconds

# Мониторю тренд
# Если растёт > 1 минуты — оптимизировать

Deployment frequency

// Сколько раз в день деплорим
deployCount = commits_to_main / week

// High performers:
// - несколько деплоев в день
// - от commit до production < 15 минут

// Low performers:
// - раз в неделю или месяц
// - от commit до production часы

Тип 6: Сухое резюме (что собираю)

// Минимальный набор метрик для production

const metrics = {
  // Performance
  'http.request.duration': histogram,
  'http.requests.total': counter,
  'db.query.duration': histogram,
  
  // Errors
  'errors.total': counter,
  'error.rate': gauge, // percentage
  
  // Business
  'users.total': gauge,
  'revenue.total': gauge,
  'orders.total': counter,
  
  // Infrastructure
  'process.memory.heapUsed': gauge,
  'process.cpu.usage': gauge,
  'db.connections.idle': gauge,
  
  // Development
  'tests.coverage.percent': gauge,
  'build.time.seconds': gauge,
  'deploy.frequency.per_day': gauge
};

// Визуализирую в Grafana
// Алерты в PagerDuty
// Уведомления в Slack

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

// Prometheus — метрики
import prometheus from 'prom-client';

// Grafana — визуализация
// (графики, дашборды)

// ELK Stack — логирование
// - Elasticsearch: хранилище
// - Logstash: обработка логов
// - Kibana: визуализация

// Sentry — error tracking
// (какие ошибки и где)

// Datadog — все в одном
// (метрики + логи + traces)

// NewRelic — мониторинг
// (APM, infrastructure, alerts)

Вывод: хорошие метрики — это разница между слепым полётом и пилотированием. Я собираю статистику постоянно, выглядываю в графики и реагирую на проблемы ДО они затрагивают пользователей.

Какую статистику собираешь во время разработки? | PrepBro