使用 prometheus python 库编写自定义指标的方法(完整代码)


Posted in Python onJune 29, 2020

虽然 prometheus 已有大量可直接使用的 exporter 可供使用,以满足收集不同的监控指标的需要。例如,node exporter 可以收集机器 cpu,内存等指标,cadvisor 可以收集容器指标。然而,如果需要收集一些定制化的指标,还是需要我们编写自定义的指标。

本文讲述如何使用 prometheus python 客户端库和 flask 编写 prometheus 自定义指标。

安装依赖库

我们的程序依赖于flask 和prometheus client 两个库,其 requirements.txt 内容如下:

flask==1.1.2
prometheus-client==0.8.0

运行 flask

我们先使用 flask web 框架将 /metrics 接口运行起来,再往里面添加指标的实现逻辑。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask
app = Flask(__name__)

@app.route('/metrics')
def hello():
 return 'metrics'

if __name__ == '__main__':
 app.run(host='0.0.0.0', port=5000)

打开浏览器,输入 http://127.0.0.1:5000/metrics,按下回车后浏览器显示 metrics 字符。

编写指标

Prometheus 提供四种指标类型,分别为 Counter,Gauge,Histogram 和 Summary。

Counter

Counter 指标只增不减,可以用来代表处理的请求数量,处理的任务数量,等。

可以使用 Counter 定义一个 counter 指标:

counter = Counter('my_counter', 'an example showed how to use counter')

其中,my_counter 是 counter 的名称,an example showed how to use counter 是对该 counter 的描述。

使用 counter 完整的代码如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, Response
from prometheus_client import Counter, generate_latest
app = Flask(__name__)
counter = Counter('my_counter', 'an example showed how to use counter')

@app.route('/metrics')
def hello():
 counter.inc(1)
 return Response(generate_latest(counter), mimetype='text/plain')

if __name__ == '__main__':
 app.run(host='0.0.0.0', port=5000)

访问 http://127.0.0.1:5000/metrics,浏览器输出:

# HELP my_counter_total an example showed how to use counter
# TYPE my_counter_total counter
my_counter_total 6.0
# HELP my_counter_created an example showed how to use counter
# TYPE my_counter_created gauge
my_counter_created 1.5932468510424378e+09

在定义 counter 指标时,可以定义其 label 标签:

counter = Counter('my_counter', 'an example showed how to use counter', ['machine_ip'])

在使用时指定标签的值:

counter.labels('127.0.0.1').inc(1)

这时浏览器会将标签输出:

my_counter_total{machine_ip="127.0.0.1"} 1.0

Gauge

Gauge 指标可增可减,例如,并发请求数量,cpu 占用率,等。

可以使用 Gauge 定义一个 gauge 指标:

registry = CollectorRegistry()
gauge = Gauge('my_gauge', 'an example showed how to use gauge', ['machine_ip'], registry=registry)

为使得 /metrics 接口返回多个指标,我们引入了 CollectorRegistry ,并设置 gauge 的 registry 属性。

使用 set 方法设置 gauge 指标的值:

gauge.labels('127.0.0.1').set(2)

访问 http://127.0.0.1:5000/metrics,浏览器增加输出:

# HELP my_gauge an example showed how to use gauge
# TYPE my_gauge gauge
my_gauge{machine_ip="127.0.0.1"} 2.0

Histogram

Histogram 用于统计样本数值落在不同的桶(buckets)里面的数量。例如,统计应用程序的响应时间,可以使用 histogram 指标类型。

使用 Histogram 定义一个 historgram 指标:

buckets = (100, 200, 300, 500, 1000, 3000, 10000, float('inf'))
histogram = Histogram('my_histogram', 'an example showed how to use histogram', ['machine_ip'], registry=registry, buckets=buckets)

如果我们不使用默认的 buckets,可以指定一个自定义的 buckets,如上面的代码所示。

使用 observe() 方法设置 histogram 的值:

histogram.labels('127.0.0.1').observe(1001)

访问 /metrics 接口,输出:

# HELP my_histogram an example showed how to use histogram
# TYPE my_histogram histogram
my_histogram_bucket{le="100.0",machine_ip="127.0.0.1"} 0.0
my_histogram_bucket{le="200.0",machine_ip="127.0.0.1"} 0.0
my_histogram_bucket{le="300.0",machine_ip="127.0.0.1"} 0.0
my_histogram_bucket{le="500.0",machine_ip="127.0.0.1"} 0.0
my_histogram_bucket{le="1000.0",machine_ip="127.0.0.1"} 0.0
my_histogram_bucket{le="3000.0",machine_ip="127.0.0.1"} 1.0
my_histogram_bucket{le="10000.0",machine_ip="127.0.0.1"} 1.0
my_histogram_bucket{le="+Inf",machine_ip="127.0.0.1"} 1.0
my_histogram_count{machine_ip="127.0.0.1"} 1.0
my_histogram_sum{machine_ip="127.0.0.1"} 1001.0
# HELP my_histogram_created an example showed how to use histogram
# TYPE my_histogram_created gauge
my_histogram_created{machine_ip="127.0.0.1"} 1.593260699767071e+09

由于我们设置了 histogram 的样本值为 1001,可以看到,从 3000 开始,xxx_bucket 的值为 1。由于只设置一个样本值,故 my_histogram_count 为 1 ,且样本总数 my_histogram_sum 为 1001。
读者可以自行试验几次,慢慢体会 histogram 指标的使用,远比看网上的文章理解得快。

Summary

Summary 和 histogram 类型类似,可用于统计数据的分布情况。

定义 summary 指标:

summary = Summary('my_summary', 'an example showed how to use summary', ['machine_ip'], registry=registry)

设置 summary 指标的值:

summary.labels('127.0.0.1').observe(randint(1, 10))

访问 /metrics 接口,输出:

# HELP my_summary an example showed how to use summary
# TYPE my_summary summary
my_summary_count{machine_ip="127.0.0.1"} 4.0
my_summary_sum{machine_ip="127.0.0.1"} 16.0
# HELP my_summary_created an example showed how to use summary
# TYPE my_summary_created gauge
my_summary_created{machine_ip="127.0.0.1"} 1.593263241728389e+09

附:完整源代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from random import randint
from flask import Flask, Response
from prometheus_client import Counter, Gauge, Histogram, Summary, \
 generate_latest, CollectorRegistry
app = Flask(__name__)
registry = CollectorRegistry()
counter = Counter('my_counter', 'an example showed how to use counter', ['machine_ip'], registry=registry)
gauge = Gauge('my_gauge', 'an example showed how to use gauge', ['machine_ip'], registry=registry)
buckets = (100, 200, 300, 500, 1000, 3000, 10000, float('inf'))
histogram = Histogram('my_histogram', 'an example showed how to use histogram',
  ['machine_ip'], registry=registry, buckets=buckets)
summary = Summary('my_summary', 'an example showed how to use summary', ['machine_ip'], registry=registry)

@app.route('/metrics')
def hello():
 counter.labels('127.0.0.1').inc(1)
 gauge.labels('127.0.0.1').set(2)
 histogram.labels('127.0.0.1').observe(1001)
 summary.labels('127.0.0.1').observe(randint(1, 10))
 return Response(generate_latest(registry), mimetype='text/plain')

if __name__ == '__main__':
 app.run(host='0.0.0.0', port=5000)

参考资料

https://github.com/prometheus/client_python
https://prometheus.io/docs/concepts/metric_types/
https://prometheus.io/docs/instrumenting/writing_clientlibs/
https://prometheus.io/docs/instrumenting/exporters/
https://pypi.org/project/prometheus-client/
https://prometheus.io/docs/concepts/metric_types/
http://www.coderdocument.com/docs/prometheus/v2.14/best_practices/histogram_and_summary.html
https://prometheus.io/docs/practices/histograms/

总结

到此这篇关于使用 prometheus python 库编写自定义指标的文章就介绍到这了,更多相关prometheus python 库编写自定义指标内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python多进程和多线程究竟谁更快(详解)
May 29 Python
Python的numpy库中将矩阵转换为列表等函数的方法
Apr 04 Python
解决python大批量读写.doc文件的问题
May 08 Python
python读取LMDB中图像的方法
Jul 02 Python
Django项目中添加ldap登陆认证功能的实现
Apr 04 Python
django组合搜索实现过程详解(附代码)
Aug 06 Python
Python日期格式和字符串格式相互转换的方法
Feb 18 Python
python 下载文件的几种方法汇总
Jan 06 Python
python如何构建mock接口服务
Jan 28 Python
Flask处理Web表单的实现方法
Jan 31 Python
python将图片转为矢量图的方法步骤
Mar 30 Python
Python Pandas pandas.read_sql函数实例用法
Jun 21 Python
使用keras时input_shape的维度表示问题说明
Jun 29 #Python
在Keras中CNN联合LSTM进行分类实例
Jun 29 #Python
使用keras实现BiLSTM+CNN+CRF文字标记NER
Jun 29 #Python
Python建造者模式案例运行原理解析
Jun 29 #Python
解决Keras中循环使用K.ctc_decode内存不释放的问题
Jun 29 #Python
Python根据指定文件生成XML的方法
Jun 29 #Python
keras在构建LSTM模型时对变长序列的处理操作
Jun 29 #Python
You might like
让你的WINDOWS同时支持MYSQL4,MYSQL4.1,MYSQL5X
2006/12/06 PHP
织梦模板标记简介
2007/03/11 PHP
php 服务器调试 Zend Debugger 的安装教程
2009/09/25 PHP
PHP内核探索:变量概述
2014/01/30 PHP
Smarty高级应用之缓存操作技巧分析
2016/05/14 PHP
Laravel手动分页实现方法详解
2016/10/09 PHP
基于Codeigniter框架实现的student信息系统站点动态发布功能详解
2017/03/23 PHP
PHP后台微信支付和支付宝支付开发
2017/04/28 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
js 图片缩放(按比例)控制代码
2009/05/27 Javascript
Jquery 基础学习笔记
2009/05/29 Javascript
为JavaScript添加重载函数的辅助方法
2010/07/04 Javascript
js中如何把字符串转化为对象、数组示例代码
2013/07/17 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
nodejs中简单实现Javascript Promise机制的实例
2014/12/06 NodeJs
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
2015/12/16 Javascript
Angularjs中UI Router全攻略
2016/01/29 Javascript
JavaScript中String对象的方法介绍
2017/01/04 Javascript
Map.vue基于百度地图组件重构笔记分享
2017/04/17 Javascript
详解JS中统计函数执行次数与执行时间
2018/09/04 Javascript
mongodb初始化并使用node.js实现mongodb操作封装方法
2019/04/02 Javascript
layui 数据表格+分页+搜索+checkbox+缓存选中项数据的方法
2019/09/21 Javascript
[03:07]2015国际邀请赛选手档案EHOME.rOtK 是什么让他落泪?
2015/07/31 DOTA
使用python实现省市三级菜单效果
2016/01/20 Python
python截取两个单词之间的内容方法
2018/12/25 Python
python 基于TCP协议的套接字编程详解
2019/06/29 Python
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
Sperry澳大利亚官网:源自美国帆船鞋创始品牌
2019/07/29 全球购物
如何为DataGridView添加一个定制的Column Type
2014/01/21 面试题
公司授权委托书样本
2014/09/15 职场文书
董事长致辞
2015/07/29 职场文书
大学生团支书竞选稿
2015/11/21 职场文书
MySQL 数据丢失排查案例
2021/05/08 MySQL
python中validators库的使用方法详解
2022/09/23 Python