Files
FunctionalScaffold/docs/metrics-improvement-summary.md
Roog (顾新培) 5921f71756 main:添加核心文件并初始化项目
新增内容:
- 创建基础项目结构。
- 添加 `.gitignore` 和 `.dockerignore` 文件。
- 编写 `pyproject.toml` 和依赖文件。
- 添加算法模块及示例算法。
- 实现核心功能模块(日志、错误处理、指标)。
- 添加开发和运行所需的相关脚本文件及文档。
2026-02-03 18:38:08 +08:00

7.0 KiB
Raw Blame History

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 请求

优点

  • 自动化:不需要在每个路由上手动添加装饰器
  • 统一:所有端点的指标记录逻辑一致
  • 易维护:新增端点自动获得指标跟踪能力

实现代码

@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_counteralgorithm_latency
  • finally 块中记录算法执行指标

实现代码

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 成功抓取并存储了指标数据:

# 查询 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 查询示例

# 每秒请求数 (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]))

生成测试流量

使用提供的脚本生成测试流量:

# 启动流量生成器
./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_idregion 等标签进行更细粒度的分析
  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 - 流量生成脚本