Monitoramento de aplicações TypeScript: das métricas aos alertas inteligentes
No desenvolvimento moderno, escrever código é apenas metade do trabalho. É crucial entender como a aplicação se comporta em produção. Para projetos TypeScript, seja um servidor Node.js ou um cliente React, o monitoramento proativo torna-se um requisito obrigatório. Neste artigo, abordaremos técnicas avançadas de coleta de métricas, configuração de alertas e construção de um sistema de observabilidade que permitirá que você durma tranquilo.
1. Métricas-chave para aplicações TypeScript
Antes de configurar alertas, precisamos definir o que exatamente estamos medindo. Vamos dividir as métricas em três grupos: infraestrutura, negócios e usuário.
Métricas de infraestrutura (metodologia RED):
- Rate — número de requisições por segundo (RPS).
- Errors — porcentagem de erros (5xx, 4xx, rejeições não tratadas).
- Duration — tempo de resposta (p50, p95, p99).
Métricas de negócio:
- Número de transações bem-sucedidas.
- Tempo de execução de operações críticas (por exemplo, geração de relatório).
- Usuários ativos (DAU/MAU).
Métricas do usuário (para aplicações cliente):
- LCP (Largest Contentful Paint) — velocidade de carregamento do conteúdo principal.
- FID (First Input Delay) — atraso da primeira interação.
- CLS (Cumulative Layout Shift) — estabilidade do layout visual.
Para coletar essas métricas em TypeScript, usaremos a biblioteca prom-client (para Node.js) e @opentelemetry/instrumentation-http.
2. Coleta de métricas com Prometheus e OpenTelemetry
Vamos ver um exemplo de configuração de métricas para uma aplicação Express em TypeScript. Instale os pacotes necessários:
npm install prom-client @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/instrumentation-http @opentelemetry/instrumentation-expressCrie o arquivo metrics.ts para registrar as métricas:
import client from 'prom-client';
const collectDefaultMetrics = client.collectDefaultMetrics;collectDefaultMetrics({ timeout: 5000 });
export const httpRequestDuration = new client.Histogram({ name: 'http_request_duration_seconds', help: 'Duration of HTTP requests in seconds', labelNames: ['method', 'route', 'status_code'], buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5],});
export const errorCounter = new client.Counter({ name: 'http_errors_total', help: 'Total number of HTTP errors', labelNames: ['method', 'route', 'status_code'],});Agora, integre as métricas no middleware:
import { Request, Response, NextFunction } from 'express';
export function metricsMiddleware(req: Request, res: Response, next: NextFunction) { const end = httpRequestDuration.startTimer(); res.on('finish', () => { end({ method: req.method, route: req.route?.path || 'unknown', status_code: res.statusCode.toString() }); if (res.statusCode >= 500) { errorCounter.inc({ method: req.method, route: req.route?.path || 'unknown', status_code: res.statusCode.toString() }); } }); next();}Adicione um endpoint para a coleta de métricas do Prometheus:
import { Router } from 'express';import client from 'prom-client';
const router = Router();router.get('/metrics', async (req, res) => { res.set('Content-Type', client.register.contentType); res.end(await client.register.metrics());});export default router;Para aplicações cliente (React), use @opentelemetry/instrumentation-document-load para coleta automática de Web Vitals.
3. Configuração de alertas avançados
Os alertas devem ser inteligentes para não gerar