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

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

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

Начать курс

Введение: Почему продвинутый мониторинг — необходимость для Node.js

В современной веб-разработке мониторинг вышел за рамки простого логирования ошибок. Для критически важных Node.js приложений — от микросервисов до высоконагруженных API — требуется проактивный сбор метрик, интеллектуальные алерты и визуализация данных. На продвинутом уровне мы говорим не просто о "приложение живо", а о его производительности, узких местах и предсказании сбоев.

В этой статье мы разберём, как построить полноценную систему мониторинга для JavaScript (Node.js) приложения: от сбора кастомных метрик до настройки алертов через Prometheus и Grafana. Вы узнаете, как использовать встроенные возможности Node.js и современные библиотеки для проактивного отслеживания состояния сервиса.

1. Сбор продвинутых метрик: от Event Loop до пользовательских счётчиков

Базовая метрика — это время ответа сервера. Продвинутая — это задержка Event Loop, количество активных дескрипторов и частота сборки мусора. Рассмотрим, как собирать эти данные с помощью process и библиотеки prom-client (клиент для Prometheus).

1.1. Метрики Event Loop и системные ресурсы

Node.js однопоточен, поэтому задержка Event Loop критична. Измеряем её через process.hrtime() и экспортируем как гистограмму.

const client = require('prom-client');
const eventLoopDelay = new client.Histogram({
    name: 'nodejs_event_loop_delay_seconds',
    help: 'Задержка Event Loop в секундах',
    buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1]
});

function measureEventLoop() {
    const start = process.hrtime.bigint();
    setImmediate(() => {
        const duration = Number(process.hrtime.bigint() - start) / 1e9;
        eventLoopDelay.observe(duration);
    });
}
setInterval(measureEventLoop, 5000);

1.2. Пользовательские метрики бизнес-логики

Помимо системных метрик, отслеживайте бизнес-показатели: количество обработанных заказов, ошибки валидации, время выполнения внешних запросов.

const orderCounter = new client.Counter({
    name: 'app_orders_total',
    help: 'Общее количество обработанных заказов',
    labelNames: ['status'] // success, failed
});

// Пример использования в обработчике
app.post('/api/order', async (req, res) => {
    try {
        await processOrder(req.body);
        orderCounter.inc({ status: 'success' });
        res.send('OK');
    } catch (err) {
        orderCounter.inc({ status: 'failed' });
        res.status(500).send('Error');
    }
});

2. Экспорт метрик и интеграция с Prometheus

Чтобы Prometheus мог собирать метрики, нужно создать эндпоинт /metrics. Используем стандартный регистр prom-client.

2.1. Создание эндпоинта для сбора

const express = require('express');
const app = express();
const client = require('prom-client');

// Собираем стандартные метрики Node.js
client.collectDefaultMetrics({ timeout: 5000 });

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

app.listen(3000, () => console.log('Metrics server on :3000'));

2.2. Конфигурация Prometheus

В файле prometheus.yml добавьте цель для вашего приложения:

scrape_configs:
  - job_name: 'nodejs-app'
    static_configs:
      - targets: ['localhost:3000']

После перезапуска Prometheus метрики будут собираться каждые 15 секунд по умолчанию.

3. Настройка алертов: от простых порогов до анализа аномалий

Алерты — это реакция на выход метрик за пределы нормы. На продвинутом уровне мы используем PromQL для сложных условий и настраиваем правила в Alertmanager.

3.1. Базовые правила алертов

Создайте файл alerts.yml:

groups:
  - name: nodejs_alerts
    rules:
      - alert: HighEventLoopLatency
        expr: nodejs_event_loop_delay_seconds{quantile="0.99"} > 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Высокая задержка Event Loop ({{ $value }}s)"

      - alert: HighErrorRate
        expr: rate(app_orders_total{status="failed"}[5m]) / rate(app_orders_total[5m]) > 0.05
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Уровень ошибок выше 5%"

3.2. Продвинутые алерты: предсказание сбоев

Используйте функцию predict_linear для прогнозирования исчерпания ресурсов:

- alert: DiskFullIn4Hours
  expr: predict_linear(node_filesystem_free_bytes{mountpoint="/"}[1h], 4*3600) < 0
  for: 10m
  labels:
    severity: critical
  annotations:
    summary: "Диск заполнится через 4 часа"

4. Визуализация в Grafana и Health Check API

Grafana позволяет строить дашборды в реальном времени. Но для быстрой диагностики полезен эндпоинт /health.

4.1. Кастомный Health Check

const checkDatabase = async () => {
    // Логика проверки БД
    return { status: 'ok', latency: 5 };
};

app.get('/health', async (req, res) => {
    const dbHealth = await checkDatabase();
    const memoryUsage = process.memoryUsage();
    const healthData = {
        status: 'healthy',
        uptime: process.uptime(),
        memory: {
            heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024) + 'MB',
            heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024) + 'MB'
        },
        database: dbHealth
    };
    const isHealthy = dbHealth.status === 'ok';
    res.status(isHealthy ? 200 : 503).json(healthData);
});

4.2. Пример дашборда в Grafana

Подключите Prometheus как источник данных и создайте панели:

  • За

Блоги

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