使用 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 Web框架Pylons中使用MongoDB的例子
Dec 03 Python
Python中文竖排显示的方法
Jul 28 Python
基于Linux系统中python matplotlib画图的中文显示问题的解决方法
Jun 15 Python
详解Django中间件执行顺序
Jul 16 Python
python 在指定范围内随机生成不重复的n个数实例
Jan 28 Python
Python3简单实现串口通信的方法
Jun 12 Python
Django Admin设置应用程序及模型顺序方法详解
Apr 01 Python
Python连接Hadoop数据中遇到的各种坑(汇总)
Apr 14 Python
Python爬虫抓取指定网页图片代码实例
Jul 24 Python
python实现人性化显示金额数字实例详解
Sep 25 Python
Python logging自定义字段输出及打印颜色
Nov 30 Python
关于 Python json中load和loads区别
Nov 07 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
php 文本文件的读取效率
2012/02/10 PHP
php数组删除元素示例
2014/03/21 PHP
php中操作memcached缓存进行增删改查数据的实现代码
2014/08/15 PHP
ThinkPHP中数据操作案例分析
2015/09/27 PHP
PHP实现的函数重载功能示例
2018/08/03 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
JQuery对checkbox操作 (循环获取)
2011/05/20 Javascript
JS解决url传值出现中文乱码的另类办法
2013/04/08 Javascript
Extjs优化(一)删除冗余代码提高运行速度
2013/04/15 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
2014/04/23 Javascript
javascript闭包入门示例
2014/04/30 Javascript
一个简单的jQuery计算器实现了连续计算功能
2014/07/21 Javascript
jQuery使用hide方法隐藏元素自身用法实例
2015/03/30 Javascript
javascript自动恢复文本框点击清除后的默认文本
2016/01/12 Javascript
深入浅析knockout源码分析之订阅
2016/07/12 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
手把手带你封装一个vue component第三方库
2019/02/14 Javascript
Vue实现todo应用的示例
2021/02/20 Vue.js
python十进制和二进制的转换方法(含浮点数)
2018/07/07 Python
python3.6的venv模块使用详解
2018/08/01 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
python反转列表的三种方式解析
2019/11/08 Python
python实现tail实时查看服务器日志示例
2019/12/24 Python
OpenCV+python实现实时目标检测功能
2020/06/24 Python
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
2021/01/06 Python
美国手工艺品市场的领导者:Annie’s
2019/04/04 全球购物
写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔
2015/07/30 面试题
银行实习鉴定
2013/12/13 职场文书
学生会主席就职演讲稿
2014/01/14 职场文书
酒店员工职业生涯规划
2014/02/25 职场文书
会计实训报告范文
2014/11/04 职场文书
房地产工程部经理岗位职责
2015/04/09 职场文书
Python 文本滚动播放器的实现代码
2021/04/25 Python
关于JavaScript 中 if包含逗号表达式
2021/11/27 Javascript
详解pytorch创建tensor函数
2022/03/22 Python
netty 实现tomcat的示例代码
2022/06/05 Servers