Prometheus 基于Python Django实现Prometheus Exporter
基于Python Django实现Prometheus Exporter
需求描述
运行监控需求,需要采集Nginx 每个URL请求的相关信息,涉及两个指标:一分钟内平均响应时间,调用次数,并且为每个指标提供3个标签:请求方法,请求状态,请求URL,并向普罗米修斯暴露这些指标相关数据
实践环境
Python 3.6.5
Django 3.0.6
prometheus-client 0.11.0
代码设计与实现
说明:为了更好的表达主题,代码中数据采集部分暂且采用data变量替代。
基于官方SDK
Gauge Metric为例
view视图实现
CustomExporters.url_exporter_views.UrlExporterView
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Create your views here.
from django.http import HttpResponse
from django.views.generic import View
from prometheus_client import CollectorRegistry, Gauge, generate_latest
import logging
import traceback
logger = logging.getLogger('mylogger')
REGISTRY = CollectorRegistry()
LABELS = ['req_status', 'req_method', 'req_url'] # 标签定义
# 指标定义
g_requests_total = Gauge('requests_total', 'url request num each minute', LABELS, registry=REGISTRY)
g_avg_response_time_seconds = Gauge('avg_response_time_seconds', 'url avg response time of one minute', LABELS, registry=REGISTRY)
class UrlExporterView(View):
def get(self, request, *args, **kwargs):
try:
data = {
'count': 34,
'method': 'get',
'status': 200,
'url': 'url',
'avg_rt':50
}
g_requests_total.labels(data.get('status'),data.get('method'),data.get('url')).set(data.get('count')) #set设定值
g_avg_response_time_seconds.labels(data.get('status'),data.get('method'),data.get('url')).set(data.get('avg_rt'))
return HttpResponse(generate_latest(REGISTRY),status=200, content_type="text/plain")
except Exception:
error_msg = '%s' % traceback.format_exc()
logger.error(error_msg)
return HttpResponse('# HELP Error occured', status=500, content_type="text/plain")
注意:通过官方SDK无法向普罗米修斯暴露数据生成时间(非采集时间),以上实现方式无法满足这种需求
项目URL路由配置
CustomPrometheusExporters.CustomPrometheusExporters.urls.py
from django.contrib import admin
from django.urls import path, re_path, include
urlpatterns = [
re_path(r'^exporters/', include('CustomExporters.urls')),
path('admin/', admin.site.urls),
]
应用urls.py url路由配置
CustomExporters.urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.urls import path,re_path
from CustomExporters.url_exporter_views import UrlExporterView
urlpatterns = [
re_path(r'url-exporter/metrics$', UrlExporterView.as_view(), name='url-exporter')
]
查看运行结果
浏览器中访问 http://127.0.0.1:8000/exporters/url-exporter/metrics,输出如下:
# HELP requests_total url request num each minute
# TYPE requests_total gauge
requests_total{req_method="get",req_status="200",req_url="url"} 34.0
# HELP avg_response_time_seconds url avg response time of one minute
# TYPE avg_response_time_seconds gauge
avg_response_time_seconds{req_method="get",req_status="200",req_url="url"} 50.0
不基于官方SDK
view视图实现
CustomExporters.url_exporter_views.UrlExporterView
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Create your views here.
from django.http import HttpResponse
from django.views.generic import View
from prometheus_client.utils import floatToGoString
import logging
import traceback
logger = logging.getLogger('mylogger')
class UrlExporterView(View):
def get(self, request, *args, **kwargs):
try:
data = {
'count': 34,
'method': 'get',
'status': 200,
'url': 'url',
'avg_rt':50,
'timestamp': 1634099490000
}
requests_total_line_list = ['# HELP requests_total The total requests number of url to req_service, req_method, status \n'] # 存放 requests_total指标输出
avg_response_time_line_list = ['# HELP avg_response_time_milseconds average request response time for url correspond to req_service, req_method, status\n'] # 存放 avg_response_time_seconds指标输出
line_template = '%(metric_name)s{req_method="%(req_method)s",req_status="%(req_status)s",req_url="%(req_url)s"} %(label_value)s %(timestamp)s\n'
requests_total_line_list.append(line_template % {
'metric_name':'requests_total',
'req_method':data.get('method'),
'req_status':data.get('status'),
'req_url':data.get('url'),
'label_value':floatToGoString(data.get('count')),
'timestamp':data.get('timestamp')
})
avg_response_time_line_list.append(line_template % {
'metric_name':'avg_response_time_milseconds',
'req_method':data.get('method'),
'req_status':data.get('status'),
'req_url':data.get('url'),
'label_value':floatToGoString(data.get('avg_rt')),
'timestamp':data.get('timestamp')
})
output_list = []
output_list.extend(requests_total_line_list)
output_list.append('\n')
output_list.extend(avg_response_time_line_list)
return HttpResponse(''.join(output_list).encode('utf-8'), status=200, content_type="text/plain")
except Exception:
error_msg = '%s' % traceback.format_exc()
logger.error(error_msg)
return HttpResponse('# HELP Error occured', status=500, content_type="text/plain")
查看运行结果
浏览器中访问 http://127.0.0.1:8000/exporters/url-exporter/metrics,输出如下:
# HELP requests_total The total requests number of url to req_service, req_method, status
requests_total{req_method="get",req_status="200",req_url="url"} 34.0 1634099490000
# HELP avg_response_time_milseconds average request response time for url correspond to req_service, req_method, status
avg_response_time_milseconds{req_method="get",req_status="200",req_url="url"} 50.0 1634099490000
样本数据格式说明
普罗米修斯基于文本的(text-based)格式是面向行的。行由换行符(\n)分隔。最后一行必须以换行字符结尾。空行将被忽略
在一行中,tokens可以由任意数量的空格和/或制表符分隔(如果它们与前一个令牌合并,则必须至少由一个空格分隔)。忽略行收尾随空格。
以 # 作为首个非空白字符的行,被当作注释,且除非#后面第一个token为HELP、TYPE,形如 # HELP、# TYPE,否则罗米修斯会自动忽略该行。
如果token为HELP,则至少需要1个token,该token为Metric名称,剩余所有token为该属性的文档字符串说明(dockstring)。HELP行可以是任意UTF-8序列字符,如果包含反斜杠 \、 换行符\n字符,需要进行显示转义,形如 \\, \n
如果token为TYPE,则至少需要2个token,第一个token为Metric名称,第二个为counter,gauge, histogram, summary, 或者 untyped,定义名称指定的Metric的类型。针对同一个给定的Metric名称,只能存在一种Type。TYPE行必须位于该Metric的第一行数据样本行之前。如果该Metric没有定义对应的TYPE行,则默认TYPE为untyped。
剩余的行描述样本(每行对应一个数据样本)使用以下格式
metric_name[{label_name1="label_value",label_name2="label_value",..,label_nameN="label_valueN"}] value [timestamp]
metric_name和label_name遵守普罗米修斯惯用的语言表达式限制label_value可以是任意UTF-8序列字符,如果包含反斜杠\、双引号"、 换行符\n字符,需要进行显示转义,形如\\,\",\nvalue代表浮点数,正如GoParseFloat()所需参数。此外,除标准数值外,NaN、+Inf和-Inf分别表示非数字、正无穷大和负无穷大的有效值timestamp数据自身生成时间,为64整数(1970-01-01 00:00:00 UTC到现在的毫秒数) ,正如GoParseInt()所需参数
Prometheus 基于Python Django实现Prometheus Exporter的更多相关文章
- 基于Python+Django的Kubernetes集群管理平台
➠更多技术干货请戳:听云博客 时至今日,接触kubernetes也有一段时间了,而我们的大部分业务也已经稳定地运行在不同规模的kubernetes集群上,不得不说,无论是从应用部署.迭代,还是从资源调 ...
- 基于Python Django开发的一个mock
最近研究了一下python的django框架, 发现这个框架不比Java spring boot差, mock同样一个接口, 代码量少很多, 维护起来也很方便, 废话不多说,直接上代码 1. 安装dj ...
- 基于Python+Django重定向的例子
Django源码, 这里HttpResponseRedirect和HttpResponsePermanentRedirect没有太大差别,前者是返回302临时重定向,后者返回301永久重定向 clas ...
- Python Web实战:Python+Django+MySQL实现基于Web版的增删改查
前言 本篇使用Python Web框架Django连接和操作MySQL数据库学生信息管理系统(SMS),主要包含对学生信息增删改查功能,旨在快速入门Python Web,少走弯路.效果演示在项目实战最 ...
- 基于dlib+django+python 实现web端人脸打卡
face_recognition 基于python+django+dlib实现的人脸打卡系统 开始之前 windows用户需要安装 VS2017 其他VS版本也行 linux用户需要安装c++编译器( ...
- 基于Centos7.4搭建prometheus+grafana+altertManger监控Spring Boot微服务(docker版)
目的:给我们项目的微服务应用都加上监控告警.在这之前你需要将 Spring Boot Actuator引入 本章主要介绍 如何集成监控告警系统Prometheus 和图形化界面Grafana 如何自定 ...
- prometheus 基于DNS的目标发现
prometheus 基于DNS的目标发现 DNS服务发现依赖于查询A.AAAA或SRV DNS记录. 1.基于 SRV 记录发现 scrape_configs: - job_name: 'webap ...
- prometheus 基于文件的目标发现
prometheus 基于文件的目标发现 1.创建目录 cd /usr/local/prometheus/conf mkdir -pv targets/{nodes,docker} 2.修改prome ...
- Prometheus 基于文件的服务发现
Prometheus 基于文件的服务发现 官方文档:https://github.com/prometheus/prometheus/tree/master/discovery 服务发现支持: end ...
- prometheus学习系列十一: Prometheus exporter详解
exporter详解 前面的系列中,我们在主机上面安装了node_exporter程序,该程序对外暴露一个用于获取当前监控样本数据的http的访问地址, 这个的一个程序成为exporter,Expor ...
随机推荐
- 如果个人pc上要装不同社区版本的pycharm,安装时需要注意的一点
pycharm下载地址[包含了目前发行的所有版本]:https://www.jetbrains.com/pycharm/download/other.html 选择指定的版本,点击 勾选uninsta ...
- JavaScript 中 toString 的奇妙使用
JavaScript 中的toString()方法,我们通常会一些其他类型的变量,转为字符串类型.但这里还有一些其他奇妙的用法. 不同的类型调用 toString() 会得到不同的结果.我们来一一分析 ...
- 给师妹写的《Java并发编程之线程池十八问》被表扬啦!
写在开头 之前给一个大四正在找工作的学妹发了自己总结的关于Java并发中线程池的面试题集,总共18题,将之取名为<Java并发编程之线程池十八问>,今天聊天时受了学妹的夸赞,心里很 ...
- ubuntu18.04最小化安装
ubuntu 18.04虚拟机安装 镜像下载地址: https://releases.ubuntu.com/18.04/ubuntu-18.04.6-live-server-amd64.iso 创建虚 ...
- 微信iOS消息拦截插件教程-手机越狱环境搭建
微信iOS消息拦截插件教程-手机越狱环境搭建 标签(空格分隔): ios越狱开发 环境 背景介绍 本教程所有内容免费 本教程来源于一次知识分享,如果有需要了解更多的 请联系QQ:480071411 i ...
- 椭圆曲线密码学(ECC)加解密,附带python代码
想起来很久没写博客了,刚好今天要写实验报告,随便把之前的也完成吧 1.椭圆曲线概念 椭圆曲线在经过化解后,可以用这条式子表达:E:y²=x³+ax+b 其背后的密码学原理,是基于椭圆曲线离散对数问题, ...
- SMOGN算法Python实现:解决回归分析中的数据不平衡
本文介绍基于Python语言中的smogn包,读取.csv格式的Excel表格文件,实现SMOGN算法,对机器学习.深度学习回归中,训练数据集不平衡的情况加以解决的具体方法. 在不平衡回归问题 ...
- Java求两个List集合的交集、并集、差集
在项目中经常会求解集合的交集.并集.差集,这里做个记录.首先创建两个集合list1.list2以及添加元素. List<String> list1 = new ArrayList<& ...
- 动态生成的 select option 无法选中,设置值
使用jQuery的 .val('22') 给select 设置值时不生效. 原因:select是动态生成的,在DOM还没生成完之前就调用了.val('22'). 解决方法:动态生成的ajax请求改成同 ...
- C++面向对象语言自制多级菜单
因为要做一个小应用,需要一个菜单类,在网上找了许久,也没有找到一款心仪的菜单类,索性用C++语言,自制一个命令行级别的菜单类,并制作成库,现记录下来,供以后借鉴. 一.特性 无限制条目 无限制层级 用 ...