Prometheus Exporter入门开发指南

Prometheus Exporter 入门开发指南

一、文档概述

Prometheus Exporter 是暴露监控指标的小程序,核心作用是将自定义的业务 / 系统指标转换为 Prometheus 能识别的格式,并通过 HTTP 接口(默认 /metrics)提供给 Prometheus 抓取,是 Prometheus 监控体系的核心组成部分。

二、环境准备

Prometheus 官方提供了 Python 客户端库 prometheus_client,这是开发 Python 版 Exporter 的标配,执行以下命令安装:

pip install prometheus-client

三、Prometheus 核心指标类型

在开发 Exporter 前,必须先理解 Prometheus 的 4 种核心指标类型,这是 Exporter 开发的基础:

指标类型 核心特点 典型用途
Counter 只增不减的计数器(重启后重置) 统计请求总数、错误总数、任务完成数
Gauge 可增可减的瞬时值(支持动态更新) 内存使用率、CPU 负载、随机值等瞬时状态
Histogram 统计数值分布(按预设桶划分) 请求延迟分布、响应大小分布
Summary 统计滑动窗口内的分位数 延迟的 90/99 分位数、接口耗时 Top N

补充:所有指标都支持添加标签(Label),用于维度拆分(如按接口路径、服务实例统计指标)。

四、完整代码解析

4.1 导入核心模块

from prometheus_client import start_http_server, Counter, Gauge, Histogram, Summary
import random
import time
  • prometheus_client
    

    :核心库,提供指标定义、HTTP 服务启动等能力:

    • start_http_server:启动 HTTP 服务,暴露 /metrics 接口;
    • Counter/Gauge/Histogram/Summary:4 种核心指标的构造函数。
  • random:用于模拟随机的指标值(如请求耗时、随机路径);

  • time:用于模拟耗时操作、控制循环间隔。

4.2 定义核心指标

(1)Counter:请求总数计数器
requests_total = Counter(
    'my_requests_total',  # 指标名(Prometheus 命名规范:小写+下划线)
    'Total number of requests processed'  # 指标描述(说明指标含义)
)
  • 作用:统计所有请求的总数量,只会递增(调用 inc() 方法),重启后重置为 0。
  • 关键方法:inc()(默认 + 1,也可传参数如 inc(2) 表示 + 2)。
(2)Gauge:动态随机值
random_value = Gauge(
    'my_random_value',
    'A random value that changes on each scrape'
)
random_value.set_function(lambda: random.random())
  • 作用:暴露一个 0~1 之间的随机瞬时值,每次 Prometheus 抓取(scrape)时自动更新。
  • 关键特性:set_function() 可以绑定一个函数,每次抓取时自动执行并更新指标值;也可手动调用 set(值)/inc()/dec() 修改值。
(3)Histogram:请求耗时分布
request_duration_histogram = Histogram(
    'my_request_duration_seconds',
    'Request duration in seconds',
    buckets=[0.1, 0.5, 1, 2, 5]  # 自定义桶(单位:秒)
)
  • 作用:统计请求耗时的分布情况,比如 “耗时 0.1 秒内的请求数”“0.1~0.5 秒的请求数” 等。
  • buckets:自定义桶的边界,默认桶为 [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],适合大部分场景。
  • 关键方法:observe(值)(记录一个数值到直方图)。
(4)Summary:请求耗时分位数
request_duration_summary = Summary(
    'my_request_duration_summary_seconds',
    'Request duration summary in seconds'
)
  • 作用:统计请求耗时的分位数(默认 0.5/0.9/0.99),比如 “90% 的请求耗时不超过 X 秒”。
  • 关键方法:observe(值)(与 Histogram 用法一致)。
(5)带标签的 Counter:按路径统计请求数
requests_by_path = Counter(
    'my_requests_by_path_total',
    'Requests by path',
    ['path']  # 定义标签名(可多个,如 ['path', 'method'])
)
  • 作用:按 “请求路径” 维度拆分请求数,比如 /home 路径的请求数、/api 路径的请求数。
  • 关键用法:labels(标签名=值).inc()(先绑定标签值,再递增)。

4.3 模拟请求处理函数

def process_request():
    """模拟一次请求处理,更新各类指标"""
    # 1. 递增总请求计数器
    requests_total.inc()

    # 2. 随机选择请求路径,更新带标签的计数器
    path = random.choice(['/home', '/api', '/health'])
    requests_by_path.labels(path=path).inc()  # 绑定path标签值并递增

    # 3. 模拟请求耗时(0.1~2.0秒)
    duration = random.uniform(0.1, 2.0)
    time.sleep(duration)  # 模拟实际业务的耗时操作

    # 4. 记录耗时到Histogram和Summary
    request_duration_histogram.observe(duration)
    request_duration_summary.observe(duration)
  • 核心逻辑:模拟一次完整的请求处理流程,同时更新所有定义的指标,是 Exporter 中 “指标采集逻辑” 的核心载体。

4.4 主程序入口

if __name__ == '__main__':
    # 1. 启动HTTP服务,监听8000端口(暴露/metrics接口)
    start_http_server(8000)
    print("Exporter is running on http://localhost:8000/metrics")

    # 2. 无限循环,持续模拟请求(实际场景可替换为真实业务逻辑)
    while True:
        process_request()
        time.sleep(1)  # 额外等待1秒,避免请求过于密集
  • start_http_server(8000):启动 HTTP 服务,Prometheus 会从 http://localhost:8000/metrics 抓取指标;
  • 无限循环:持续生成模拟请求,保证指标有数据更新(实际开发中,循环逻辑可替换为 “定时采集业务指标”“监听事件更新指标” 等)。

五、运行与测试

5.1 运行脚本

将示例代码保存为 my_exporter.py,执行以下命令运行:

python my_exporter.py

运行成功后会输出:Exporter is running on http://localhost:8000/metrics

5.2 验证指标暴露

打开浏览器访问 http://localhost:8000/metrics,看到类似以下的指标数据(Prometheus 标准格式):

# HELP my_requests_total Total number of requests processed
# TYPE my_requests_total counter
my_requests_total 5.0
# HELP my_random_value A random value that changes on each scrape
# TYPE my_random_value gauge
my_random_value 0.789456
# HELP my_requests_by_path_total Requests by path
# TYPE my_requests_by_path_total counter
my_requests_by_path_total{path="/home"} 2.0
my_requests_by_path_total{path="/api"} 2.0
my_requests_by_path_total{path="/health"} 1.0
  • 能看到这些指标,说明 Exporter 运行正常。

5.3 关键验证点

  1. 指标名和描述与代码中定义的一致;
  2. my_random_value 每次刷新页面会变化(Gauge 动态更新);
  3. my_requests_total 会持续递增(Counter 特性);
  4. 带标签的指标会按 /home//api//health 拆分数值。

六、扩展建议

6.1 替换模拟逻辑为真实业务

process_request() 中的 “随机模拟” 替换为真实业务逻辑,比如:

  • 采集服务器 CPU / 内存使用率(可结合 psutil 库);
  • 统计接口实际请求数(对接 Web 框架如 Flask/Django);
  • 监控数据库连接数(查询数据库状态)。

6.2 添加错误处理

建议给指标采集逻辑加异常捕获:

def process_request():
    try:
        # 原有逻辑
        requests_total.inc()
        # ... 其他逻辑
    except Exception as e:
        # 可选:定义一个错误计数器,统计异常数
        error_total = Counter('my_error_total', 'Total number of errors')
        error_total.inc()
        print(f"Error processing request: {e}")

6.3 自定义指标采集频率

将固定 time.sleep(1) 替换为定时任务(如 schedule 库),更灵活控制采集频率:

pip install schedule
import schedule

def collect_metrics():
    process_request()

if __name__ == '__main__':
    start_http_server(8000)
    # 每5秒采集一次指标
    schedule.every(5).seconds.do(collect_metrics)
    while True:
        schedule.run_pending()
        time.sleep(1)

七、Exporter 开发最佳实践

  1. 指标命名规范

    • 小写字母 + 下划线(如 my_requests_total,避免大写 / 特殊字符);
  • 后缀体现指标类型(如计数器加 _total,耗时加 _seconds)。
  1. 标签设计原则

    • 标签数不宜过多(建议≤5 个),否则会导致指标爆炸;
  • 标签值不宜动态生成(如用户 ID、随机字符串)。
  1. 性能考虑

    • 避免在 /metrics 请求时执行耗时操作(可提前采集并缓存);
  • 无限循环中控制采集频率,避免占用过多 CPU / 内存。

八、总结

关键点回顾

  1. 开发 Python 版 Prometheus Exporter 的核心是使用 prometheus_client 库,先定义指标,再更新指标值,最后通过 HTTP 服务暴露;
  2. Prometheus 核心指标有 4 种:Counter(只增)、Gauge(瞬时值)、Histogram(分布)、Summary(分位数),带标签的指标可实现维度拆分;
  3. 开发时,先通过模拟逻辑验证 Exporter 运行,再逐步替换为真实业务逻辑,同时注意错误处理和命名规范。

附:my_exporter.py

from prometheus_client import start_http_server, Counter, Gauge, Histogram, Summary
import random
import time

# 1. Counter:只增计数器(例如请求总数)
requests_total = Counter(
    'my_requests_total',
    'Total number of requests processed'
)

# 2. Gauge:可增可减的瞬时值(例如当前随机值)
#    使用 set_function 让 Gauge 每次被抓取时自动获取最新值
random_value = Gauge(
    'my_random_value',
    'A random value that changes on each scrape'
)
random_value.set_function(lambda: random.random())

# 3. Histogram:直方图,用于观测值的分布(如请求延迟)
#    buckets 可以自定义,默认 buckets 适合大部分场景
request_duration_histogram = Histogram(
    'my_request_duration_seconds',
    'Request duration in seconds',
    buckets=[0.1, 0.5, 1, 2, 5]  # 可选,自定义桶范围
)

# 4. Summary:摘要,用于计算滑动时间窗口内的分位数(如延迟的 90 分位数)
#    默认包含 0.5, 0.9, 0.99 分位数
request_duration_summary = Summary(
    'my_request_duration_summary_seconds',
    'Request duration summary in seconds'
)

# 带标签的指标示例:按路径统计请求数
requests_by_path = Counter(
    'my_requests_by_path_total',
    'Requests by path',
    ['path']  # 定义标签名
)

def process_request():
    """模拟一次请求处理,更新各类指标"""
    # 更新总请求计数器
    requests_total.inc()

    # 模拟随机路径的请求
    path = random.choice(['/home', '/api', '/health'])
    requests_by_path.labels(path=path).inc()  # 带标签的计数器

    # 模拟请求处理耗时(随机 0.1 ~ 2.0 秒)
    duration = random.uniform(0.1, 2.0)
    time.sleep(duration)  # 模拟耗时操作

    # 将耗时记录到 Histogram 和 Summary
    request_duration_histogram.observe(duration)
    request_duration_summary.observe(duration)

if __name__ == '__main__':
    # 启动 HTTP 服务,监听 8000 端口,暴露 /metrics 端点
    start_http_server(8000)
    print("Exporter is running on http://localhost:8000/metrics")

    # 主循环,每 3 秒模拟一次请求
    while True:
        process_request()
        # 注意:process_request 内部已经 sleep 了随机时长,
        # 但为了让循环更稳定,我们可以再加一个固定间隔
        time.sleep(1)  # 额外等待 1 秒,避免请求过于密集

附:Dockerfile

FROM python:3.9-slim

WORKDIR /app

# 设置 Python 环境变量,避免生成 .pyc 文件和缓冲输出
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

RUN echo "prometheus-client>=0.20.0" > requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

COPY my_exporter.py .

EXPOSE 8000

CMD ["python", "my_exporter.py"]

附:requirements.txt

prometheus_client==0.24.1
posted @ 2026-02-15 00:39  wanghongwei-dev  阅读(30)  评论(0)    收藏  举报