Prometheus 基于Python Django实现Prometheus Exporter

Python67

需求描述

运行监控需求,需要采集Nginx 每个URL请求的相关信息,涉及两个指标:一分钟内平均响应时间,调用次数,并且为每个指标提供3个标签:请求方法,请求状态,请求URL,并向普罗米修斯暴露这些指标相关数据

实践环境

Python 3.6.5

Django 3.0.6

prometheus-client 0.11.0

代码设计与实现

说明:为了更好的表达主题,代码中数据采集部分暂且采用 data变量替代。

Gauge Metric为例

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无法向普罗米修斯暴露数据生成时间(非采集时间),以上实现方式无法满足这种需求

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),
]

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

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为 HELPTYPE,形如 # 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名称,只能存在一种 TypeTYPE行必须位于该 Metric的第一行数据样本行之前。如果该 Metric没有定义对应的 TYPE行,则默认 TYPEuntyped

剩余的行描述样本(每行对应一个数据样本)使用以下格式

metric_name[{label_name1="label_value",label_name2="label_value",..,label_nameN="label_valueN"}] value [timestamp]
  • metric_namelabel_name遵守普罗米修斯惯用的语言表达式限制
  • label_value 可以是任意UTF-8序列字符,如果包含反斜杠 \、双引号 "、 换行符 \n字符,需要进行显示转义,形如 \\, \", \n
  • value 代表浮点数,正如Go ParseFloat()所需参数。此外,除标准数值外, NaN+Inf-Inf分别表示非数字、正无穷大和负无穷大的有效值
  • timestamp 数据自身生成时间,为64整数(1970-01-01 00:00:00 UTC到现在的毫秒数) ,正如Go ParseInt()所需参数

Original: https://www.cnblogs.com/shouke/p/15426777.html
Author: 授客
Title: Prometheus 基于Python Django实现Prometheus Exporter



相关阅读

Title: python pyautogui

使用pyautogui随机调用图库里的一张照片设置为壁纸,每天定时执行

import time
import pyautogui
import random

pyautogui.keyDown('win')
pyautogui.press('d')
pyautogui.keyUp('win')    #显示桌面

time.sleep(1)
pyautogui.click(140,150,clicks=2)   #找到图片库

time.sleep(1.5)
image=pyautogui.locateOnScreen('c:/Users/25671/PycharmProjects/pythonProject/cupture2.PNG',confidence=0.5)    #通过图片定位
goto_pos=pyautogui.center(image)
pyautogui.moveTo(goto_pos)
pyautogui.click(clicks=2)

time.sleep(1)
image=pyautogui.locateOnScreen('c:/Users/25671/PycharmProjects/pythonProject/cupture3.PNG',confidence=0.7)    #通过图片定位
if image is not None:
    goto_pos=pyautogui.center(image)
    pyautogui.moveTo(goto_pos)
    pyautogui.moveRel(0,-20,duration=1)    #相对向上移动
    pyautogui.click(clicks=2)                   #放大

x=random.randrange(280,1880,145)     #随机定位图片
y=random.randrange(190,830,220)
pyautogui.click(x,y,clicks=2)      #选中
time.sleep(1.5)

pyautogui.click(900,500,clicks=1,button='right')    #右键图片
time.sleep(0.5)
pyautogui.press('k')        #按k设置为背景
time.sleep(1)

pyautogui.click(1887,10,clicks=1)   #关闭图片

time.sleep(1)
pyautogui.keyDown('alt')    #关闭当前界面
pyautogui.press('f4')
pyautogui.keyUp('alt')

pyautogui

使用pip安装pywin32与pywinhook
安装pyautogui

b = pyautogui.position()

time.sleep(1)

image=pyautogui.locateONScreen('fox.PNG')     #获取图片 图片可以用截图工具截取

#locateONScreen 可以增加confidence参数来设置寻找图片精度
confidence=1精确查找(也是默认)  confidence=0.5模糊查找   根据数值来设置
confidence 来自函数opencv-python 通过pip install opencv-python可下载(建议增加此参数可提高搜索效率)

goto_pos=pyautogui.center(image)

pyautogui.moveTo(goto_pos)

pyautogui.click(clicks=2)

pyautogui.click(611, 483,clicks=2 ,duration=0.5)
坐标 点击次数 延迟
pyautogui.click(button='right')
点击右键

pyautogui.moveRel(0,600,duration=1)

pyautogui.typewrite(['enter','g','o','o','d','left','left','left','backspace','G','end','.'],0.25)
pyautogui.typewrite('i like pyhton')

pyautogui.PAUSE=0.5

print( random.randint(1,10) )        # 产生 1 到 10 的一个整数型随机数
print( random.random() )             # 产生 0 到 1 之间的随机浮点数
print( random.uniform(1.1,5.4) )     # 产生  1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print( random.choice('tomorrow') )   # 从序列中随机选取一个元素
print( random.randrange(1,100,2) )   # 生成从1到100的间隔为2的随机整数

设置windows定时操作

1.右键此电脑
2.管理
3.任务计划程序
4.创建基本任务
5.设置名称描述
6.触发器 每天
7.选择启动程序

Original: https://www.cnblogs.com/supermao12/p/15864303.html
Author: supermao12
Title: python pyautogui