TypeScript 应用监控:从指标到智能告警
在现代开发中,编写代码只是工作的一半。关键是要了解应用程序在生产环境中的表现。对于 TypeScript 项目,无论是 Node.js 服务器还是 React 客户端,主动监控已成为一项强制性要求。在本文中,我们将深入探讨收集指标、配置告警以及构建可观测性系统的高级技术,让您高枕无忧。
1. TypeScript 应用的关键指标
在配置告警之前,需要明确我们要测量什么。我们将指标分为三类:基础设施指标、业务指标和用户指标。
基础设施指标(RED 方法论):
- Rate — 每秒请求数 (RPS)。
- Errors — 错误百分比(5xx、4xx、未处理的拒绝)。
- Duration — 响应时间(p50、p95、p99)。
业务指标:
- 成功交易数量。
- 关键操作执行时间(例如,生成报告)。
- 活跃用户数 (DAU/MAU)。
用户指标(针对客户端应用):
- LCP (Largest Contentful Paint) — 主要内容加载速度。
- FID (First Input Delay) — 首次交互延迟。
- CLS (Cumulative Layout Shift) — 视觉布局稳定性。
为了在 TypeScript 中收集这些指标,我们将使用 prom-client 库(用于 Node.js)和 @opentelemetry/instrumentation-http。
2. 使用 Prometheus 和 OpenTelemetry 收集指标
我们来看一个为 TypeScript 的 Express 应用配置指标的示例。安装必要的包:
npm install prom-client @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/instrumentation-http @opentelemetry/instrumentation-express创建 metrics.ts 文件用于注册指标:
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'],});现在将指标集成到中间件中:
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();}添加用于 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;对于客户端应用(React),我们使用 @opentelemetry/instrumentation-document-load 自动收集 Web Vitals。
3. 配置高级告警
告警应该是智能的,以避免产生