main:添加核心文件并初始化项目

新增内容:
- 创建基础项目结构。
- 添加 `.gitignore` 和 `.dockerignore` 文件。
- 编写 `pyproject.toml` 和依赖文件。
- 添加算法模块及示例算法。
- 实现核心功能模块(日志、错误处理、指标)。
- 添加开发和运行所需的相关脚本文件及文档。
This commit is contained in:
2026-02-02 10:46:01 +08:00
parent 3c3659d314
commit 5921f71756
54 changed files with 5726 additions and 0 deletions

View 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` - 流量生成脚本