UNPKG

koatty_trace

Version:

Full link tracking and error interception for koatty.

272 lines (212 loc) 7.54 kB
# koatty_trace Full link tracking and error interception for koatty. ## 功能特性 - 🔍 **全链路追踪**: 基于OpenTelemetry的分布式链路追踪 - 📊 **多协议指标收集**: 支持HTTP、WebSocket、gRPC的指标收集并导出到Prometheus - 🚨 **错误拦截**: 统一的错误处理和异常捕获 - 🔗 **服务拓扑**: 自动分析和记录服务依赖关系 - ⚡ **性能监控**: 请求响应时间、错误率等关键指标 - 🔄 **重试机制**: 可配置的请求重试策略 - 🎯 **请求ID追踪**: 全链路请求ID生成和传播 - 🛡️ **并发安全**: 线程安全的指标收集和Span管理 - 🚀 **高性能**: 路径标准化缓存、批量处理、内存优化 ## 安装 ```bash npm install koatty_trace # 或 pnpm add koatty_trace ``` ## 基础使用 ```typescript import { Trace } from 'koatty_trace'; import { Koatty } from 'koatty_core'; const app = new Koatty(); // 基础配置 app.use(Trace({ enableTrace: true, timeout: 10000, requestIdHeaderName: 'X-Request-Id' }, app)); ``` ## 多协议指标收集 ### 配置Prometheus指标导出 ```typescript import { Trace } from 'koatty_trace'; app.use(Trace({ enableTrace: true, // Prometheus指标配置 metricsConf: { metricsEndpoint: '/metrics', // 指标端点路径 metricsPort: 9464, // 指标服务端口 reportInterval: 5000, // 上报间隔(ms) defaultAttributes: { // 默认标签 service: 'my-service', version: '1.0.0' } } }, app)); ``` ### 自动收集的指标 框架会自动收集以下多协议指标,支持HTTP、WebSocket和gRPC: #### 1. 请求总数 (`requests_total`) - **类型**: Counter - **描述**: 所有协议的请求总数统计 - **标签**: - `method`: 请求方法 (GET, POST, PUT, DELETE等) - `status`: 状态码 (HTTP状态码或gRPC状态码) - `path`: 标准化的请求路径 (如 `/users/:id`) - `protocol`: 协议类型 (`http`, `websocket`, `grpc`) - `compression`: 压缩类型 (WebSocket: `deflate`/`none`, gRPC: `gzip`/`brotli`/`none`) - `grpc_service`: gRPC服务名 (仅gRPC协议) #### 2. 错误总数 (`errors_total`) - **类型**: Counter - **描述**: 所有协议的错误请求统计 - **标签**: - `method`: 请求方法 - `status`: 状态码 - `path`: 标准化的请求路径 - `protocol`: 协议类型 - `error_type`: 错误类型 - HTTP/WebSocket: `client_error` (4xx), `server_error` (5xx) - gRPC: `grpc_error` (非0状态码) #### 3. 响应时间 (`response_time_seconds`) - **类型**: Histogram - **描述**: 所有协议的请求响应时间分布 - **单位**: 秒 - **桶边界**: [0.1, 0.5, 1, 2.5, 5, 10] - **标签**: - `method`: 请求方法 - `status`: 状态码 - `path`: 标准化的请求路径 - `protocol`: 协议类型 #### 4. WebSocket连接总数 (`websocket_connections_total`) - **类型**: Counter - **描述**: WebSocket连接统计 - **标签**: - `protocol`: 协议类型 (websocket) - `service`: 服务名称 ### 协议检测 框架会自动检测请求协议类型: ```typescript // HTTP请求 GET /api/users HTTP/1.1 -> protocol: "http" // WebSocket连接 GET /ws HTTP/1.1 Upgrade: websocket -> protocol: "websocket" // gRPC请求 POST /package.UserService/GetUser HTTP/2 Content-Type: application/grpc -> protocol: "grpc" ``` ### 路径标准化 为了减少指标的基数,框架会自动标准化请求路径: ```typescript // 原始路径 -> 标准化路径 '/users/123' -> '/users/:id' '/users/123/profile' -> '/users/:id/profile' '/api/v1/users/550e8400-e29b-41d4-a716-446655440000' -> '/api/v1/users/:uuid' '/posts/507f1f77bcf86cd799439011' -> '/posts/:objectid' // gRPC服务路径 '/package.UserService/GetUser' -> '/package.UserService/GetUser' (保持原样) ``` ### 查看指标 启动应用后,可以通过以下方式查看指标: ```bash # 访问指标端点 curl http://localhost:9464· # 示例输出 # HELP requests_total Total requests across all protocols # TYPE requests_total counter requests_total{method="GET",status="200",path="/api/users",protocol="http"} 42 requests_total{method="POST",status="0",path="/package.UserService/GetUser",protocol="grpc",grpc_service="package.UserService",compression="gzip"} 15 requests_total{method="GET",status="101",path="/ws",protocol="websocket",compression="deflate"} 8 # HELP response_time_seconds Response time in seconds across all protocols # TYPE response_time_seconds histogram response_time_seconds_bucket{method="GET",status="200",path="/api/users",protocol="http",le="0.1"} 35 response_time_seconds_bucket{method="POST",status="0",path="/package.UserService/GetUser",protocol="grpc",le="0.1"} 12 # HELP websocket_connections_total Total WebSocket connections # TYPE websocket_connections_total counter websocket_connections_total{protocol="websocket",service="my-service"} 5 ``` ## 完整配置选项 ```typescript app.use(Trace({ // 基础配置 enableTrace: true, // 是否启用链路追踪 timeout: 10000, // 请求超时时间(ms) encoding: 'utf-8', // 响应编码 requestIdHeaderName: 'X-Request-Id', // 请求ID头名称 requestIdName: 'requestId', // 请求ID属性名 asyncHooks: false, // 是否启用异步钩子 // 指标配置 metricsConf: { metricsEndpoint: '/metrics', // Prometheus指标端点 metricsPort: 9464, // 指标服务端口 reportInterval: 5000, // 上报间隔(ms) defaultAttributes: {}, // 默认指标标签 reporter: (metrics) => { // 自定义指标上报器 console.log('Metrics:', metrics); } }, // OpenTelemetry配置 opentelemetryConf: { endpoint: "http://localhost:4318/v1/traces", // OTLP端点 enableTopology: false, // 是否启用拓扑分析 headers: {}, // OTLP请求头 resourceAttributes: {}, // 资源属性 samplingRate: 1.0, // 采样率 timeout: 10000, // 导出超时时间 spanTimeout: 30000, // Span超时时间 maxActiveSpans: 1000, // 最大活跃Span数 }, // 重试配置 retryConf: { enabled: false, // 是否启用重试 count: 3, // 最大重试次数 interval: 1000, // 重试间隔(ms) conditions: (error) => true // 重试条件判断函数 } }, app)); ``` ## 与Prometheus集成 ### 1. Prometheus配置 在`prometheus.yml`中添加抓取配置: ```yaml scrape_configs: - job_name: 'koatty-app' static_configs: - targets: ['localhost:9464'] scrape_interval: 15s metrics_path: /metrics ``` ### 2. Grafana仪表板 推荐的Grafana查询示例: ```promql # 请求QPS rate(http_requests_total[5m]) # 错误率 rate(http_errors_total[5m]) / rate(http_requests_total[5m]) # 平均响应时间 rate(http_response_time_seconds_sum[5m]) / rate(http_response_time_seconds_count[5m]) # P95响应时间 histogram_quantile(0.95, rate(http_response_time_seconds_bucket[5m])) ``` ## 开发和测试 ```bash # 安装依赖 pnpm install # 运行测试 pnpm test # 运行指标收集测试 pnpm test test/metrics.test.ts # 代码检查 pnpm run eslint # 构建项目 pnpm run build ``` ## 许可证 BSD-3-Clause License ## 贡献 欢迎提交Issue和Pull Request来改进这个项目。