main:添加核心文件并初始化项目
新增内容: - 创建基础项目结构。 - 添加 `.gitignore` 和 `.dockerignore` 文件。 - 编写 `pyproject.toml` 和依赖文件。 - 添加算法模块及示例算法。 - 实现核心功能模块(日志、错误处理、指标)。 - 添加开发和运行所需的相关脚本文件及文档。
This commit is contained in:
227
docs/metrics-improvement-summary.md
Normal file
227
docs/metrics-improvement-summary.md
Normal file
@@ -0,0 +1,227 @@
|
||||
# Prometheus 指标记录问题修复总结
|
||||
|
||||
## 问题描述
|
||||
|
||||
Prometheus 中没有正常记录应用的访问数据。虽然 `/metrics` 端点可以访问,并且定义了所有指标类型,但这些指标都没有任何数据值。
|
||||
|
||||
## 根本原因
|
||||
|
||||
1. **HTTP 请求指标未记录**:`api/routes.py` 中的路由处理函数没有使用 `@track_request` 装饰器来记录 HTTP 请求指标
|
||||
2. **算法执行指标未记录**:`algorithms/base.py` 中的 `execute()` 方法没有调用 metrics 模块来记录算法执行指标
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 1. 添加 HTTP 请求指标跟踪中间件
|
||||
|
||||
**文件**:`src/functional_scaffold/main.py`
|
||||
|
||||
**修改内容**:
|
||||
- 导入 metrics 相关的对象:`request_counter`, `request_latency`, `in_progress_requests`
|
||||
- 添加 `track_metrics` 中间件,自动跟踪所有 HTTP 请求
|
||||
|
||||
**优点**:
|
||||
- 自动化:不需要在每个路由上手动添加装饰器
|
||||
- 统一:所有端点的指标记录逻辑一致
|
||||
- 易维护:新增端点自动获得指标跟踪能力
|
||||
|
||||
**实现代码**:
|
||||
```python
|
||||
@app.middleware("http")
|
||||
async def track_metrics(request: Request, call_next):
|
||||
"""记录所有HTTP请求的指标"""
|
||||
if not settings.metrics_enabled:
|
||||
return await call_next(request)
|
||||
|
||||
# 跳过 /metrics 端点本身,避免循环记录
|
||||
if request.url.path == "/metrics":
|
||||
return await call_next(request)
|
||||
|
||||
in_progress_requests.inc()
|
||||
start_time = time.time()
|
||||
status = "success"
|
||||
|
||||
try:
|
||||
response = await call_next(request)
|
||||
if response.status_code >= 400:
|
||||
status = "error"
|
||||
return response
|
||||
except Exception as e:
|
||||
status = "error"
|
||||
raise e
|
||||
finally:
|
||||
elapsed = time.time() - start_time
|
||||
request_counter.labels(
|
||||
method=request.method,
|
||||
endpoint=request.url.path,
|
||||
status=status
|
||||
).inc()
|
||||
request_latency.labels(
|
||||
method=request.method,
|
||||
endpoint=request.url.path
|
||||
).observe(elapsed)
|
||||
in_progress_requests.dec()
|
||||
```
|
||||
|
||||
### 2. 添加算法执行指标记录
|
||||
|
||||
**文件**:`src/functional_scaffold/algorithms/base.py`
|
||||
|
||||
**修改内容**:
|
||||
- 在 `execute()` 方法中导入 `algorithm_counter` 和 `algorithm_latency`
|
||||
- 在 `finally` 块中记录算法执行指标
|
||||
|
||||
**实现代码**:
|
||||
```python
|
||||
def execute(self, *args, **kwargs) -> Dict[str, Any]:
|
||||
from ..core.metrics import algorithm_counter, algorithm_latency
|
||||
|
||||
start_time = time.time()
|
||||
status = "success"
|
||||
|
||||
try:
|
||||
# ... 算法执行逻辑 ...
|
||||
except Exception as e:
|
||||
status = "error"
|
||||
# ... 错误处理 ...
|
||||
finally:
|
||||
elapsed_time = time.time() - start_time
|
||||
algorithm_counter.labels(algorithm=self.name, status=status).inc()
|
||||
algorithm_latency.labels(algorithm=self.name).observe(elapsed_time)
|
||||
```
|
||||
|
||||
## 验证结果
|
||||
|
||||
### 1. 应用 /metrics 端点
|
||||
|
||||
修复后,`/metrics` 端点正常返回指标数据:
|
||||
|
||||
```
|
||||
# HTTP 请求指标
|
||||
http_requests_total{endpoint="/healthz",method="GET",status="success"} 3.0
|
||||
http_requests_total{endpoint="/invoke",method="POST",status="success"} 2.0
|
||||
http_requests_total{endpoint="/readyz",method="GET",status="success"} 1.0
|
||||
|
||||
# HTTP 请求延迟
|
||||
http_request_duration_seconds_sum{endpoint="/invoke",method="POST"} 0.0065615177154541016
|
||||
http_request_duration_seconds_count{endpoint="/invoke",method="POST"} 2.0
|
||||
|
||||
# 算法执行指标
|
||||
algorithm_executions_total{algorithm="PrimeChecker",status="success"} 2.0
|
||||
algorithm_execution_duration_seconds_sum{algorithm="PrimeChecker"} 0.00023603439331054688
|
||||
algorithm_execution_duration_seconds_count{algorithm="PrimeChecker"} 2.0
|
||||
|
||||
# 当前进行中的请求
|
||||
http_requests_in_progress 0.0
|
||||
```
|
||||
|
||||
### 2. Prometheus 查询
|
||||
|
||||
Prometheus 成功抓取并存储了指标数据:
|
||||
|
||||
```bash
|
||||
# 查询 HTTP 请求总数
|
||||
curl 'http://localhost:9090/api/v1/query?query=http_requests_total'
|
||||
|
||||
# 查询算法执行总数
|
||||
curl 'http://localhost:9090/api/v1/query?query=algorithm_executions_total'
|
||||
```
|
||||
|
||||
## 可用指标
|
||||
|
||||
修复后,以下指标可以在 Prometheus 和 Grafana 中使用:
|
||||
|
||||
### HTTP 请求指标
|
||||
|
||||
1. **http_requests_total** (Counter)
|
||||
- 标签:`method`, `endpoint`, `status`
|
||||
- 描述:HTTP 请求总数
|
||||
- 用途:统计各端点的请求量、成功率
|
||||
|
||||
2. **http_request_duration_seconds** (Histogram)
|
||||
- 标签:`method`, `endpoint`
|
||||
- 描述:HTTP 请求延迟分布
|
||||
- 用途:分析请求响应时间、P50/P95/P99 延迟
|
||||
|
||||
3. **http_requests_in_progress** (Gauge)
|
||||
- 描述:当前正在处理的请求数
|
||||
- 用途:监控并发请求数、负载情况
|
||||
|
||||
### 算法执行指标
|
||||
|
||||
1. **algorithm_executions_total** (Counter)
|
||||
- 标签:`algorithm`, `status`
|
||||
- 描述:算法执行总数
|
||||
- 用途:统计算法调用量、成功率
|
||||
|
||||
2. **algorithm_execution_duration_seconds** (Histogram)
|
||||
- 标签:`algorithm`
|
||||
- 描述:算法执行延迟分布
|
||||
- 用途:分析算法性能、优化瓶颈
|
||||
|
||||
## 使用示例
|
||||
|
||||
### Prometheus 查询示例
|
||||
|
||||
```promql
|
||||
# 每秒请求数 (QPS)
|
||||
rate(http_requests_total[5m])
|
||||
|
||||
# 请求成功率
|
||||
sum(rate(http_requests_total{status="success"}[5m])) / sum(rate(http_requests_total[5m]))
|
||||
|
||||
# P95 延迟
|
||||
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
|
||||
|
||||
# 算法执行失败率
|
||||
sum(rate(algorithm_executions_total{status="error"}[5m])) / sum(rate(algorithm_executions_total[5m]))
|
||||
```
|
||||
|
||||
### 生成测试流量
|
||||
|
||||
使用提供的脚本生成测试流量:
|
||||
|
||||
```bash
|
||||
# 启动流量生成器
|
||||
./scripts/generate_traffic.sh
|
||||
|
||||
# 在另一个终端查看实时指标
|
||||
watch -n 1 'curl -s http://localhost:8111/metrics | grep http_requests_total'
|
||||
```
|
||||
|
||||
## Grafana 仪表板
|
||||
|
||||
访问 Grafana 查看可视化指标:
|
||||
|
||||
1. 打开浏览器访问:http://localhost:3000
|
||||
2. 登录(默认用户名/密码:admin/admin)
|
||||
3. 导入仪表板:`monitoring/grafana/dashboard.json`
|
||||
|
||||
仪表板包含以下面板:
|
||||
- 请求速率(QPS)
|
||||
- 请求延迟(P50/P95/P99)
|
||||
- 错误率
|
||||
- 算法执行统计
|
||||
- 并发请求数
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **中间件顺序**:指标跟踪中间件应该在日志中间件之后注册,确保所有请求都被记录
|
||||
2. **/metrics 端点**:中间件会跳过 `/metrics` 端点本身,避免循环记录
|
||||
3. **错误状态**:HTTP 状态码 >= 400 会被标记为 `status="error"`
|
||||
4. **性能影响**:指标记录的性能开销极小(微秒级),不会影响应用性能
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **添加更多维度**:可以添加 `user_id`、`region` 等标签进行更细粒度的分析
|
||||
2. **自定义指标**:根据业务需求添加自定义指标(如缓存命中率、外部 API 调用次数等)
|
||||
3. **告警规则**:配置 Prometheus 告警规则,在指标异常时发送通知
|
||||
4. **长期存储**:考虑使用 Thanos 或 Cortex 进行长期指标存储和查询
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `src/functional_scaffold/main.py` - HTTP 请求指标跟踪中间件
|
||||
- `src/functional_scaffold/algorithms/base.py` - 算法执行指标记录
|
||||
- `src/functional_scaffold/core/metrics.py` - 指标定义
|
||||
- `monitoring/prometheus.yml` - Prometheus 配置
|
||||
- `monitoring/grafana/dashboard.json` - Grafana 仪表板
|
||||
- `scripts/generate_traffic.sh` - 流量生成脚本
|
||||
Reference in New Issue
Block a user