找回密码
 注册
查看: 536|回复: 0

利用python代码获取Prometheus API查询监控数据导出数据

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2023-7-3 17:00:11 | 显示全部楼层 |阅读模式
$ N- A6 f7 ~+ r6 S2 E1 V
发送给企业微信机器人
: n. m  ]5 h+ U3 }# ?- y! }
7 j" U! o5 C! Q8 i: e' Q# ]#  upload_file 是为了生成 media_id, 供消息使用
: o  `+ K4 m" a4 p6 U$ F# M/ P8 }% ?0 u, I
# -*- encoding: utf-8 -*-
6 r9 V! V  }/ {import requests, paramiko, json, os, datetime8 W, q- A/ \2 n0 t6 w' G0 B
import pandas as pd! @% R9 K% d  B( s2 L' \
from copy import copy
$ F9 S6 {0 J; t0 \5 vfrom urllib3 import encode_multipart_formdata
( o7 \$ A# K+ d7 G% L8 W
6 _& Z  B8 n! ^; I) _, Pdef upload_file(file_path, wx_upload_url):) z. V  o& [0 K: t
    file_name = file_path.split("/")[-1]
: L7 P: A2 G$ w    with open(file_path, 'rb') as f:
  ]# V# p! G+ L5 M        length = os.path.getsize(file_path)
" a$ V; M* O  r, @7 a2 F        data = f.read()% ^0 V  d+ W9 A2 f7 Y* t% d
    headers = {"Content-Type": "application/octet-stream"}2 t2 D  |: `2 y; }, a2 ?9 j
    params = {3 [2 c: @5 R( r1 `0 V
        "filename": file_name,
/ t/ Y6 i) p0 {& u( M* B        "filelength": length,4 F, d0 d8 ?& x8 L3 L
    }
* n" e4 E! d( C) U& n    file_data = copy(params)
2 X6 g$ q% L: t+ `    file_data['file'] = (file_path.split('/')[-1:][0], data)
8 X2 P: T4 M4 Q; D# X  o3 @    encode_data = encode_multipart_formdata(file_data)
8 A. e( E& i' `: ?9 \0 _! t, T: G$ B1 N4 i    file_data = encode_data[0]
8 z; D8 c8 ]" g2 p/ I    headers['Content-Type'] = encode_data[1]
6 [6 S' i. S# v+ z  s    r = requests.post(wx_upload_url, data=file_data, headers=headers)
5 k/ |1 G) Q3 V) \    print(r.text)! B/ D( z; ~4 p2 l  F8 ?: J- k
    media_id = r.json()['media_id']
1 {8 r5 t8 W7 {; i" ^% y( k    return media_id' t+ }, E5 ]8 k
# media_id 通过上一步上传的方法获得
; k3 [! e. l$ j) x. m( A* X: t8 L) l8 O, L* u6 a1 A& O2 N
def qi_ye_wei_xin_file(wx_url, media_id):
* X$ Y# C( S9 c    headers = {"Content-Type": "text/plain"}2 J5 I4 b: w4 {' S# \
    data = {
) z- N" }; h( A. N6 T( C        "msgtype": "file",
; D7 D' b6 O* L- w        "file": {) U; ^! Q7 h. _: z7 P8 ?
            "media_id": media_id
) P+ _3 q4 t4 F1 w) G        }
7 ?2 p7 b6 x2 U8 e- y1 T+ W    }7 G% X5 y$ M0 x: K6 q, M
    r = requests.post(. }, f' `& s+ e2 z( G
        url=wx_url,5 F- u2 f' W% E# n) v
        headers=headers, json=data)2 X/ R% G3 o% g, D+ |1 P
    print(r.text)  h: u4 Y4 \$ |7 ~% i2 X* v; a

( `2 x9 k' J/ x7 I, c6 |9 B$ r' _# U% _
8 o0 z9 E% l2 U: J- {1 e
从Prometheus 上获取监控数据5 [* l0 B2 m0 D; i0 P' q

* q1 o9 ^0 G( K, X, {! s, q6 c1 Q# 得到一个Overssh的返回值
2 D# F( y2 s6 i& m7 C: z6 C" Kdef get_file_list(hostname, port, username, key_name, command):/ D( x" w2 T1 r: W/ b
    ssh = paramiko.SSHClient()                       # 创建SSH对象
, s; t. C1 X  u* W0 }+ ?4 o    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())      # 允许连接不在know_hosts文件中的主机8 M* a, |1 N0 o. I) T: g- ?, D
    # ssh.connect(hostname='ip', port=22, username='user', password='密码')        # 连接服务器& k! k; l! l% _3 v4 p" F6 O
    ssh.connect(hostname=hostname, port=port, username=username,1 `* \% b9 `, B7 W9 D5 d
                pkey=paramiko.RSAKey.from_private_key_file(key_name))                 # 连接服务器8 m, w3 A  L* @, j5 z5 d; y
    stdin, stdout, stderr = ssh.exec_command(command)
/ G/ `9 U5 I1 z7 y+ w9 p% `
& F' P+ p1 I7 M- ]2 b% e  |% j# `    file_list = str(stdout.read(), encoding="utf-8")% m- v. o: l6 Q1 _! B& s7 e, [
    ssh.close()  # 关闭连接5 P! K/ x; }4 a, U) t
5 S3 L* R6 f, ]( ]' a; o" \) m/ w6 {
    return file_list
6 r/ ?( ?; s0 A
1 h; |' v  W( ?% Y
4 g8 Q; P3 ]/ n6 b) M2 A0 a* u4 E) I将PD写入到磁盘3 v  I0 l( U9 Z& H$ z
3 a3 T3 n  N2 b7 \. K3 s
def write_to_dish(results,fileDir):. i! B8 s$ T8 B2 d1 a; d
    writer = pd.ExcelWriter(fileDir)
3 o) {( M9 M. ?! A4 @    results.to_excel(writer,float_format='%.5f')# \, l0 ?. b$ P2 ~( {9 I9 z/ n
    writer.save()  y8 E/ |5 b4 a; ~# F$ x5 r1 G
7 D- ~# H$ v0 {
定义好需要查询的metric, i. c5 Y+ Z. L: o$ s0 S! `% O! Q
3 }+ e3 B6 d; i! b
# 查询需要检查的数据,第一个必须为 up0 s8 w; a* ]9 @4 S, V
def rds_metrics_list():. D: y& F& j. }9 {9 P
    return {'up': '状态',
' J2 L6 Z7 F4 Q: y. r: O  y                    'rds001_cpu_util': 'CPU使用率(%)',
# L8 z+ a2 H6 y# l/ v                    'rds002_mem_util': '内存使用率(%)'," x+ Y% P/ r- ]' p% u2 y- `% M- o: u
                    'rds003_iops': 'iops',
7 z5 r2 D/ f0 I: F( A                    'rds004_bytes_in': '网络流量入(Bytes)',
$ E  _! Z8 v3 E, @( F% X1 d                    'rds005_bytes_out': '网络流量出(Bytes)',# i6 L. R# F1 J. ?7 u) ^
                    'rds008_qps': 'QPS',0 g% b6 @$ N7 i4 a6 k
                    'rds009_tps': 'TPS',+ B3 V2 U' l2 J
                    'rds081_vm_ioutils': 'io使用率(%)',
% I. K) |5 x% z4 A3 ^8 M; F                    'rds047_disk_total_size': '磁盘总大小(G)',
$ L& w* Z! F& i3 f2 C( f# @                    'rds048_disk_used_size': '磁盘使用(G)',2 b( P- p) l8 Q  H9 A) i
                    'mysql_global_status_threads_connected': '当前连接数',  v! n1 X" v' B- k
                    'mysql_global_variables_max_connections': '最大连接数',& i6 K% \; A8 x* `2 o$ c+ b
                    }! S. V/ o" \: T9 ?* f/ Z
' m# r! g+ }: m& S

7 e3 S& v8 t+ ]9 q
- x- A1 B( K2 p" D! ~Prometheus 获取数据落盘数据,并发送给企业微信机器人
/ Y4 F6 S1 J" }& ~9 ]0 w7 u
' K# d. q: m4 ?5 I5 ~if __name__ == '__main__':6 R: H0 t  H+ `) t, i- Z
    # prometheus 主机信息
, D* N: H3 U# P+ h    host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}
% n# R/ @  Y" E3 A    # 检查文件路径
. D9 I  h) O4 f    check_file_dir = 'check_files'
2 r. M6 x+ G5 \3 e0 Q3 v
' Z  c6 g' a3 G3 @    # 检查文件时间,时区问题需要减去8小时
3 i) W% r9 q: X" Q2 c    curhour = -17  # 默认给-17 当前时间是-8.11 C5 b5 q: p" Y) j' M4 v

; ^- I! Y# _' ]( ]7 `1 [! c    # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人
( G! `$ }. E- _  E. G& `2 V9 S* w$ Q% S% n
    check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',; U! r( }# c3 P5 X* c
                                            'robot_key': 'xxx'}}( _! P7 m; b& U; b
0 r- d; q  c# p! n
    if not os.path.exists(check_file_dir):' B/ M* `3 _6 x4 Y* J! T/ o) v, c' G
        os.makedirs(check_file_dir)
, N4 n! J4 v, t& H4 K- W" i0 {2 P# R" e+ _
    metrics_list = rds_metrics_list()! V, N/ H0 l. ^

- S7 k3 v- l5 o0 Y    check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")% Q1 W$ ^1 S! c: `4 d3 {5 j! W
    check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")5 g" g6 O! f8 D( b% ^
    print(check_time_day, check_time_hour)
. \* ?! q1 d' p% G9 W. a. c4 ?3 p7 e# a3 V) [
    for metric in metrics_list:9 o2 M9 p2 c/ R3 [& p
        command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \
" Y9 ?) P% R. q( ]- G8 v8 R                  %(metric, check_time_day, check_time_hour, check_time_day, check_time_hour)* `8 ?) u/ n* s. I9 D* b
        file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)
' r9 X+ E* ^9 |! g        metrics = json.loads(file_list)4 Y, p9 {7 I7 [5 Z. n
        for key in metrics['data']['result']:
, J1 W0 V% a5 V6 t: w$ S; ~            # Mysql数据库巡检
/ r4 l6 x. b: W- k% ]7 l            Prometheus_job = key['metric']['job']* [* C9 y4 H6 x) M6 \4 f8 o' Q4 J
            Prometheus_instance = key['metric']['instance']
( U$ o. R/ I+ Y) M            for project in check_file_dict:/ I8 j" a, Y) J! J' y
                if Prometheus_job == project and key['metric']['__name__'] == 'up':
# ?2 F8 f1 o6 V9 }2 P5 ~. n7 M                    metric_dict = {}0 m# a, @# S, Q* \
                    metric_dict['instance'] = key['metric']['instance']4 E( F2 F+ Y" ?% h4 p2 X( k
                    metric_dict[metrics_list[metric]] = key['values'][0][1]/ P. X9 E8 k" ?& X

, P0 P" p: L  {# d8 W  [( I                    check_file_dict[key['metric']['job']]['value'].append(metric_dict)8 w; n- Y( U# X6 ?! }* O% i
                    # print(check_file_dict)
' `/ N5 A2 m) ]( P' r1 E( B* Y# t' I( Y( c9 O1 m3 X" ]+ p
                for instance in check_file_dict[project]['value']:2 ^# v) J: b. @- t' b7 S% e
                    if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:/ a- U  n9 m2 S  v2 B
                        instance[metrics_list[metric]] = key['values'][0][1]
9 z  a+ _! T9 W% B* h7 B% K
: o9 X# `' }8 g0 [
7 ~7 ~8 _: ~2 b, _, v    for key in check_file_dict:
( r! v2 f/ @) q" d        test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'( o3 d: A4 K' i% S6 G/ [
        print(test_report)% w+ Q6 \1 p8 H  O; Z, Z
        if os.path.exists(test_report):
( H5 P  F; j% N+ D) u& ^2 Z            os.remove(test_report)& P! X$ \8 J# j+ |8 q) l& ^4 g
        print(check_file_dict[key]['value'])
9 D; t; v0 b- E, ?# P        write_to_dish(pd.DataFrame(check_file_dict[key]['value']),3 N8 W& N- f8 E2 j% }
                      fileDir=test_report). w' `. v8 H. b9 ?
6 t! w0 V9 T4 X; s2 U2 c
        #发送企业微信机器人
! h6 ^% \% T1 a) U! N& ^        wx_api_key = check_file_dict[key]['robot_key']  # 这个地方写你自己的key
  B) Y$ c5 {! H; I2 N( ]        wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key)# C" B' o, [% D$ o3 x1 I8 W6 `
        wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)
$ D1 N4 ?, }" _6 l" }* i. `        media_id = upload_file(test_report, wx_upload_url)! l' E+ d" H9 O( t0 }
        qi_ye_wei_xin_file(wx_url, media_id)/ j/ K, A8 S9 B) h0 {& h
3 D0 n. O. M7 B- E
+ m0 Z# R- s8 f" }  u# A
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 00:32 , Processed in 0.014420 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表