Библиотека prom-client: Мониторинг Node.js приложений с Prometheus
В современной веб-разработке мониторинг производительности и состояния приложений стал необходимостью. Одним из самых популярных решений для сбора и анализа метрик является Prometheus — система с открытым исходным кодом, которая собирает данные в виде временных рядов. Для интеграции с Node.js существует официальная библиотека prom-client, которая позволяет легко экспортировать метрики в формате, понятном Prometheus.
В этой статье мы подробно разберём, как установить и использовать prom-client, какие типы метрик доступны, и как интегрировать их с веб-фреймворком Express.
Установка и подключение
Для начала установите библиотеку через npm:
npm install prom-client
После установки импортируйте её в ваше приложение:
const prometheus = require('prom-client');
const express = require('express');
const app = express();
Основные типы метрик
Библиотека prom-client поддерживает четыре основных типа метрик Prometheus:
- Counter — счётчик, который только увеличивается (например, количество запросов).
- Gauge — значение, которое может как увеличиваться, так и уменьшаться (например, количество активных соединений).
- Histogram — гистограмма, измеряющая распределение значений (например, время ответа).
- Summary — суммарная статистика, похожая на Histogram, но с более точными квантилями.
Пример: Counter (счётчик запросов)
Создадим счётчик для отслеживания общего количества HTTP-запросов:
const httpRequestsTotal = new prometheus.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status']
});
// Middleware для подсчёта запросов
app.use((req, res, next) => {
res.on('finish', () => {
httpRequestsTotal.inc({
method: req.method,
route: req.path,
status: res.statusCode
});
});
next();
});
Пример: Gauge (активные соединения)
Gauge удобен для отслеживания текущего состояния, например, количества активных пользователей:
const activeUsers = new prometheus.Gauge({
name: 'active_users',
help: 'Number of active users'
});
app.get('/login', (req, res) => {
activeUsers.inc(); // Увеличиваем при входе
res.send('Logged in');
});
app.get('/logout', (req, res) => {
activeUsers.dec(); // Уменьшаем при выходе
res.send('Logged out');
});
Пример: Histogram (время ответа)
Histogram позволяет измерить, сколько времени занимает обработка запросов:
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] // Границы корзин в секундах
});
app.use((req, res, next) => {
const end = httpRequestDuration.startTimer();
res.on('finish', () => {
end({ method: req.method, route: req.path });
});
next();
});
Экспорт метрик для Prometheus
Чтобы Prometheus мог собирать данные, нужно создать endpoint (обычно /metrics), который возвращает все зарегистрированные метрики:
app.get('/metrics', async (req, res) => {
res.set('Content-Type', prometheus.register.contentType);
res.end(await prometheus.register.metrics());
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Кастомные метрики с лейблами
Вы можете добавлять лейблы (метки) для более детальной фильтрации. Например, разделим метрики по версиям API:
const apiCalls = new prometheus.Counter({
name: 'api_calls_total',
help: 'Total API calls by version',
labelNames: ['api_version']
});
app.get('/api/v1/users', (req, res) => {
apiCalls.inc({ api_version: 'v1' });
res.json({ users: [] });
});
app.get('/api/v2/users', (req, res) => {
apiCalls.inc({ api_version: 'v2' });
res.json({ users: [] });
});
Сброс метрик (для тестов)
Если вы пишете тесты, полезно сбрасывать метрики перед каждым тестом:
beforeEach(() => {
prometheus.register.clear();
});
Интеграция с Express и асинхронные метрики
Иногда нужно собирать метрики из внешних источников (база данных, внешний API). Для этого используйте collect():