# 指标过滤和路径规范化 ## 变更说明 本次修改优化了 HTTP 请求指标的记录逻辑,主要包括两个方面: ### 1. 跳过健康检查端点 以下端点不再记录到 Prometheus 指标中: - `/metrics` - 指标端点本身 - `/healthz` - 存活检查 - `/readyz` - 就绪检查 **原因**:这些端点通常被频繁调用(如 Kubernetes 健康检查、Prometheus 抓取),但对业务监控意义不大,会产生大量噪音数据。 ### 2. 路径参数规范化 带有路径参数的端点会被规范化为模板形式: | 原始路径 | 规范化后 | |---------|---------| | `GET /jobs/a1b2c3d4e5f6` | `GET /jobs/{job_id}` | | `GET /jobs/xyz123456789` | `GET /jobs/{job_id}` | **原因**:避免因为不同的路径参数值产生过多的指标标签,导致指标基数爆炸(cardinality explosion),影响 Prometheus 性能。 ## 实现细节 ### 代码修改 **文件:`src/functional_scaffold/main.py`** 1. 添加 `normalize_path()` 函数: ```python def normalize_path(path: str) -> str: """规范化路径,将路径参数替换为模板形式""" if path.startswith("/jobs/") and len(path) > 6: return "/jobs/{job_id}" return path ``` 2. 修改 `track_metrics` 中间件: ```python # 跳过不需要记录指标的端点 skip_paths = {"/metrics", "/readyz", "/healthz"} if request.url.path in skip_paths: return await call_next(request) # 使用规范化后的路径记录指标 normalized_path = normalize_path(request.url.path) incr("http_requests_total", {"method": request.method, "endpoint": normalized_path, "status": status}) ``` ### 测试覆盖 **文件:`tests/test_middleware.py`** 新增 6 个测试用例: - `test_normalize_jobs_path` - 测试任务路径规范化 - `test_normalize_other_paths` - 测试其他路径保持不变 - `test_normalize_jobs_root` - 测试 /jobs 根路径 - `test_skip_health_endpoints` - 测试跳过健康检查端点 - `test_record_normal_endpoints` - 测试记录普通端点 - `test_normalize_job_path` - 测试规范化任务路径的集成测试 所有测试通过:✅ 56/56 passed ## 验证方法 ### 手动测试 使用提供的测试脚本: ```bash ./scripts/test_metrics_filtering.sh ``` ### 预期结果 访问 `/metrics` 端点后,应该看到: ✅ **应该出现的指标:** ``` http_requests_total{method="POST",endpoint="/invoke",status="success"} 1 http_requests_total{method="GET",endpoint="/jobs/{job_id}",status="error"} 2 ``` ❌ **不应该出现的指标:** ``` http_requests_total{method="GET",endpoint="/healthz",...} http_requests_total{method="GET",endpoint="/readyz",...} http_requests_total{method="GET",endpoint="/metrics",...} http_requests_total{method="GET",endpoint="/jobs/a1b2c3d4e5f6",...} ``` ## 扩展性 如果需要添加更多路径规范化规则,只需修改 `normalize_path()` 函数: ```python def normalize_path(path: str) -> str: """规范化路径,将路径参数替换为模板形式""" # 任务路径 if path.startswith("/jobs/") and len(path) > 6: return "/jobs/{job_id}" # 用户路径(示例) if path.startswith("/users/") and len(path) > 7: return "/users/{user_id}" # 其他路径保持不变 return path ``` ## 影响范围 - ✅ 不影响现有功能 - ✅ 不影响 API 行为 - ✅ 仅影响指标记录逻辑 - ✅ 向后兼容 - ✅ 所有测试通过 ## 相关文档 - [监控指南](../docs/monitoring.md) - 已更新指标说明 - [测试脚本](../scripts/test_metrics_filtering.sh) - 手动验证脚本