Мониторинг TypeScript-приложений: инструменты и практики

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

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

Начать курс

Мониторинг приложений TypeScript: от ошибок до производительности

Мониторинг TypeScript-приложений — это комплекс практик и инструментов, обеспечивающих наблюдаемость (observability) системы в реальном времени. В отличие от простого логирования, профессиональный мониторинг включает сбор метрик, трейсинг запросов, агрегацию ошибок и автоматическое оповещение. Для TypeScript, работающего как на сервере (Node.js), так и в браузере, критически важно иметь единую систему наблюдения. В этой статье мы разберём ключевые инструменты и примеры их интеграции.

Зачем мониторить TypeScript-приложения?

TypeScript компилируется в JavaScript, что накладывает особенности на отладку. Исходный код с типами превращается в динамический JS, и ошибки типов могут проявляться только в рантайме. Без мониторинга вы рискуете:

  • Пропустить TypeError или ReferenceError в production
  • Не заметить деградацию производительности (медленные запросы, утечки памяти)
  • Потерять контекст ошибки (стектрейс, пользовательские данные, окружение)

Основные компоненты системы мониторинга

Современный стек мониторинга строится на трёх столпах: логи (logs), метрики (metrics) и трейсы (traces). Для TypeScript-приложений мы рассмотрим конкретные библиотеки:

1. Sentry — король отслеживания ошибок

Sentry — это SaaS-платформа для мониторинга ошибок и производительности. Для TypeScript доступен официальный пакет @sentry/node и @sentry/react. Он автоматически перехватывает исключения, собирает стектрейсы и контекст.

Установка:

npm install @sentry/node @sentry/tracing

Базовая инициализация в Node.js:

import * as Sentry from '@sentry/node';
import { ProfilingIntegration } from '@sentry/profiling-node';

Sentry.init({
  dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
  integrations: [new ProfilingIntegration()],
  tracesSampleRate: 1.0, // частота сбора трейсов (0-1)
  profilesSampleRate: 1.0, // профилирование производительности
});

// Ручной вызов при ошибке
app.get('/api/users', async (req, res) => {
  try {
    const users = await getUsers();
    res.json(users);
  } catch (error) {
    Sentry.captureException(error);
    res.status(500).send('Internal Server Error');
  }
});

Преимущества:

  • Автоматическое связывание ошибок с релизами
  • Поддержка source maps для TypeScript
  • Производительность: мониторинг медленных транзакций

2. OpenTelemetry — стандарт observability

OpenTelemetry (OTel) — это открытый стандарт для сбора телеметрии. Для TypeScript используется пакет @opentelemetry/sdk-node. OTel позволяет собирать трейсы и метрики, а затем отправлять их в любую систему (Jaeger, Prometheus, Datadog).

Пример интеграции с Express:

import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/instrumentation-node';

const sdk = new NodeSDK({
  instrumentations: [getNodeAutoInstrumentations()],
  // экспортёр можно настроить на OTLP или консоль
});

sdk.start();

// Вся логика Express автоматически трейсится
import express from 'express';
const app = express();
app.get('/data', (req, res) => {
  res.json({ status: 'ok' });
});

OpenTelemetry автоматически инструментирует популярные библиотеки: Express, MongoDB, Redis, gRPC. Это даёт полную картину прохождения запроса через сервисы.

3. Prometheus + Grafana — метрики и визуализация

Для сбора метрик (RPS, latency, ошибки) в TypeScript используют библиотеку prom-client. Она предоставляет счётчики, гистограммы и суммарные метрики.

Пример создания метрики:

import client from 'prom-client';

const requestCounter = new client.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status'],
});

app.use((req, res, next) => {
  res.on('finish', () => {
    requestCounter.inc({
      method: req.method,
      route: req.route?.path || 'unknown                    

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