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

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2023-7-3 17:00:11 | 显示全部楼层 |阅读模式

" }" m# Q$ r4 _7 x/ v/ l- \发送给企业微信机器人
# e* K+ C4 H$ I! H
/ y2 T) i0 a' C/ A1 e#  upload_file 是为了生成 media_id, 供消息使用& I0 Q4 ~5 a' b" e+ C* H# m% i

5 b- e" f  K" K/ c# -*- encoding: utf-8 -*-! F7 n9 m2 W* p1 r3 ~7 N. c
import requests, paramiko, json, os, datetime: `$ G  f& m! u# l
import pandas as pd
3 b. e( K8 K0 s6 t! U# ^from copy import copy9 t; q& H: c7 K4 O7 v* }
from urllib3 import encode_multipart_formdata. A- ?  ]/ \: [) m7 B' k
: @) B; x% _* e. `
def upload_file(file_path, wx_upload_url):9 |3 Z8 J. S% B1 o
    file_name = file_path.split("/")[-1]
( E8 _. p8 G  A    with open(file_path, 'rb') as f:. ~1 ^6 z8 _' ?$ J4 d
        length = os.path.getsize(file_path)
  B  [3 q( G' p8 \' ?        data = f.read()
5 A$ H* |+ l0 U* d( q2 B    headers = {"Content-Type": "application/octet-stream"}
0 y; z& s& [! `; _1 F    params = {. ~; c9 w. k3 C# U
        "filename": file_name,! \* n6 k2 K: `5 V) u2 G
        "filelength": length,
( ^0 m' U# C! Y0 D! Y: E% Q    }& @/ `4 u7 `1 ~& Y7 `
    file_data = copy(params)
7 ?: y1 B7 F/ o; u0 K2 f- a    file_data['file'] = (file_path.split('/')[-1:][0], data)
: h; o7 S, C( s, B    encode_data = encode_multipart_formdata(file_data)
, R4 r, f8 K5 J. x! e% h    file_data = encode_data[0]
( P5 a/ {1 E9 i! f+ V    headers['Content-Type'] = encode_data[1]% S$ K! s7 l& u) v) G; E1 u
    r = requests.post(wx_upload_url, data=file_data, headers=headers): d+ ?  u1 S' S9 k4 ?4 K& Q1 P
    print(r.text)
& e. r  `$ E% Q) G: \3 |: S0 E- N    media_id = r.json()['media_id']
0 Y% K( U9 l# i; {/ `    return media_id$ q! K& L4 J% u' ]9 Q8 z
# media_id 通过上一步上传的方法获得
4 z& _! d0 ~6 m. }/ v4 W
) [: L/ ^* k# H" pdef qi_ye_wei_xin_file(wx_url, media_id):! }% J5 e  Z# o) f+ ]/ K
    headers = {"Content-Type": "text/plain"}
& o- j8 Y% C) E  h) y1 J4 L0 B" f& i    data = {* f9 V4 R6 D$ `" P
        "msgtype": "file",
1 ]+ s9 u4 `% U% e2 Z        "file": {
1 F* b6 ?& [% \+ f* v+ h, P            "media_id": media_id# S8 S! t( J& J" I& `
        }0 V  h7 @3 D2 m; K
    }
: K; Y6 e+ S1 |9 g4 w4 @, ~    r = requests.post(' n9 Z' |) t2 P; O$ }6 j" L0 P
        url=wx_url,
/ P& y3 K3 b' v        headers=headers, json=data)
; d" ]; b8 \7 m+ V0 o' c0 |    print(r.text)+ [; |! I3 z7 f, H+ b+ Z

( O0 a0 J+ t& o. W
$ f( Z) \1 U4 F: j. _3 S4 @" Q& k5 R  ?: l& z
从Prometheus 上获取监控数据
1 c! L4 T* U+ }" G+ G, I( z) T9 `, {- f
# 得到一个Overssh的返回值
9 [' L" O6 B6 f9 B( Rdef get_file_list(hostname, port, username, key_name, command):
1 }3 h. J3 j" Y9 G    ssh = paramiko.SSHClient()                       # 创建SSH对象
' @- \1 _1 I, i/ Q: o: W7 W    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())      # 允许连接不在know_hosts文件中的主机4 c: p' H- J. ~+ _+ p- _9 X
    # ssh.connect(hostname='ip', port=22, username='user', password='密码')        # 连接服务器
, g4 p, v5 {1 K  ^" d    ssh.connect(hostname=hostname, port=port, username=username,) H' p; ?2 d: V: ^5 s
                pkey=paramiko.RSAKey.from_private_key_file(key_name))                 # 连接服务器
: ?6 ^1 Z% M# Y7 \2 {: i7 _    stdin, stdout, stderr = ssh.exec_command(command)* Y% V0 T4 Z! C  e; Z
( d" P5 O7 n, C
    file_list = str(stdout.read(), encoding="utf-8")
# T2 e% b! ]: ?* B# V    ssh.close()  # 关闭连接8 Y+ |9 ?' s& Z! `

. T4 C3 M0 }; M/ B- N, t9 g    return file_list
  Y. W- U" M% _5 |" I2 n- D( t2 `0 Z- M# D  x; @* k; n
$ u) z  ?: {# Q' ]* t1 A
将PD写入到磁盘
5 Z# l1 j+ U1 V% [/ H) Y: _# d) a0 }3 A& b  \
def write_to_dish(results,fileDir):
& @  t( z, ^2 S# J" M    writer = pd.ExcelWriter(fileDir)! y5 r; T' |- b$ w$ S
    results.to_excel(writer,float_format='%.5f')
. f- T8 |+ q0 z    writer.save()
5 m6 S! I$ E9 {4 f: ?/ r
0 j4 {/ V7 {- C定义好需要查询的metric$ ~- x# O* h7 T0 {

0 q5 o- R) J8 i' [# 查询需要检查的数据,第一个必须为 up# z4 P; _7 M' E2 G$ U& e
def rds_metrics_list():* k3 h) Y' A" o- G
    return {'up': '状态',
- `2 n2 {3 i, S' A3 r                    'rds001_cpu_util': 'CPU使用率(%)',
& L9 v& @7 H( J* L/ T9 G1 |" u                    'rds002_mem_util': '内存使用率(%)',0 T. d' T5 c+ y/ H, j! @, R! Y  }
                    'rds003_iops': 'iops',/ ?' |$ _# C  V' T* R
                    'rds004_bytes_in': '网络流量入(Bytes)',. `( I) S# [, j9 b/ V" R
                    'rds005_bytes_out': '网络流量出(Bytes)',/ A5 U/ g6 L! v- m! Z5 ]9 @
                    'rds008_qps': 'QPS',
* ~; f: x; O: F/ f& j                    'rds009_tps': 'TPS',/ H9 r' n) l! R4 v# \8 I
                    'rds081_vm_ioutils': 'io使用率(%)',) G& K5 E$ N0 [% `; M' S
                    'rds047_disk_total_size': '磁盘总大小(G)',
" y3 o8 J1 q0 L0 g+ X5 k. }) D                    'rds048_disk_used_size': '磁盘使用(G)',
& U0 L, U5 @. U/ {) m9 y                    'mysql_global_status_threads_connected': '当前连接数',
. J/ k5 e4 ~, p4 Z3 i                    'mysql_global_variables_max_connections': '最大连接数',# X; \, e5 c. x  ]5 ~3 A$ u& y
                    }9 ~' Q9 K: b! B
& F1 G$ o* w; h
6 g5 |& a5 l+ r0 w$ m' r/ ?' h* ~

* b: y  \1 h2 s5 m0 P9 h! _Prometheus 获取数据落盘数据,并发送给企业微信机器人: J( K. L# O9 [9 X& `

. t# W8 R3 {# p# kif __name__ == '__main__':  P) G1 `9 x" q# l% e; J4 H
    # prometheus 主机信息
: z9 w0 K+ l# P* I    host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}
7 A+ m3 M  S& Y    # 检查文件路径" a( L; P) _" p
    check_file_dir = 'check_files'
9 j' O( G+ M1 C  C8 v, c' e5 O; N
2 @; V7 T! ]' w    # 检查文件时间,时区问题需要减去8小时
( b8 m5 ]  g' V' U7 p  e+ e    curhour = -17  # 默认给-17 当前时间是-8.1
1 V- t, Z% ?* Z% r( }0 _4 W  o) |. r/ ^$ F. o4 X/ s
    # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人* ^/ G# B1 H. W# i7 e& H
+ t" A% x8 h5 Q" w2 Q, \
    check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',
5 J; w" H; A2 w% ^0 h                                            'robot_key': 'xxx'}}
0 A) Q) A7 `4 [* C- ?' [! K
" Q" T  e" J0 P8 x    if not os.path.exists(check_file_dir):
/ ?/ N" K4 @: B) f; T        os.makedirs(check_file_dir)$ J! u  q6 h# @$ ?  z

  ?" M: l( |4 @& F* T: w+ C: [1 |    metrics_list = rds_metrics_list()' V0 f1 f7 M6 p2 j, o
7 a3 Z# g! D3 u, l2 P$ i4 x8 W
    check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")- j$ V) H; Y3 a) x  F* \
    check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")
4 H) L7 m. ?+ [3 s    print(check_time_day, check_time_hour)$ T9 Y2 n+ t! m. O4 @7 i

. Z6 o: Y! v7 [) h4 k    for metric in metrics_list:, x9 f1 ^4 x4 ~; u
        command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \& d  L2 t4 A7 v1 a, X% m
                  %(metric, check_time_day, check_time_hour, check_time_day, check_time_hour)# f0 ]( X: m' B7 z
        file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)
* j. P0 {# r' z        metrics = json.loads(file_list)
( M( S# c0 ?- W. X) |& Q! I* a        for key in metrics['data']['result']:
) [( o- F( C+ ?8 K. z            # Mysql数据库巡检
3 \; V( {0 v3 X6 |& `# O7 V            Prometheus_job = key['metric']['job']3 v  h) i( a' t3 }  a: Y
            Prometheus_instance = key['metric']['instance']1 B% C# g3 [' C; t$ N; C, y) @, X$ L
            for project in check_file_dict:' x2 W6 }7 u" C
                if Prometheus_job == project and key['metric']['__name__'] == 'up':
, A$ O: Y% F! M# o                    metric_dict = {}3 `" D: J) L) t: L- j6 [
                    metric_dict['instance'] = key['metric']['instance']
) W: Q& b" m2 {5 Y* W# W4 r                    metric_dict[metrics_list[metric]] = key['values'][0][1]
' H! u4 G' ^; \# a: p0 {
* X3 u5 h7 V) d/ W0 A                    check_file_dict[key['metric']['job']]['value'].append(metric_dict)
) Y9 \  \+ q, ]9 \# T                    # print(check_file_dict)
3 D* S& B5 U( v& C
9 S. I( l( i6 r) p/ H                for instance in check_file_dict[project]['value']:: o- u% _" P9 n4 E
                    if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:* n' v2 U4 X2 ?4 Z
                        instance[metrics_list[metric]] = key['values'][0][1]
7 y4 Q5 C: G2 _# ^& W& ?4 f
1 u& q- m% S2 I# ~: g  v/ |' f) `
! M! ^) y# W! x    for key in check_file_dict:: R- r  c( G# `% p# ?+ E' M$ F
        test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'
% J0 S9 y9 k* r        print(test_report)
) B( ~5 X, _$ b        if os.path.exists(test_report):$ o/ F2 R$ X( s& N/ j+ W( ^
            os.remove(test_report), }, A$ ~1 j$ z: B
        print(check_file_dict[key]['value'])
+ A& R' ?% z* L5 l2 `) \        write_to_dish(pd.DataFrame(check_file_dict[key]['value']),
% X- |' `, U9 y; k( L                      fileDir=test_report)! h0 ?: `, q! \" n2 N% i) J0 X

5 L5 J% F1 o& Z, o  N3 J, p( t* d* g        #发送企业微信机器人
2 j8 u# ~' K1 b  L5 l        wx_api_key = check_file_dict[key]['robot_key']  # 这个地方写你自己的key
8 y# }) l$ }% b1 W) d        wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key)
; [* j" J# Q1 v! Z1 X2 }        wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)
$ i6 p: _' Z( R) M) l/ c/ D        media_id = upload_file(test_report, wx_upload_url)) E- e5 c- Z# `9 l: Q
        qi_ye_wei_xin_file(wx_url, media_id)8 l8 j, x% X/ B- c+ `

3 v, t6 t7 M2 }4 Y% I0 y6 @5 ]6 ^! x
) ], J1 I! d  B  g( ?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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