Мониторинг Node.js: инструменты и библиотеки для отслеживания производительности

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

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

Начать курс

Мониторинг приложений JavaScript (Node.js): полный обзор инструментов и практик

Разработка на Node.js — это мощно, но без правильного мониторинга ваше приложение может превратиться в «чёрный ящик». В этой статье мы разберём ключевые инструменты и библиотеки, которые помогут вам отслеживать состояние серверных JavaScript-приложений, выявлять узкие места и предотвращать сбои.

Зачем нужен мониторинг Node.js?

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

  • Пропустить утечку памяти — GC не справляется, приложение падает.
  • Не заметить рост времени ответа — пользователи уходят.
  • Потерять контроль над ошибками — необработанные rejections убивают процесс.

1. Встроенные средства Node.js

Начнём с того, что уже есть в ядре. Node.js предоставляет модуль process и perf_hooks для базового сбора метрик.

// Пример: сбор метрик памяти и времени ответа
const { performance, PerformanceObserver } = require('perf_hooks');

// Мониторинг Event Loop
const obs = new PerformanceObserver((items) => {
  const entry = items.getEntries()[0];
  console.log(`Задержка Event Loop: ${entry.duration}ms`);
});
obs.observe({ entryTypes: ['function'] });

// Замер времени выполнения функции
performance.mark('start');
// ... ваш код ...
performance.mark('end');
performance.measure('myFunction', 'start', 'end');

// Мониторинг памяти
setInterval(() => {
  const memory = process.memoryUsage();
  console.log(`RSS: ${memory.rss}, Heap: ${memory.heapUsed}`);
}, 5000);

2. PM2 — менеджер процессов с мониторингом

PM2 — стандарт де-факто для production Node.js. Он не только управляет процессами, но и предоставляет встроенный мониторинг через команду pm2 monit.

  • Автоматический перезапуск при падении процесса.
  • Сбор метрик: CPU, память, количество запросов.
  • Логирование stdout/stderr.
  • Cluster mode для максимальной загрузки ядер.
// Установка и запуск
npm install pm2 -g
pm2 start app.js --name "my-app" --instances max

// Встроенный мониторинг
pm2 monit

// Экспорт метрик в JSON
pm2 jlist > metrics.json

Для продвинутого мониторинга используйте pm2-metrics — плагин, который отправляет данные в Prometheus.

3. Clinic.js — диагностика производительности

Clinic.js — набор инструментов от NearForm для профилирования Node.js. Включает три утилиты:

  • Clinic Doctor — общая диагностика (Event Loop, GC, I/O).
  • Clinic Bubbleprof — анализ асинхронных операций.
  • Clinic Flame — флейм-графы для поиска горячих функций.
// Установка
npm install -g clinic

// Запуск с нагрузочным тестированием
clinic doctor -- node app.js

// Затем в другом терминале:
autocannon localhost:3000

// После остановки откроется HTML-отчёт с визуализацией

Clinic.js особенно полезен для выявления проблем с Event Loop (высокая задержка, частые GC-паузы).

4. Prometheus + Node.js — кастомные метрики

Prometheus — стандарт сбора метрик в микросервисной архитектуре. Для Node.js используйте библиотеку prom-client.

const prometheus = require('prom-client');

// Создаём счётчик запросов
const httpRequestsTotal = new prometheus.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status']
});

// Гистограмма времени ответа
const httpRequestDuration = new prometheus.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in seconds',
  labelNames: ['method', 'route'],
  buckets: [0.1, 0.5, 1, 2, 5]
});

// Middleware для Express
app.use((req, res, next) => {
  const end = httpRequestDuration.startTimer();
  res.on('finish', () => {
    httpRequestsTotal.inc({
      method: req.method,
      route: req.route?.path || 'unknown',
      status: res.statusCode
    });
    end({ method: req.method, route: req.route?.path || 'unknown' });
  });
  next();
});

// Endpoint для Prometheus
app.get('/metrics', async (req,                    

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