易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 528|回复: 0
收起左侧

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

[复制链接]
发表于 2023-7-3 17:00:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x

& }2 U+ y2 [9 v" E: O发送给企业微信机器人; e2 h: c% p2 w) F6 ^; ]2 K  h
- \6 I. N( `+ J/ ]4 x' }
#  upload_file 是为了生成 media_id, 供消息使用
. ]* k! h. Q) R3 I! F- E/ V+ G8 l7 s& @6 ^6 z# o4 ~( [9 g
# -*- encoding: utf-8 -*-
9 U. m  b/ T. }1 G2 limport requests, paramiko, json, os, datetime
" a$ x* w5 ?% Q# H! }import pandas as pd
* L/ m' f/ i  z" \5 Xfrom copy import copy
# V7 y" j8 h4 V; x: z$ w1 {from urllib3 import encode_multipart_formdata1 K* Q6 E1 n( K3 c& Q& f8 V: U
( Y, R; n5 {  n% P# Y) |+ N9 f
def upload_file(file_path, wx_upload_url):
" V0 l' p' f6 r    file_name = file_path.split("/")[-1]
: N7 L7 A# x$ {' U  ]    with open(file_path, 'rb') as f:$ ~4 ~% d1 R( w! m. S3 P/ ^
        length = os.path.getsize(file_path)
! W$ R) F) b3 w% {1 m        data = f.read()# O4 F. N7 a# }2 k. X1 S
    headers = {"Content-Type": "application/octet-stream"}2 W6 z, U5 W/ C/ Y
    params = {
) y- W/ L7 q% F* c1 _% _1 Y( [        "filename": file_name,- i- ]- o, G4 ?8 f3 r) h
        "filelength": length,3 B3 f. [" g4 |3 ~
    }
2 u0 H4 V8 V5 G# T8 d    file_data = copy(params)$ |$ @( U! K0 q2 T0 X' [4 K
    file_data['file'] = (file_path.split('/')[-1:][0], data)
( H1 ]7 M" y9 B9 }" p3 m    encode_data = encode_multipart_formdata(file_data)$ _1 Y7 X: \& f' g# f
    file_data = encode_data[0]+ [- @# h$ ^; A* _4 N) a
    headers['Content-Type'] = encode_data[1]0 S4 w, {: _" O4 o
    r = requests.post(wx_upload_url, data=file_data, headers=headers)
& L" [8 K1 n8 C; n4 O# Q, \2 O    print(r.text)
5 k9 N& s4 C( C, H    media_id = r.json()['media_id']% P) w3 \3 H6 X7 ?
    return media_id
% Q' k7 }% z( u# media_id 通过上一步上传的方法获得
" _0 R2 \2 A8 r# q- k6 b/ h8 F- j0 \
/ {2 y/ d" h. t" h) w( Xdef qi_ye_wei_xin_file(wx_url, media_id):+ f0 A* H3 @# w+ K  Q* c7 C
    headers = {"Content-Type": "text/plain"}
: f$ {6 J# z6 a( N    data = {
0 F0 \9 D# H) m1 w: A1 C$ K0 D        "msgtype": "file",# T4 n  N7 {3 F: W9 t
        "file": {
, {8 N- K# a9 E3 k  g' x& e) |            "media_id": media_id
& W3 M7 G: J9 \  B( a        }2 J+ C/ S: O0 j8 z3 X& {2 ]; U
    }$ ]+ e* x5 ^( v( d% _) Z0 P4 m
    r = requests.post(3 p9 K3 K/ ]1 M3 Y: a4 i
        url=wx_url,
% p# n2 X/ b6 j% w* _        headers=headers, json=data)0 q8 l& v6 y0 P. f2 o  I8 i
    print(r.text)
% m6 P' K4 a, K2 n7 d- q0 b1 V- Q: _7 r8 G7 l  o
" Q6 x1 u% m& M/ g8 F% m( Q) L, J
, A) _9 P- {$ c( x0 o% }; K2 D
从Prometheus 上获取监控数据
. E* |0 D& u" t: |& H6 Q
3 j  U3 X  ~& V# 得到一个Overssh的返回值- r. _: M: d+ a1 i7 q
def get_file_list(hostname, port, username, key_name, command):
5 L2 U6 ^$ B' M/ ]: d    ssh = paramiko.SSHClient()                       # 创建SSH对象
0 P  K0 S' K* P* g) d! `7 J& ^    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())      # 允许连接不在know_hosts文件中的主机
( w+ [! ~$ I9 U* c: A& n    # ssh.connect(hostname='ip', port=22, username='user', password='密码')        # 连接服务器2 v/ S: b0 s+ \' t' b5 s
    ssh.connect(hostname=hostname, port=port, username=username,
, B% R/ S; n) g% o' I4 {( g                pkey=paramiko.RSAKey.from_private_key_file(key_name))                 # 连接服务器, `; d/ y3 w; L7 n& J
    stdin, stdout, stderr = ssh.exec_command(command)
. M; |2 q0 y9 l# u- u$ l1 x" y; ]6 r* t! O2 t4 d3 o
    file_list = str(stdout.read(), encoding="utf-8")
2 ?$ f* s( X2 R- l3 D    ssh.close()  # 关闭连接# H, D) z" R2 {; P+ p' M: U

$ g3 n5 {$ ~! ]. \3 F) g    return file_list
% d! G; h; H- y5 Y: k: u* i8 S$ v
3 Y. W5 R( c4 e5 r  r1 w" X- S3 N
2 e/ Z3 @! `1 e5 }% [& Z( P将PD写入到磁盘- P  _; d6 H/ p& b: C

$ Y4 A4 O% L/ k$ ]. N& k& \7 Idef write_to_dish(results,fileDir):
9 a3 g3 m2 x/ z, p    writer = pd.ExcelWriter(fileDir)
; h* n3 b4 J# s    results.to_excel(writer,float_format='%.5f')
9 R0 J+ P/ n2 z    writer.save()* C- }& J$ [% z( r+ e3 r

7 X9 T" M9 s& d2 v% x  x' F$ z定义好需要查询的metric" R% b  Y9 }' c3 H) Q- X

' ]1 e8 W& r0 @) P" w7 ]/ l# 查询需要检查的数据,第一个必须为 up0 ^4 M% e8 R5 l5 U( G) k8 Y
def rds_metrics_list():% B' |: D$ I! O% }" X
    return {'up': '状态',7 |8 g% R. b% [
                    'rds001_cpu_util': 'CPU使用率(%)',/ I# e. b! y7 g" q2 x
                    'rds002_mem_util': '内存使用率(%)',. U' e" D+ z. s- Q3 j
                    'rds003_iops': 'iops',6 c1 d- \5 _7 ^
                    'rds004_bytes_in': '网络流量入(Bytes)',
1 E1 {0 v; G# m/ S. ?  h$ S. }# {- [* }                    'rds005_bytes_out': '网络流量出(Bytes)',. d, T' l" u( h' P9 Z) p# I
                    'rds008_qps': 'QPS',! c0 z7 V; F* \. B2 }
                    'rds009_tps': 'TPS',
; a. Z/ t( Q$ w4 t! i  O                    'rds081_vm_ioutils': 'io使用率(%)',3 t* e1 T3 G- C$ ~6 ~6 W9 P. u
                    'rds047_disk_total_size': '磁盘总大小(G)',
! ], a" y2 J# v5 o( Z                    'rds048_disk_used_size': '磁盘使用(G)',
" T9 g( t- s# k+ |                    'mysql_global_status_threads_connected': '当前连接数',
3 N5 d8 c8 l4 V) l$ A                    'mysql_global_variables_max_connections': '最大连接数',
$ j* N7 m) h- l* G. G5 H( q% ^                    }
1 u3 T) M: P3 _3 n, \/ ^
; u* {  h2 M/ l& z2 `
2 c3 }5 U9 j- D( I3 a1 p) k3 m; }/ |2 K
Prometheus 获取数据落盘数据,并发送给企业微信机器人; F6 ~3 Y3 o0 u9 \2 o; K
8 R4 C5 \- o/ V# u2 F9 l) N
if __name__ == '__main__':
% O& f; e, q- i% N/ m    # prometheus 主机信息3 ~) m+ d: `! g
    host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}
. w+ {# e+ x3 G3 i2 _; v$ \    # 检查文件路径
4 @! M: k& J! {  y/ u+ y4 V    check_file_dir = 'check_files'# Q; j, l3 U* V( L& R2 R

8 M# n* s* i6 q    # 检查文件时间,时区问题需要减去8小时
, b1 E1 f* _% |/ a- |' C4 t# a' n    curhour = -17  # 默认给-17 当前时间是-8.1
. l( j$ L% S' J( S, G) U
0 V) ^( [$ H4 e7 F, |) I3 U+ J    # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人3 p% `6 g+ O- D; ]  z! r; ~) v' ]
5 u: |3 b% H/ Z/ v( C
    check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',
# ^1 H* W& z4 Y0 m) B                                            'robot_key': 'xxx'}}# B- ?  n8 I) L$ [! C( k, z- R; ]

! a2 r4 _( }7 a    if not os.path.exists(check_file_dir):
: i/ t$ H- l# t& S& Y        os.makedirs(check_file_dir)
. ^4 f) t+ G9 z/ w- ]/ S
, ]7 |, A7 n3 ^; D1 h    metrics_list = rds_metrics_list()
% E. z, ?# f( q0 r# {9 z! h  D$ B9 j5 h3 U  E' ~' R4 b' t% s
    check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")
1 T; c4 q6 f/ F% d# q    check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")
* u1 E6 D/ Q5 w8 C" z    print(check_time_day, check_time_hour)- F5 x! f( q/ {* Y7 V7 n

) L' a; A. k0 ?0 v+ p    for metric in metrics_list:
. \1 {( O& n, K# G. B, ~        command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \& }$ |+ L* q/ l- X7 T# X
                  %(metric, check_time_day, check_time_hour, check_time_day, check_time_hour)! J4 b5 m; k& _3 n
        file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)3 }5 a, }( |* w% z2 t# {' m+ J1 J
        metrics = json.loads(file_list)* V0 j$ e5 h9 j
        for key in metrics['data']['result']:8 j6 V% x. x; q/ g7 H% m% W8 C
            # Mysql数据库巡检
5 a1 I; I  x4 V0 J7 S! n            Prometheus_job = key['metric']['job']
1 ~. p4 ^: o$ n& [            Prometheus_instance = key['metric']['instance']
8 g0 u* ~6 G4 U            for project in check_file_dict:
: K5 i' @' N6 Z( Z                if Prometheus_job == project and key['metric']['__name__'] == 'up':
& V1 L' B7 O5 Q9 ?                    metric_dict = {}
$ o0 f+ ~$ I( R+ E                    metric_dict['instance'] = key['metric']['instance']$ Q- E. [* m8 u7 V
                    metric_dict[metrics_list[metric]] = key['values'][0][1]- |# F% G) C& E, b

# a; @* ]& v' ^$ w6 A. Q2 \                    check_file_dict[key['metric']['job']]['value'].append(metric_dict); N4 o+ Q) q' A1 t5 F" s
                    # print(check_file_dict)& x. {- j! B9 Z0 a: i' ~

% p8 K7 ^! e+ J3 j0 P5 X0 w  A* J                for instance in check_file_dict[project]['value']:
  _) {) e6 _" e9 @7 _. _                    if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:5 o0 C2 y7 q' g- ~8 v
                        instance[metrics_list[metric]] = key['values'][0][1]
) o7 L) g* o- O- E: |
$ Q, f  R1 {8 L& p+ G# K% h/ t& ~1 _7 o% _
    for key in check_file_dict:
% m# l( k- [+ L        test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'8 F7 M) {0 p* f* p/ n0 V; a
        print(test_report)! S" G6 m" d- e8 C! Z; M1 Z
        if os.path.exists(test_report):( L6 z5 ^1 w, `4 H" m/ \
            os.remove(test_report)
3 W+ [( Q( m8 l/ c        print(check_file_dict[key]['value'])
; H3 Y4 V# \; W& d4 q- o        write_to_dish(pd.DataFrame(check_file_dict[key]['value']),
1 e( h! l; ~3 a9 j: ?: O                      fileDir=test_report)7 K3 a# [0 y! _2 y7 \. ?2 I8 X5 S

% E) S/ J9 x1 @/ j, E        #发送企业微信机器人
) I& u  f3 j. S9 o* k        wx_api_key = check_file_dict[key]['robot_key']  # 这个地方写你自己的key
1 v" i: g* I/ z' `' S1 q6 g- g        wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key); O' r: B, K: I1 R
        wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)
' [+ M! ]: J- }& N3 h8 d: Y        media_id = upload_file(test_report, wx_upload_url)
- X* X7 \; q$ J  c5 b& `        qi_ye_wei_xin_file(wx_url, media_id), m; C. e6 W9 n6 A. Q; g# u

: k0 K- a+ E: S6 d) U% \* E9 ~1 s
0 z3 e0 _- \7 _* l5 `1 l$ b0 B
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )点击这里给我发消息

GMT+8, 2026-4-9 00:03 , Processed in 0.055212 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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