Антон Ларичев

Введение
Мониторинг Node.js приложения с помощью Prometheus и Grafana позволяет видеть, что происходит с сервисом в реальном времени: от потребления памяти до времени ответа API. Без мониторинга вы узнаете о проблемах только тогда, когда пользователи начнут жаловаться, а с правильно настроенной связкой Prometheus + Grafana для Node.js вы увидите деградацию производительности задолго до того, как она станет критичной.
В этом руководстве мы за час поднимем полноценный мониторинг Node.js приложения: подключим библиотеку prom-client для сбора метрик, настроим Prometheus для их хранения и создадим наглядный дашборд в Grafana. Всё это завернём в Docker Compose, чтобы развернуть одной командой.
Как работает связка Prometheus и Grafana
Prometheus использует pull-модель сбора метрик: он сам ходит к вашему приложению по HTTP и забирает данные с эндпоинта /metrics. Это принципиально отличается от push-модели, где приложение само отправляет метрики в систему мониторинга.
Архитектура выглядит так:
Node.js приложение (/metrics) → Prometheus (сбор и хранение) → Grafana (визуализация)
Prometheus хранит данные как time-series — временные ряды с метками. Каждая метрика имеет имя, набор лейблов и значение с таймстампом. Grafana подключается к Prometheus как к источнику данных и строит графики на основе запросов на языке PromQL.
Подключение prom-client к Node.js приложению
Библиотека prom-client — официальный клиент Prometheus для Node.js. Установим её и настроим базовый сбор метрик:
npm install prom-client express
Создадим приложение с эндпоинтом для метрик:
import express from 'express';
import { collectDefaultMetrics, Registry, Counter, Histogram } from 'prom-client';
const app = express();
const register = new Registry();
// Собираем стандартные метрики Node.js (CPU, память, event loop)
collectDefaultMetrics({ register });
// Счётчик HTTP-запросов
const httpRequestsTotal = new Counter({
name: 'http_requests_total',
help: 'Общее количество HTTP-запросов',
labelNames: ['method', 'route', 'status_code'],
registers: [register],
});
// Гистограмма времени ответа
const httpRequestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'Время обработки HTTP-запроса в секундах',
labelNames: ['method', 'route'],
buckets: [0.01, 0.05, 0.1, 0.5, 1, 5],
registers: [register],
});
// Middleware для сбора метрик
app.use((req, res, next) => {
const end = httpRequestDuration.startTimer({ method: req.method, route: req.path });
res.on('finish', () => {
httpRequestsTotal.inc({ method: req.method, route: req.path, status_code: res.statusCode });
end();
});
next();
});
// Эндпоинт для Prometheus
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
app.get('/api/users', (req, res) => {
res.json([{ id: 1, name: 'Anton' }]);
});
app.listen(3000, () => console.log('Сервер запущен на порту 3000'));
Библиотека prom-client по умолчанию собирает около 30 метрик Node.js: использование памяти heap, длительность garbage collection, задержку event loop и количество активных хэндлов.
Какие типы метрик использовать в Node.js
Prometheus поддерживает четыре типа метрик, и важно выбрать правильный:
- Counter — монотонно растущее значение. Подходит для подсчёта запросов, ошибок, обработанных задач. Никогда не уменьшается, сбрасывается только при перезапуске
- Gauge — значение, которое может расти и падать. Используйте для текущих подключений, размера очереди, температуры CPU
- Histogram — распределение значений по бакетам. Идеален для времени ответа API, размера запроса. Позволяет считать перцентили
- Summary — похож на Histogram, но считает перцентили на стороне клиента. Используется реже из-за ограничений агрегации
Для мониторинга Node.js приложения чаще всего нужны Counter для запросов и ошибок, Histogram для латентности и Gauge для состояния соединений.
Настройка Prometheus и Grafana через Docker Compose
Создадим файл docker-compose.yml, который поднимет всё окружение для мониторинга:
version: '3.8'
services:
app:
build: .
ports:
- '3000:3000'
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- '9090:9090'
grafana:
image: grafana/grafana:latest
ports:
- '3001:3000'
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
volumes:
grafana-data:
Конфигурация Prometheus в файле prometheus.yml:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'nodejs-app'
metrics_path: /metrics
static_configs:
- targets: ['app:3000']
Запускаем одной командой:
docker compose up -d
После запуска Prometheus начнёт каждые 15 секунд опрашивать эндпоинт /metrics вашего Node.js приложения и сохранять метрики в свою time-series базу данных.
Как создать дашборд Grafana для Node.js
Откройте Grafana по адресу http://localhost:3001, войдите с логином admin и паролем admin. Далее подключите Prometheus как источник данных:
- Перейдите в Connections > Data Sources > Add data source
- Выберите Prometheus
- В поле URL укажите
http://prometheus:9090 - Нажмите Save & Test
Теперь создайте дашборд с ключевыми панелями. Вот PromQL-запросы для основных графиков:
# Количество запросов в секунду (RPS)
rate(http_requests_total[5m])
# 95-й перцентиль времени ответа
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# Использование памяти heap в мегабайтах
process_resident_memory_bytes / 1024 / 1024
# Процент ошибок (5xx)
rate(http_requests_total{status_code=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100
# Задержка event loop
nodejs_eventloop_lag_seconds
Рекомендую начать с четырёх панелей: RPS, латентность (p95), использование памяти и процент ошибок. Эти четыре графика дают полную картину здоровья вашего Node.js приложения.
Частые ошибки при настройке мониторинга Node.js
Слишком много лейблов. Не используйте динамические значения вроде ID пользователя в лейблах. Каждая уникальная комбинация лейблов создаёт новую time-series, и Prometheus быстро упрётся в лимиты памяти. Путь /api/users/:id должен записываться как /api/users/:id, а не как /api/users/123.
Забыли про метрики по умолчанию. Вызов collectDefaultMetrics() даёт базовые метрики Node.js бесплатно: память, CPU, event loop, GC. Не пренебрегайте ими.
Не настроили алерты. Дашборд без алертов — это красивая картинка, которую никто не смотрит. Настройте алерты в Grafana хотя бы на процент ошибок выше 1% и латентность p95 выше 2 секунд.
Интервал scrape слишком частый. Значение 5 секунд создаёт ненужную нагрузку. Для большинства приложений 15-30 секунд — оптимальный интервал сбора метрик Prometheus.
Заключение
Мониторинг Node.js приложения через Prometheus и Grafana настраивается за час, а пользу приносит годами. Мы подключили prom-client для сбора метрик, настроили Prometheus для их хранения и создали дашборд в Grafana для визуализации. Весь стек поднимается через Docker Compose одной командой.
Следующие шаги: добавьте кастомные бизнес-метрики (количество регистраций, оплат, ошибок интеграций), настройте алерты в Grafana и подключите Alertmanager для уведомлений в Telegram или Slack. Мониторинг — это не разовая настройка, а процесс, который развивается вместе с вашим приложением.






Комментарии
0