详解Python prometheus_client使用方式

 更新时间:2022年02月09日 10:19:47   作者:JoJo93  
本文主要介绍了Python prometheus_client使用方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

背景说明

服务部署在阿里云的K8s上,配置了基于Prometheus的Grafana监控。原本用的是自定义的Metrics接口统计,上报一些字段,后面发现Prometheus自带的监控非常全面好用,适合直接抓取统计,所以做了一些改变。

Python prometheus-client 安装

pip install prometheus-client

Python封装

# 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返回结果实例

Metrics返回结果截图

 到此这篇关于详解Python prometheus_client使用方式的文章就介绍到这了,更多相关Python prometheus_client内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python+Sklearn实现异常检测

    Python+Sklearn实现异常检测

    这篇文章主要为大家详细介绍了Python如何利用Sklearn实现异常检测,文中的示例代码讲解详细,对我们学习Python有一定的帮助,感兴趣的可以跟随小编一起学习一下
    2022-12-12
  • py中的目录与文件判别代码

    py中的目录与文件判别代码

    python中的判别目录和文件的脚本
    2008-07-07
  • Python连接达梦数据库的实现示例

    Python连接达梦数据库的实现示例

    本文主要介绍了Python连接达梦数据库的实现示例,dmPython是DM提供的依据Python DB API version 2.0中API使用规定而开发的数据库访问接口,使Python应用程序能够对DM数据库进行访问
    2023-12-12
  • pycharm 使用心得(三)Hello world!

    pycharm 使用心得(三)Hello world!

    作为PyCharm编辑器的起步,我们理所当然的先写一个Hello word,并运行它。(此文献给对IDE不熟悉的初学者)
    2014-06-06
  • python实现数通设备端口监控示例

    python实现数通设备端口监控示例

    这篇文章主要介绍了python实现数通设备端口监控示例,需要的朋友可以参考下
    2014-04-04
  • Python基于当前时间批量创建文件

    Python基于当前时间批量创建文件

    这篇文章主要介绍了Python基于当前时间批量创建文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 关于使用OpenCsv导入大数据量报错的问题

    关于使用OpenCsv导入大数据量报错的问题

    这篇文章主要介绍了使用OpenCsv导入大数据量报错的问题 ,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • python并发编程多进程之守护进程原理解析

    python并发编程多进程之守护进程原理解析

    这篇文章主要介绍了python并发编程多进程之守护进程原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 解读NumPy数组与Python列表的比较

    解读NumPy数组与Python列表的比较

    在Python中处理数值数据时,可以选择使用Python列表或NumPy数组,Python列表灵活,可存储不同类型元素,但在大数据处理上可能较慢,NumPy数组固定类型,内存连续存储,执行数组操作如加法、乘法等更高效,尤其在大数据集处理上具有明显的性能和内存使用优势
    2024-10-10
  • Python语言中的数据类型-序列

    Python语言中的数据类型-序列

    这篇文章主要介绍了Python语言中的数据类型-序列,前面我们提到了Python数据类型中的内置数值类型与字符串类型。今天学习一下Python的序列数据类型,要知道的是在Python中没有数组这一数据结构,需要的朋友可以参考一下
    2022-02-02

最新评论