Мониторинг JavaScript приложений: метрики и алерты от А до Я
В современном мире разработки недостаточно просто написать работающий код. Критически важно понимать, как ведет себя ваше приложение в production-среде. Мониторинг JavaScript приложений (особенно на Node.js) — это не просто тренд, а необходимость. Он позволяет выявлять узкие места, предотвращать сбои и обеспечивать высокую доступность сервисов. В этой статье мы разберем полный цикл: от сбора ключевых метрик до настройки алертов, используя современный стек инструментов.
Почему мониторинг Node.js важен?
Node.js приложения часто работают в асинхронном режиме, обрабатывая тысячи запросов в секунду. Без мониторинга вы рискуете:
- Пропустить утечку памяти (memory leak), которая приведет к падению сервера.
- Не заметить рост времени ответа (latency), что ухудшит пользовательский опыт.
- Потерять данные из-за необработанных ошибок.
Система мониторинга дает вам visibility (наблюдаемость) и позволяет принимать решения на основе данных, а не догадок.
Ключевые метрики для JavaScript приложений
Все метрики можно разделить на три группы: инфраструктурные, бизнес-метрики и метрики приложения. Рассмотрим их подробнее.
1. Инфраструктурные метрики (USE-метод)
Это базовые показатели здоровья сервера: CPU, память, диск, сеть. Для Node.js особенно важна память (heap, non-heap) и количество открытых файловых дескрипторов.
2. Метрики приложения (RED-метод)
Метод RED (Rate, Errors, Duration) — золотой стандарт для микросервисов:
- Rate (Скорость): количество запросов в секунду (RPS).
- Errors (Ошибки): процент запросов, завершившихся ошибкой (4xx, 5xx).
- Duration (Длительность): время выполнения запроса (p50, p95, p99 перцентили).
3. Бизнес-метрики
Специфичные для вашего продукта: количество зарегистрированных пользователей, завершенных заказов, активных сессий и т.д.
Сбор метрик с Prometheus и Node.js
Prometheus — стандарт де-факто для сбора метрик. Для Node.js используем библиотеку prom-client. Рассмотрим пример настройки.
Установка и базовая настройка
npm install prom-client express
Создадим сервер с эндпоинтом /metrics:
const express = require('express');
const client = require('prom-client');
const app = express();
const port = 3000;
// Создаем регистр метрик
const register = new client.Registry();
// Добавляем стандартные метрики Node.js
client.collectDefaultMetrics({ register });
// Создаем кастомную гистограмму для времени ответа
const httpRequestDuration = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status'],
buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5]
});
register.registerMetric(httpRequestDuration);
// Middleware для измерения времени
app.use((req, res, next) => {
const end = httpRequestDuration.startTimer();
res.on('finish', () => {
end({ method: req.method, route: req.route?.path || 'unknown', status: res.statusCode });
});
next();
});
// Эндпоинт для метрик
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
app.get('/', (req, res) => {
res.send('Hello, monitoring!');
});
app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
Кастомные счетчики
Добавим счетчик ошибок:
const errorCounter = new client.Counter({
name: 'app_errors_total',
help: 'Total number of application errors',
labelNames: ['type']
});
register.registerMetric(errorCounter);
// Пример использования в обработчике
app.get('/error', (req, res) => {
try {
throw new Error('Test error');
} catch (e) {
errorCounter.inc({ type: 'test' });
res.status(500).send('Error occurred');
}
});
Настройка алертов: от теории к практике
Собирать метрики мало. Нужно настроить алерты, чтобы система сама сообщала о проблемах. Рассмотрим настройку на базе Prometheus и Alertmanager.
Правила алертов (Prometheus Rules)
Создайте файл alerts.yml:
groups:
- name: nodejs_alerts
rules:
- alert: HighErrorRate
expr: rate(app_errors_total[5m]) > 0.1
for: 1m
labels:
severity: critical
annotations:
summary: "High error rate detected"
description: "Error rate is {{ $value }} errors/sec for the last 5 minutes."
- alert: HighLatency
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 2
for: 2m
labels:
severity: warning
annotations:
summary: "High latency detected"
description: "P95 latency is {{ $value }} seconds."
Интеграция с Alertmanager
Alertmanager обрабатывает оповещения и отправляет их в Slack, Telegram, Email и т.д. Пример конфигурации для Telegram:
route:
receiver: 'telegram'
group_by: ['alertname']
group_wait: 30s
receivers:
- name: 'telegram'
telegram_configs:
- bot_token: 'YOUR_BOT_TOKEN'
chat_id: YOUR_CHAT_ID
send_resolved: true
Визуализация с Grafana
Grafana — лучший инструмент для создания дашбордов. Подключите ваш Prometheus как источник данных и создайте панели:
- Общий обзор: RPS, latency (p50/p95/p99), error rate.
- Память: heap used, heap total, external memory.
- <