Lazy loaded image
Prometheus 客户端 Python 库 prometheus_client
Words 5139Read Time 13 min
2026-1-11
2026-1-12
date
related_level
slug
type
relate_date
summary
status
tags
category
last_updated
Jan 12, 2026 10:07 AM
是否已更新
orginal_page
是否推荐
参考资料
prometheus_client 多进程模式:通过共享文件(PROMETHEUS_MULTIPROC_DIR) 聚合指标
  • 背景
    • Prometheus 客户端库假定采用线程模型,其中指标在工作进程之间共享
    • Python 通常使用进程而不是线程来处理大型工作负载
将 prometheus_client 置于多进程模式会带来以下限制
  • 注册表无法像往常一样使用,所有已实例化的指标都会被导出
    • 将指标注册到注册表中供 MultiProcessCollector 稍后使用,可能导致导出重复指标
  • 自定义收集器无法正常工作
  • Gauge 不能使用 set_function 方法
  • Gauge 不能使用 pid 标签
  • Info 类和 Enum 类不能使用
  • Exemplar 类不能使用
  • 不支持移除和清除标签
  • pushgateway 不能使用
prometheus_client 实现多进程模式涉及以下步骤
部署层面:设置环境变量 PROMETHEUS_MULTIPROC_DIR
  • 必须将 PROMETHEUS_MULTIPROC_DIR 环境变量设置为 prometheus_client 可用于存储指标的目录
    • 此目录必须在进程/Gunicorn 运行之间清空,建议每次在启动前清空
  • 该环境变量应该通过启动 shell 脚本设置,而不是直接从 Python 设置
    • 若在 Python 中 os.environ 设置,可能只对主进程生效
每次在请求上下文中创建 registry
  • 不要复用全局 registry
    • 如果 MultiProcessCollector 使用了已注册指标的 registry,则会从文件加载另一份,可能导致同一指标出现两次
  • 最佳实践
    • 每次请求上下文中使用一个全新的 registry=CollectorRegistry(),并只注册 MultiProcessCollector
gunicorn 配置文件应包含以下函数
调整 Gauge 类指标:指定如何合并不同进程的 Gauge 值
multiprocess_mode 支持以下模式
  • 在模式开头加上 live 返回相同的结果,但仅考虑存活的进程
模式
行为
适用场景
'all'
每个进程单独输出(带 pid 标签)
调试、分析单个 worker
'min'
所有进程值的最小值
如“最低可用连接数”
'max'
所有进程值的最大值
如“最高队列长度”
'sum'
所有进程值的总和
最常用(如总请求数、总内存)
'mostrecent'
最近更新的进程的值
状态类指标(但慎用)
 

prometheus_client 指标类

基类 MetricWrapperBase(Collector), Collector(Protocol)
  • 详见文档
  • MetricWrapperBase 继承自 Collector,可被 Prometheus registry 收集并暴露
  • MetricWrapperBase 实现了标签相关处理
四种原生指标类
Counter 类:递增,并在进程重新启动时重置
名称不要手动添加 _total 后缀
  • 内部添加 _total 后缀,在暴露时间序列时会用到
方法 inc(amount) 增加 value
方法 count_exceptions() 作为修饰器或上下文管理器对异常执行计数
  • 方法 reset() 重置计数
Gauge 类:增减
新增初始化参数 multiprocess_mode,默认为 all
  • multiprocess_mode: Literal['all', 'liveall', 'min', 'livemin', 'max', 'livemax', 'sum', 'livesum', 'mostrecent', 'livemostrecent'] = 'all',
  • 若使用 'mostrecent' 模式,仅允许通过 set() 方法设置带时间戳的数值
    • 每个进程写入独立文件,由主进程合并为最新的值
    • live* 为仅考虑进程存活
工具方法 set_to_current_time() 设置时间为当前 UNIX 时间戳
方法 inc(amount), dec(amount), set(value) 调整 value
方法 track_inprogress() 返回 InprogressTracker 对象作为修饰器或者上下文管理器跟踪正在进行的任务数
  • 进入时增加计数,退出时减少计数
方法 time() 返回 Timer 对象作为修饰器或者上下文管理器记录代码块执行耗时
  • 通过调用 set(duration) 方法记录耗时
方法 set_function(f) 将 Gauge 的值绑定到一个函数
  • 设置后其他方法失效
  • 样例中,每次暴露指标时调用对应 len() 函数并将结果作为指标值
    源码实现
    • 注意多线程安全
    Summary 类:记录观测值数量与总和
    • 保留 quantile 标签名但未实际使用
      • 需要计算分位数请使用 Histogram
    名称不要手动添加 _count, _sum 后缀
    • 初始化 self._countself._sum 时内部添加对应后缀,在暴露时间序列时会用到
    方法 observe(amount) 简单递增 _count 并为 _sum 增加 amount 数值
    样例
    方法 time() 返回 Timer 对象作为修饰器或者上下文管理器记录代码块执行耗时
    time() 样例
    • Gauge 类的 time() 类似但调用的方法是 observe(duration)
    Histogram 类:统计观测值分布
    • 保留 le 标签名
    新增初始化参数 buckets: Sequence[Union[float, str]] = DEFAULT_BUCKETS
    • DEFAULT_BUCKETS = (.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2.5, 5.0, 7.5, 10.0, INF)
    桶的初始处理
    • 转为 float,升序排列,自动追加 INF 作为最后一个桶(确保所有值都能落入某个桶),要确保包括 INF 在内至少有两个值
    名称不要手动添加 _bucket, _sum 后缀
    • 初始化 self._bucketsself._sum 时内部添加对应后缀,在暴露时间序列时会用到
    • 每个桶均为一个单独的计数器
    方法 observe(amount)_sum 对应增加 amountamount 首次落入某个桶的上标范围内时,对应桶计数加一
    • exemplar 为可选的示例元数据,如 observe(amount, exemplar={'trace_id': 'abc'})
      • 通常用于关联追踪(Tracing)系统
    样例
    方法 time() 返回 Timer 对象作为修饰器或者上下文管理器记录代码块执行耗时
    time() 样例
    • Gauge 类的 time() 类似但调用的方法是 observe(duration)
    Counter, Summary, Histogram 默认导出一个以 _created 为后缀的额外时间序列
    • 其值为指标创建时的 Unix 时间戳
    • 可以通过设置环境变量 PROMETHEUS_DISABLE_CREATED_SERIES=True 或在代码调用全局函数 disable_created_metrics() 中来禁用
      其他辅助指标类
      Info 类:用于暴露键值对元数据
      info(val) 方法设置字典 val 的 key 为标签名,value 为标签值
      • 所有值应为字符串
      • key 不能与指标已有的标签名重叠,value 不能为空
      Info 类样例
      Enum 类:表示一个实体当前处于预定义状态集合中的某一个
      初始化时必须提供 states 字符串序列
      • 序列可以是 list 或 tuple 等
      • 不能用指标名作为标签名
      用整数索引表示当前状态
      • 默认为 states 字符串序列首个字符串
      state(state) 方法设置当前状态
      • 传入 state 必须在 states 字符串序列中
      Enum 类样例
      Exemplar 类:NamedTuple,为 CounterHistogram 指标的时间序列附加示例元数据
      源码定义
      Counter 样例
      Histogram 样例
      Exemplar 仅以 OpenMetrics 文本格式呈现
      • 如果你使用了该库内置的 HTTP 指标服务器(例如 start_http_server() 或集成到 Flask/FastAPI 中),那么客户端(如 Prometheus Server)可以通过 HTTP 内容协商来请求 OpenMetrics 格式
        • Prometheus Server 默认就会发送 Accept: application/openmetrics-text 请求头,因此会自动收到包含 Exemplars 的响应
      • 如果你不是通过 HTTP 服务器暴露指标,默认的 generate_latest()(来自 prometheus_client.exposition不会输出 Exemplars,必须显式使用 OpenMetrics 专用的生成函数
        • from prometheus_client.openmetrics.exposition import generate_latest
      • Prometheus 需要启用 --enable-feature=exemplar-storage 标识才能存储 Exemplar
      调用方法 labels(*labelvalues: Any, **labelkwargs: Any) 为指标添加标签
      源码定义
      • 建议仅通过调用 .labels() 方法来初始化标签值,参考样例三
      Counter 类样例一:位置参数
      Counter 类样例二:关键字参数
      Counter 类样例三:声明时不会被初始化
       

      prometheus_client 收集器(collector)和注册表(registry)

      prometheus_client 默认会运行一些收集器来收集 python 进程和当前平台的信息
      进程收集器自动收集当前 Python 进程的系统资源使用情况
      • 收集 CPU 使用率、内存占用、文件描述符和启动时间等,以 process_ 为前缀的指标暴露
      • 仅在 Linux 上可用(因为依赖 /proc/self/stat 等 Linux 特有接口)
      • 可以导出有关其他进程的指标
        • 通过构造函数参数 pid 和 namespace 来实现
      平台收集器自动暴露 Python 运行环境的元数据,作为 python_info 指标的标签
      • 指标值恒为 1,所有信息都在标签中
      • 如果使用 Jython,还会包含所用 JVM 的元数据
      • 除此之外还有一个 GC 收集器未展开说明
      可以通过 prometheus_client.REGISTRY.unregister() 方法来手动禁用
      CollectorRegistry 类负责管理所有注册的收集器
      • 全局注册表实例 REGISTRY
        • REGISTRY = CollectorRegistry(auto_describe=True)
      初始化时可以提供 target_infoauto_describe
      • target_info 字典参数用于设置全局 target_info 指标标签
        • 详见下面的 set_target_info() 方法说明
      在检测指标名冲突时,当收集器没有显式提供 describe() 方法时,auto_describe 决定是否回退到调用 collect() 来获取指标信息
      • 内部 _get_name(collector) 方法
      方法 register(collector: Collector) 注册收集器
      • 获取该收集器将产生的所有指标名,检查是否与已有指标名冲突
      • 如果无冲突,更新两个映射字典
      方法 unregister(collector: Collector) 注销收集器
      方法 collect() 从 registry 中的所有 collector 收集指标并产出
      • 返回一个可迭代对象(generator)
      • Prometheus /metrics handler 会遍历它来输出所有指标
      方法 restricted_registry() 返回一个 RestrictedRegistry 对象,只收集指定名称的指标
      RestrictedRegistry 对象的方法 collect() 只收集并输出 names 里的指标
      方法 set_target_info(labels: Optional[Dict[str, str]]) 设置全局 target_info 指标标签
      • 如果 labels 非空,则注册一个名为 target_info 的虚拟收集器
      • 如果 labels 为 None 则移除 target_info
      方法 get_target_info() 返回当前 target_info 指标标签
      自定义收集器适用于无法直接在目标代码中埋点的场景(如第三方服务、黑盒系统等)
      • 创建一个 Custom Collector,定期从外部系统(如 API、日志、数据库)拉取指标数据,并将其转换为 Prometheus 格式暴露出去
      CustomCollector 类样例
      继承 Collector,定义 collect() 方法
      • collect() 方法必须 yield MetricFamily 对象
        • 每个 MetricFamily 代表一个指标,可包含多个带标签的样本
        • 可用类 CounterMetricFamily, GaugeMetricFamily, SummaryMetricFamily, HistogramMetricFamilyInfoMetricFamily 等
      • 注册到全局 REGISTRY,Prometheus 的 HTTP handler 就能自动抓取这些指标
      可选,定义 describe() 方法用于检测命名冲突和防止重复注册
      • 注册阶段提前告知注册表,将 yield 哪些指标名称
      • describe() 只需返回与 collect 格式相同的指标(但无需包含样本)
      • 通常不需要实现 describe 方法
        • 创建 CollectorRegistry 时设置了 auto_describe=True 且收集器未定义 describe 方法,那么注册时会调用 collect 而不是 describe
        • 如果该行为会产生问题再实现合适的 describe 方法或者直接返回空列表
       

      prometheus_client 暴露指标

      • 通常通过 HTTP 协议公开指标
      最简单的是通过 start_http_server() 启动一个 HTTP 服务器
      • 以下样例启动一个 HTTP 服务器在 8000 端口暴露指标
      • start_http_server() 返回 HTTP 服务器实例和后台线程对象,可用于优雅地关闭服务器
      可以通过 start_http_server() 启动一个 HTTPS 服务器
      • 需要提供 certfile 和 keyfile
      • 启用 HTTPS 后,可以通过设置 client_auth_required=True 来启用 mTLS
        • client_cafile 可用于指定包含 CA 证书链的证书文件,该证书链用于验证客户端证书
        • client_capath 可用于指定包含 CA 证书链的证书目录,该证书链用于验证客户端证书
      其他实现根据不同 web 框架而不同,仅列举 Django 和 Flask
      Django
      添加端点和视图
      调整多进程设置
      • 默认情况下,如果设置了环境变量 PROMETHEUS_MULTIPROC_DIR ,则会启用多进程支持
      • 可以通过 PrometheusDjangoView 自定义暴露指标
      • django-prometheus 提供 Django 应用程序的一些现成的监控指标
      Flask
      • 需要通过 Prometheus WSGI 应用来提供指标服务
      myapp.py
      • 运行 WSGI 应用
        • uwsgi --http 127.0.0.1:8000 --wsgi-file myapp.py --callable app
      其他:与 node_exporter 的 textfile collect 集成
      • 写入到文本文件然后让 node_exporter 读取
      • 这里使用了一个独立的注册表,因为默认注册表可能包含其他指标(例如来自 Process Collector 的进程指标),而这里只希望将特定的自定义指标写入文本文件
      其他:与 pushgateway 集成
      pushgateway 需要分组键,详见 pushgateway 文档的 HTTP 方法
      • 函数 push_to_gateway 会将指标替换为具有相同分组键的值
        • 对应 PUT 方法
      • 函数 pushadd_to_gateway 只会替换名称和分组键相同的指标
        • 对应 POST 方法
      • 函数 delete_from_gateway 删除具有给定作业和分组键的指标
        • 对应 DELETE 方法
      • 函数 instance_ip_grouping_key 返回一个分组键,其中实例标签设置为主机的 IP 地址
      样例:推送到位于本机 9091 端口的 pushgateway 实例
      • 这里使用了一个独立的注册表,因为默认注册表可能包含其他指标(例如来自 Process Collector 的进程指标),而这里只希望推送特定的自定义指标
      发送前压缩数据:设置 compression 参数设置为 'gzip' 或 'snappy'
      • snappy 需要安装 python-snappy 软件包
      pushgateway 身份验证处理
      • basic_auth_handler 设置 Authorization 标头
      • 函数 push_to_gateway 设置对应 handler
      pushgateway TLS 验证处理
      • tls_auth_handler 设置对应 TLS 文件
      • 函数 push_to_gateway 设置对应 handler
       
      上一篇
      GnuPG 加密工具
      下一篇
      向 Prometheus 暴露指标

      Comments
      Loading...