[1228]Python prometheus-client使用方式

2023-11-13

github:https://github.com/prometheus/client_python

安装 prometheus_client

使用 pip 工具可以非常方便地安装 prometheus_client:

pip install prometheus-client

基本使用介绍

prometheus_client 提供了丰富的 API,可以用于定义和注册 metrics,并根据需要暴露这些 metrics 的接口。

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

# 定义和注册 metric
c = Counter('test_counter', '测试计数器')
g = Gauge('test_gauge', '测试仪表盘')
s = Summary('test_summary', '测试摘要')
h = Histogram('test_histogram', '测试直方图', buckets=(1, 2, 3))

# 计数器自增
c.inc()

# 仪表盘设置值
g.set(42)

# 摘要和直方图设置数值
s.observe(1.2)
h.observe(4.2)

# 启动 HTTP 服务器,暴露 metrics 接口
start_http_server(8080)

以上代码中,我们首先定义了四个不同类型的 metric(计数器、仪表盘、摘要和直方图),然后分别对它们进行了操作,比如计数器进行了自增操作,仪表盘设置了值,摘要和直方图设置了观察值。最后,我们调用了 start_http_server() 函数,将 metrics 接口暴露出来,以便外部程序可以访问。

应用实例

收集 CPU 使用率指标

下面的示例代码可以用来收集 CPU 的使用率指标:

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

# 定义和注册指标
cpu_percent = Gauge('cpu_percent', 'CPU 使用率百分比')
cpu_freq_current = Gauge('cpu_freq_current', 'CPU 当前频率')
cpu_freq_min = Gauge('cpu_freq_min', 'CPU 最小频率')
cpu_freq_max = Gauge('cpu_freq_max', 'CPU 最大频率')

# 获取 CPU 频率信息
cpu_freq = psutil.cpu_freq()

# 设置初始值
cpu_freq_current.set(cpu_freq.current)
cpu_freq_min.set(cpu_freq.min)
cpu_freq_max.set(cpu_freq.max)

# 启动 HTTP 服务器,暴露 metrics 接口
start_http_server(8080)

while True:
    # 收集 CPU 使用率指标
    cpu_percent.set(psutil.cpu_percent())

    # 收集 CPU 频率指标
    cpu_freq = psutil.cpu_freq()
    cpu_freq_current.set(cpu_freq.current)

    # 等待 1 秒钟,再次进行收集
    time.sleep(1)

在以上代码中,我们使用 psutil 库获取 CPU 使用率和频率等信息,并将它们作为指标进行收集。每次循环执行时,我们都会将当前的指标值设置到相应的 metric 中,并等待一秒钟之后再次收集。

收集自定义指标

prometheus_client 不仅可以收集系统级别的指标,还可以方便地收集自定义的指标。

下面的示例代码演示了如何收集一个随机数指标:

from prometheus_client import Gauge, start_http_server
import random

# 定义和注册指标
random_value = Gauge('random_value', '随机数指标')

# 启动 HTTP 服务器,暴露 metrics 接口
start_http_server(8080)

while True:
    # 生成 0 到 100 的随机数,并设置到指标中
    random_value.set(random.randint(0, 100))

    # 等待 5 秒钟,再次进行收集
    time.sleep(5)

以上代码中,我们定义了一个随机数指标,每隔 5 秒钟会生成一个随机数,并将其设置到指标中。然后,我们又将这个指标通过 start_http_server() 接口暴露出来,以便其他程序可以方便地访问。

通过以上两个示例,我们可以看到 prometheus_client 灵活的 API,可以轻松地实现各种不同类型和不同维度的指标收集和暴露。

Python封装

  • monitor.py
# encoding: utf-8
from prometheus_client import Counter, Gauge, Summary
from prometheus_client.core import CollectorRegistry
from prometheus_client.exposition import choose_encoder


class Monitor:
    def __init__(self):
    # 注册收集器&最大耗时map
    self.collector_registry = CollectorRegistry(auto_describe=False)
    self.request_time_max_map = {}

    # 接口调用summary统计
    self.http_request_summary = Summary(name="http_server_requests_seconds",
                                   documentation="Num of request time summary",
                                   labelnames=("method", "code", "uri"),
                                   registry=self.collector_registry)
    # 接口最大耗时统计
    self.http_request_max_cost = Gauge(name="http_server_requests_seconds_max",
                                  documentation="Number of request max cost",
                                  labelnames=("method", "code", "uri"),
                                  registry=self.collector_registry)

    # 请求失败次数统计
    self.http_request_fail_count = Counter(name="http_server_requests_error",
                                      documentation="Times of request fail in total",
                                      labelnames=("method", "code", "uri"),
                                      registry=self.collector_registry)

    # 模型预测耗时统计
    self.http_request_predict_cost = Counter(name="http_server_requests_seconds_predict",
                                        documentation="Seconds of prediction cost in total",
                                        labelnames=("method", "code", "uri"),
                                        registry=self.collector_registry)
    # 图片下载耗时统计
    self.http_request_download_cost = Counter(name="http_server_requests_seconds_download",
                                         documentation="Seconds of download cost in total",
                                         labelnames=("method", "code", "uri"),
                                         registry=self.collector_registry)

    # 获取/metrics结果
    def get_prometheus_metrics_info(self, handler):
        encoder, content_type = choose_encoder(handler.request.headers.get('accept'))
        handler.set_header("Content-Type", content_type)
        handler.write(encoder(self.collector_registry))
        self.reset_request_time_max_map()

    # summary统计
    def set_prometheus_request_summary(self, handler):
        self.http_request_summary.labels(handler.request.method, handler.get_status(), handler.request.path).observe(handler.request.request_time())
        self.set_prometheus_request_max_cost(handler)

    # 自定义summary统计
    def set_prometheus_request_summary_customize(self, method, status, path, cost_time):
        self.http_request_summary.labels(method, status, path).observe(cost_time)
        self.set_prometheus_request_max_cost_customize(method, status, path, cost_time)

    # 失败统计
    def set_prometheus_request_fail_count(self, handler, amount=1.0):
        self.http_request_fail_count.labels(handler.request.method, handler.get_status(), handler.request.path).inc(amount)

    # 自定义失败统计
    def set_prometheus_request_fail_count_customize(self, method, status, path, amount=1.0):
        self.http_request_fail_count.labels(method, status, path).inc(amount)

    # 最大耗时统计
    def set_prometheus_request_max_cost(self, handler):
        requset_cost = handler.request.request_time()
        if self.check_request_time_max_map(handler.request.path, requset_cost):
            self.http_request_max_cost.labels(handler.request.method, handler.get_status(), handler.request.path).set(requset_cost)
            self.request_time_max_map[handler.request.path] = requset_cost

    # 自定义最大耗时统计
    def set_prometheus_request_max_cost_customize(self, method, status, path, cost_time):
        if self.check_request_time_max_map(path, cost_time):
            self.http_request_max_cost.labels(method, status, path).set(cost_time)
            self.request_time_max_map[path] = cost_time

    # 预测耗时统计
    def set_prometheus_request_predict_cost(self, handler, amount=1.0):
        self.http_request_predict_cost.labels(handler.request.method, handler.get_status(), handler.request.path).inc(amount)

    # 自定义预测耗时统计
    def set_prometheus_request_predict_cost_customize(self, method, status, path, cost_time):
        self.http_request_predict_cost.labels(method, status, path).inc(cost_time)

    # 下载耗时统计
    def set_prometheus_request_download_cost(self, handler, amount=1.0):
        self.http_request_download_cost.labels(handler.request.method, handler.get_status(), handler.request.path).inc(amount)

    # 自定义下载耗时统计
    def set_prometheus_request_download_cost_customize(self, method, status, path, cost_time):
        self.http_request_download_cost.labels(method, status, path).inc(cost_time)

    # 校验是否赋值最大耗时map
    def check_request_time_max_map(self, uri, cost):
        if uri not in self.request_time_max_map:
            return True
        if self.request_time_max_map[uri] < cost:
            return True
        return False

    # 重置最大耗时map
    def reset_request_time_max_map(self):
        for key in self.request_time_max_map:
            self.request_time_max_map[key] = 0.0

调用

import tornado
import tornado.ioloop
import tornado.web
import tornado.gen
from datetime import datetime
from tools.monitor import Monitor

global g_monitor

class ClassifierHandler(tornado.web.RequestHandler):
    def post(self):
        # TODO Something you need
        # work....
        # 统计Summary,包括请求次数和每次耗时
        g_monitor.set_prometheus_request_summary(self)
        self.write("OK")


class PingHandler(tornado.web.RequestHandler):
    def head(self):
        print('INFO', datetime.now(), "/ping Head.")
        g_monitor.set_prometheus_request_summary(self)
        self.write("OK")

    def get(self):
        print('INFO', datetime.now(), "/ping Get.")
        g_monitor.set_prometheus_request_summary(self)
        self.write("OK")


class MetricsHandler(tornado.web.RequestHandler):
    def get(self):
        print('INFO', datetime.now(), "/metrics Get.")
		g_monitor.set_prometheus_request_summary(self)
		# 通过Metrics接口返回统计结果
    	g_monitor.get_prometheus_metrics_info(self)
    

def make_app():
    return tornado.web.Application([
        (r"/ping?", PingHandler),
        (r"/metrics?", MetricsHandler),
        (r"/work?", ClassifierHandler)
    ])

if __name__ == "__main__":
    g_monitor = Monitor()
	
	app = make_app()
    app.listen(port)
    tornado.ioloop.IOLoop.current().start()

Metrics返回结果实例
image.png

参考:https://pythonjishu.com/ldkilffcsapzipi/
https://www.cnblogs.com/alioth01/p/14363574.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[1228]Python prometheus-client使用方式 的相关文章

随机推荐

  • Java调用jython

    Java调用jython 因为工作需要 需要在Java Jvm 进程内调用Python脚本 下了Jython练练手 脚本语言看着真别扭啊 若干年前写自动化测试工具时也用过python一小阵子 但基本忘光光了 好了 直奔主题 前提 1 sun
  • Linux如何给服务器增加白名单

    1 查看系统白名单配置 iptables L n 2 增加白名单 19 40 145 140 是需要增加的服务器IP iptables I INPUT s 19 40 145 140 32 p tcp j ACCEPT 注 I I是i的大写
  • oracle 函数使用方法----replace函数

    例 sql语句如下 select from cen sys TB DIC JDLX t 查询结果如下 需求 需要获取字段 PID 的值并 新增一个字段 PNAME PNAME的值为字段PID去掉 市平台前置机 剩下的字段 实现 select
  • 后端返回parentId,前端处理成children嵌套数据

    rouyi 的 vuetree函数结合elementui el table组件使用 把有parentId和id结构的数据处理成children嵌套数据 字段名称不一致 可以设置 vuetree函数 构造树型结构数据 param data 数
  • html 调用ActiveX

    html网页调用ActiveX控件时 要获取到ActiveX的ClassID 这个ClassID是注册到系统里的 而不是工程中的uuid 下图为uuid 正确的是在注册表的HKEY CLASSES ROOT中查找你的工程名的 项 找到后 其
  • flink state ttl 清理逻辑(截止到flink1.8之前的逻辑)

    在我们开发Flink应用时 许多有状态流应用程序的一个常见要求是自动清理应用程序状态以有效管理状态大小 或控制应用程序状态的访问时间 TTL Time To Live 功能在Flink 1 6 0中开始启动 并在Apache Flink中启
  • openwrt golang mysql_golang1.9编译openwrt运行程序 ,window7下liteide编译

    网上看了好多资料发现都很过时了 基本都是用的https github com gomini go mips32编译的 但是go1 9早就支持mips了 设置好编译参数 开始build 这时在go pkg下会出现linux mips目录 就是
  • Thumb / Thumb-2 / ThumbEE

    本文转载至 http zh wikipedia org wiki ARM E6 9E B6 E6 A7 8B Thumb 较新的ARM处理器有一种16 bit指令模式 叫做Thumb 也许跟每个条件式运行指令均耗用4位的情形有关 在Thum
  • 问题定位及解决方案

    1 视频沉浸页快速滑动后 必现不能向下划动 复现步骤 进入视频沉浸页 快速向下划动 滑动到第一页最后一个时 不能再向下划动 解决步骤 1 确定请求API mtop aliexpress ugc feed video list 2 找到触发请
  • uniapp开发小程序,编译时报错Cannot read property ‘forceUpdate‘ of undefined的解决方案

    1 这个报错 主要是没有在uniapp的开发平台为这个应用注册一个appid 2 登录uniapp开发平台 https dev dcloud net cn 注册成为开发者 并创建一个应用 此应用的名称要与本地的项目的名称一致 3 重现获取u
  • Android开发---Fragment可见/不可见时的生命周期回调函数

    Fragment可见 不可见时的生命周期回调函数 项目中经常会碰到 需要在fragment失去焦点和获得焦点的方法中进行一些设置 但是fragment没有onpause 和onResume 方法 你重写的这两个方法 都是fragment依附
  • python安装

    Python 环境搭建 本章节我们将向大家介绍如何在本地搭建Python开发环境 Python可应用于多平台包括 Linux 和 Mac OS X 你可以通过终端窗口输入 python 命令来查看本地是否已经安装Python以及Python
  • ORA-32021: parameter value longer than 255 characters 解决方法

    在增加节点完后 用dbca 添加数据库实例时 报ORA 32021 parameter value longer than 255 characters 错误 oraagent log 2011 10 24 09 18 32 724 USR
  • 框架学习笔记——Spring

    Spring 文章目录 Spring 1 Spring简介 1 1 框架的主要特征 1 2 Spring的主要特点 1 3 组成 2 Spring之控制反转 IOC 2 1 百科 2 2 两种方式 2 3 依赖注入 推导 2 3 1 新建一
  • Centos7.5安装应用服务教程 ---- jdk1.8安装教程

    1 下载jdk1 8压缩包 建议装在 usr local目录下 2 解压 tar zxvf jdk 8u301 linux x64 tar gz 3 配置环境变量 修改文件配置 vi vim etc profile 在文件底部加入以下配置
  • C++中queue使用详细说明

    一 queue 的介绍 queue 翻译为队列 在 STL 中主要则是实现了一个先进先出的容器 二 queue 的定义 单独定义一个 queue queue
  • linux开放tomcat8080端口,防火墙开启/关闭/状态查询

    linux开放tomcat8080端口 防火墙开启 关闭 状态查询 最终效果 开放8080端口成功访问tomcat页面 要实现开放端口8080有两种方式 仅限于我所知道的 条条大路通罗马 能实现功能就行 废话不多说上干货 一是单独开放808
  • github 如何删除不需要的项目(两种方法)

    在Github上删除项目是一项非常基本的操作 但是对于很多使用者来说 却可能会因为缺乏经验而无从下手 如果你也处于这个情况 那么这篇文章就为你提供了一些详细的指导 删除Github上的项目可以采用两种方式 通过网站进行删除 或者通过Git客
  • JavaScript中的promise

    概述 promise 承诺 是异步编程的一种解决方案 可以替代传统的解决方案 回调函数和事件 ES6统一了用法 并原生提供了Promise对象 promise是异步编程的一种解决方案 什么时候我们会来处理异步事件呢 一种很常见的场景就应该是
  • [1228]Python prometheus-client使用方式

    文章目录 安装 prometheus client 基本使用介绍 应用实例 收集 CPU 使用率指标 收集自定义指标 Python封装 调用 github https github com prometheus client python