Мониторинг TypeScript приложений: метрики и алерты

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Мониторинг TypeScript приложений: от метрик до умных алертов

В современной разработке написать код — лишь половина дела. Критически важно понимать, как приложение ведёт себя в production. Для TypeScript-проектов, будь то сервер на Node.js или клиент на React, проактивный мониторинг становится обязательным требованием. В этой статье мы разберём продвинутые техники сбора метрик, настройки алертов и построения системы observability, которая позволит вам спать спокойно.

1. Ключевые метрики для TypeScript-приложений

Прежде чем настраивать алерты, нужно определить, что именно мы измеряем. Разделим метрики на три группы: инфраструктурные, бизнесовые и пользовательские.

Инфраструктурные метрики (RED-методология):

  • Rate — количество запросов в секунду (RPS).
  • Errors — процент ошибок (5xx, 4xx, unhandled rejections).
  • Duration — время ответа (p50, p95, p99).

Бизнесовые метрики:

  • Количество успешных транзакций.
  • Время выполнения критических операций (например, генерация отчёта).
  • Активные пользователи (DAU/MAU).

Пользовательские метрики (для клиентских приложений):

  • LCP (Largest Contentful Paint) — скорость загрузки основного контента.
  • FID (First Input Delay) — задержка первого взаимодействия.
  • CLS (Cumulative Layout Shift) — стабильность визуального макета.

Для сбора этих метрик в TypeScript мы будем использовать библиотеку prom-client (для Node.js) и @opentelemetry/instrumentation-http.

2. Сбор метрик с помощью Prometheus и OpenTelemetry

Рассмотрим пример настройки метрик для Express-приложения на TypeScript. Установим необходимые пакеты:

npm install prom-client @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/instrumentation-http @opentelemetry/instrumentation-express

Создадим файл metrics.ts для регистрации метрик:

import client from 'prom-client';

const collectDefaultMetrics = client.collectDefaultMetrics;
collectDefaultMetrics({ timeout: 5000 });

export const httpRequestDuration = new client.Histogram({
    name: 'http_request_duration_seconds',
    help: 'Duration of HTTP requests in seconds',
    labelNames: ['method', 'route', 'status_code'],
    buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5],
});

export const errorCounter = new client.Counter({
    name: 'http_errors_total',
    help: 'Total number of HTTP errors',
    labelNames: ['method', 'route', 'status_code'],
});

Теперь интегрируем метрики в middleware:

import { Request, Response, NextFunction } from 'express';

export function metricsMiddleware(req: Request, res: Response, next: NextFunction) {
    const end = httpRequestDuration.startTimer();
    res.on('finish', () => {
        end({ method: req.method, route: req.route?.path || 'unknown', status_code: res.statusCode.toString() });
        if (res.statusCode >= 500) {
            errorCounter.inc({ method: req.method, route: req.route?.path || 'unknown', status_code: res.statusCode.toString() });
        }
    });
    next();
}

Добавим эндпоинт для сбора метрик Prometheus:

import { Router } from 'express';
import client from 'prom-client';

const router = Router();
router.get('/metrics', async (req, res) => {
    res.set('Content-Type', client.register.contentType);
    res.end(await client.register.metrics());
});
export default router;

Для клиентских приложений (React) используем @opentelemetry/instrumentation-document-load для автоматического сбора Web Vitals.

3. Настройка продвинутых алертов

Алерты должны быть умными, чтобы не генерировать шум. Рассмотрим типовые сценарии.

Правило 1: Алерт на высокую латентность (p99 > 1 секунды в течение 5 минут):

- alert: HighLatencyP99
  expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 1
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "P99 latency is above 1s for 5 minutes"

Правило 2: Алерт на резкий рост ошибок (5xx errors rate > 1% от общего трафика):

- alert: HighErrorRate
  expr: (sum(rate(http_errors_total{status_code=~"5.."}[5m])) / sum(rate(http_request_duration_seconds_count[5m]))) > 0.01
  for: 2m
  labels:
    severity: warning
  annotations:
    summary: "Error rate is above 1%"

Правило 3: Алерт на отсутствие данных (dead man's switch):

- alert: NoMetrics
  expr: absent(up{job="typescript-app"}) == 1
  for: 1m
  labels:
    severity: critical
  annotations:
    summary: "No metrics received from TypeScript app"

Для бизнесовых алертов используйте синтетические мониторинги (например, проверка, что количество заказов в минуту не упало ниже порога).

4. Интеграция с Sentry и Grafana

Prometheus отлично хранит метрики, но для трейсинга и логов нужны другие инструменты. Sentry — идеальный выбор для отслеживания ошибок в TypeScript.

Подключение Sentry к Express:

import * as Sentry from '@sentry/node';
import { ProfilingIntegration } from '@sentry/profiling-node';

Sentry.init({
    dsn: process.env.SENTRY_DSN,
    integrations: [new ProfilingIntegration()],
    tracesSampleRate: 1.0,
    profilesSampleRate: 1.0,
});
app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());

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

  • График RPS по маршрутам (rate).
  • Тепловая кар

Блоги

Рекомендаций по книгам