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

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

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

Начать курс

Мониторинг JavaScript приложений: метрики и алерты (продвинутый уровень)

Современные JavaScript-приложения на Node.js становятся всё сложнее: это микросервисы, event-driven архитектуры, real-time системы. Простой мониторинг "жив/не жив" уже не даёт полной картины. Для обеспечения стабильности и высокой производительности требуется продвинутый подход: сбор бизнес-метрик, анализ latency, настройка умных алертов и observability. В этой статье мы разберём, как выстроить систему мониторинга на продвинутом уровне с использованием Node.js, Prometheus и Grafana.

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

Мониторинг начинается с правильного выбора метрик. Для production-среды критичны три группы:

  • RED-метрики (Rate, Errors, Duration) — частота запросов, количество ошибок, время ответа.
  • USE-метрики (Utilization, Saturation, Errors) — загрузка CPU, использование памяти, количество открытых файловых дескрипторов.
  • Бизнес-метрики — количество активных пользователей, размер очереди задач, скорость обработки событий.

Пример сбора метрик с помощью библиотеки prom-client:

const client = require('prom-client');
const httpRequestDuration = new client.Histogram({
    name: 'http_request_duration_seconds',
    help: 'Duration of HTTP requests in seconds',
    labelNames: ['method', 'route', 'status_code'],
    buckets: [0.1, 0.3, 0.5, 1, 3, 5]
});

app.use((req, res, next) => {
    const end = httpRequestDuration.startTimer();
    res.on('finish', () => {
        end({ method: req.method, route: req.route?.path || 'unknown', status_code: res.statusCode });
    });
    next();
});

Также обязательно мониторить garbage collection (GC) и event loop lag — это поможет выявить проблемы с производительностью до того, как они станут критическими.

2. Настройка алертов: от простого к умному

Алерты — это не просто уведомления о падении сервера. На продвинутом уровне алерты должны быть:

  • Контекстными — учитывать время суток, день недели, бизнес-циклы.
  • Многоуровневыми — Warning, Critical, Pager.
  • Предиктивными — на основе трендов (например, рост latency на 20% за 15 минут).

Пример правила для Prometheus Alertmanager с использованием прогнозирования:

groups:
  - name: nodejs_alerts
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_errors_total[5m]) / rate(http_requests_total[5m]) > 0.05
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Высокий процент ошибок ({{ $value | humanizePercentage }})"
          description: "Более 5% запросов возвращают ошибки за последние 2 минуты."

      - alert: MemoryLeak
        expr: predict_linear(nodejs_heap_bytes_used{space="total"}[30m], 3600) > 1e9
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Прогнозируемая утечка памяти"
          description: "Использование heap может превысить 1GB через час."

Важно настроить дедупликацию и группировку алертов, чтобы не завалить дежурного инженера сотнями однотипных сообщений. Используйте group_wait и group_interval в конфигурации Alertmanager.

3. Продвинутое логирование: структурированные логи и трассировка

Стандартный console.log не подходит для production. Используйте структурированное логирование с библиотеками pino или winston в формате JSON. Это позволяет легко парсить логи и интегрировать их с системами агрегации (ELK, Loki).

Пример настройки pino:

const pino = require('pino');
const logger = pino({
    level: process.env.LOG_LEVEL || 'info',
    formatters: {
        level: (label) => ({ level: label.toUpperCase() })
    },
    serializers: {
        req: pino.stdSerializers.req,
        res: pino.stdSerializers.res,
        err: pino.stdSerializers.err
    }
});

app.use((req, res, next) => {
    req.log = logger.child({ requestId: req.id });
    req.log.info({ url: req.url, method: req.method }, 'Incoming request');
    next();
});

Для распределённых систем обязательна распределённая трассировка (distributed tracing). Используйте OpenTelemetry SDK для Node.js. Это позволит отслеживать путь запроса через несколько микросервисов:

const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');

const provider = new NodeTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new JaegerExporter({
    endpoint: 'http://jaeger:14268/api/traces'
})));
provider.register();

4. Интеграция с Grafana: дашборды и аннотации

Grafana — стандарт де-факто для визуализации метрик. На продвинутом уровне стоит использовать:

  • Template variables — для фильтрации по сервисам, версиям, окружениям.
  • Annotations — для отображения событий (релизы, деплои, инциденты) прямо на графиках.
  • Alerting в Grafana — как альтернатива или дополнение к Alertmanager, с поддержкой ML-моделей.

Пример запроса для дашборда, показывающего 95-й перцентиль времени ответа:

histogram_quantile(0.95,
    sum(rate(http_request_duration_seconds_bucket[5m])) by (le, route)
)

Не забудьте добавить дашборд для Node.js runtime метрик: event loop lag, heap size, количество активных handles. Это поможет быстро диагностировать проблемы "узкого горла".

Заключение

Продвинутый мониторинг JavaScript-приложений на Node.js — это не просто набор инструментов, а целая культура. Выстроив правильный сбор метрик, настроив умные алерты и внедрив распределён

Блоги

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