易陆发现互联网技术论坛

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

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

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

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

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

x
0 I* Y' |" O2 C6 C6 K" c. R
发送给企业微信机器人! |% a3 m3 w( N8 v' u7 K

- B+ ]  e: ^5 \% K( D, h#  upload_file 是为了生成 media_id, 供消息使用# M2 n6 {5 O$ i8 [# }
2 u' A8 \' w2 q+ x& W* p+ U
# -*- encoding: utf-8 -*-2 a6 N# a. p: k( e2 O6 @1 s. q0 w1 A$ C
import requests, paramiko, json, os, datetime$ ^1 l) v4 Z+ a" e1 `
import pandas as pd
/ J( B9 P0 H5 ufrom copy import copy
: h  v$ b) {4 Q, M+ y! @. Afrom urllib3 import encode_multipart_formdata" J" v8 z6 I  K5 r
: @! j& z) c3 N6 ?
def upload_file(file_path, wx_upload_url):% M1 z/ B- x. m9 S
    file_name = file_path.split("/")[-1]
/ X2 @1 r( B" p$ N  \+ Q    with open(file_path, 'rb') as f:( Z: v% l- c5 G  ?  E) `
        length = os.path.getsize(file_path)
8 v" A% u# [/ Q# \9 S        data = f.read(); m+ T" T4 a* }' p- N& E
    headers = {"Content-Type": "application/octet-stream"}
& p& u# W0 Q+ b- C# p8 p. `+ q    params = {
: @0 N( K1 m& e) \3 j2 {        "filename": file_name,2 \3 u0 P' ?4 v! x* p% ^
        "filelength": length,* ~" ~+ B$ Z0 E
    }
) X0 S9 e7 H, M3 Y* U    file_data = copy(params)
6 \5 X3 Z0 @- p6 J# r' c9 o    file_data['file'] = (file_path.split('/')[-1:][0], data)
) Z, y4 p, c4 K4 A% X    encode_data = encode_multipart_formdata(file_data)( Z2 V  E, f5 t4 w
    file_data = encode_data[0]
$ I7 U8 s/ n& T: v8 g    headers['Content-Type'] = encode_data[1]  q& p' l: t9 E; d; d
    r = requests.post(wx_upload_url, data=file_data, headers=headers)+ Z" H5 q3 ~. e0 }* q
    print(r.text)
/ h( G- F; ^7 t( O; q' H    media_id = r.json()['media_id']
5 N$ X  t; o3 g7 D) v' u8 _; g, d( m    return media_id6 j& I9 Y! ^: |5 ^; z) v
# media_id 通过上一步上传的方法获得
' r4 p. O$ H' j3 X( y8 c: Q1 k* P1 r, l, _
def qi_ye_wei_xin_file(wx_url, media_id):
1 f( s. n% g- C4 s% K6 F    headers = {"Content-Type": "text/plain"}
5 N8 Y! ]7 r2 F; m: h# _2 R    data = {
  r7 L: r. f$ i; w0 s, |        "msgtype": "file",
. ~( F3 n, }% T, B6 s- T% z$ C        "file": {
  \, T. u/ e' ]$ ^$ |            "media_id": media_id
* _5 x: s' C9 D$ Z+ ?) p: `, }        }; n% j8 [# [: ~$ x4 V& a2 Z2 G
    }& r$ R8 X" h# j0 t
    r = requests.post(
1 q8 H* f: f! S% X7 d        url=wx_url,
* V+ E0 X3 M8 s7 Z0 [$ e        headers=headers, json=data)
% r+ q4 M+ }/ T/ ?! Z    print(r.text)" R7 g: ~  U, I
  `& P* y0 _2 ^( ~
; \8 a# L  c. v. \
( l4 Q# l6 i% c6 o0 {" h* L: M3 y. o
从Prometheus 上获取监控数据' [1 a, v. C/ ]" I7 Z2 O8 N" r6 O# a( t3 h
. W5 t5 \& u& }/ W3 V& T
# 得到一个Overssh的返回值
  Z9 }! d/ q& S4 {9 tdef get_file_list(hostname, port, username, key_name, command):  d/ i2 S* }  k/ I) Q; b
    ssh = paramiko.SSHClient()                       # 创建SSH对象3 M: R/ V6 J$ ~; _0 N
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())      # 允许连接不在know_hosts文件中的主机4 x  K! a: t* N$ w( ^8 O, y
    # ssh.connect(hostname='ip', port=22, username='user', password='密码')        # 连接服务器0 ?7 g; j/ v5 }& d1 ?+ Q. k
    ssh.connect(hostname=hostname, port=port, username=username,( [9 @: `! S- Y5 g* l+ Q
                pkey=paramiko.RSAKey.from_private_key_file(key_name))                 # 连接服务器
3 h4 s' M' g! m4 l7 u, W    stdin, stdout, stderr = ssh.exec_command(command)
) a/ S8 |4 w+ ?# M9 Y! b$ ^# f" }  q5 Z2 i* K2 A6 e8 c) Y5 N
    file_list = str(stdout.read(), encoding="utf-8")/ A+ w* j, w( K" H$ U
    ssh.close()  # 关闭连接
9 b# l3 A, |2 \% Q& i8 P
& l- u5 z5 C, t( X    return file_list
( \( ^& E! B% Q9 C1 {: P7 `6 D1 w9 w  ^0 w! ?7 W
: W; c" \- j/ o7 j2 R& n
将PD写入到磁盘4 Q! N5 p* j/ j6 D5 k  V

% I6 Z/ M0 W" c, Pdef write_to_dish(results,fileDir):
. R- l" m2 z4 g% A* y: ]    writer = pd.ExcelWriter(fileDir)
1 s% e- K3 U$ b    results.to_excel(writer,float_format='%.5f')
8 o6 r) J/ c" P0 a3 k5 `    writer.save()8 t* \7 n! D" G% s

- J" ^0 g4 U* n( W+ H定义好需要查询的metric
) I9 T8 ^- k" d# T; s( \5 K9 F1 Y( [7 N. o+ H
# 查询需要检查的数据,第一个必须为 up$ D$ D# d* v3 q! n! W3 F8 V
def rds_metrics_list():5 K( \& Z* V0 b( c
    return {'up': '状态',
$ V4 ~* P  k& v  j) ~* ]' Y$ r6 |. e                    'rds001_cpu_util': 'CPU使用率(%)',5 s# d! r% e& n( ?: J9 B% K5 c
                    'rds002_mem_util': '内存使用率(%)',
  ^7 X2 r, T1 |) p/ |6 ~                    'rds003_iops': 'iops',4 f0 C# h! C  C7 J% A
                    'rds004_bytes_in': '网络流量入(Bytes)',
) a# B) j& x6 Q! [/ ]6 B1 h) }( S# H                    'rds005_bytes_out': '网络流量出(Bytes)',
0 [" k* ]$ R6 v7 S+ k& D5 D( h                    'rds008_qps': 'QPS',
9 ?4 E2 B( R$ Y# Z. T                    'rds009_tps': 'TPS'," @, Q+ g) I- A
                    'rds081_vm_ioutils': 'io使用率(%)',
: w3 k4 e. x% Q                    'rds047_disk_total_size': '磁盘总大小(G)',. T, B& d6 K% t5 V0 ?, G) m
                    'rds048_disk_used_size': '磁盘使用(G)',
# z. W0 {1 @# t% ~8 L                    'mysql_global_status_threads_connected': '当前连接数',2 f+ q+ l& r; h) ?
                    'mysql_global_variables_max_connections': '最大连接数',  a' q% ^. L9 C, ~5 ]; o& @
                    }# h$ f( i/ o( |1 ~
# l( W1 s/ \4 u3 r8 _- C* j: N  H
5 n5 h! a: O1 l: [8 m4 x- t/ I

& W$ J) k# S- [7 p5 |$ fPrometheus 获取数据落盘数据,并发送给企业微信机器人
/ H6 c9 ~8 Q7 ^- V2 j% _; S; t
5 A" s/ r7 }% {* o0 w/ Nif __name__ == '__main__':
, M& T  _4 Q& C& C. O4 g! {" v    # prometheus 主机信息
' \3 j) ?5 V. O& Y    host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}
' F7 k- Q2 X/ {8 @) |! X* R    # 检查文件路径& b1 E& D5 Q4 A) n. A
    check_file_dir = 'check_files'! P% q' R$ c# T
8 D5 ^- G& Q2 B$ q- e; A& u* B
    # 检查文件时间,时区问题需要减去8小时
7 ^& ]: b2 a  {    curhour = -17  # 默认给-17 当前时间是-8.1
) z9 D) q: C- x, n, Q
; r' l7 h* F$ ]4 ]; ?! f3 p    # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人/ p) Z. `6 b1 t/ i; _" J1 W# t
8 D% x2 s3 i1 R0 A% ?: G
    check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',/ x" c; Q! _: p6 Z  u; L
                                            'robot_key': 'xxx'}}
6 H) d+ g9 N1 N/ `- Q
. }2 G! Y2 {  v- l: t0 q    if not os.path.exists(check_file_dir):# B& }, i! R- c' i* T
        os.makedirs(check_file_dir). w) w6 ~/ _5 U: t( K/ \

8 v/ Z9 g% y6 q! u6 I' K    metrics_list = rds_metrics_list()
1 a' l4 A6 q$ v# O1 j# l! j+ S9 g' L+ w
    check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")+ h, }- z3 q1 h. [
    check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")
- l2 g' H9 t+ N" F0 z7 ~& D    print(check_time_day, check_time_hour)! Q0 K( U. a2 c& w/ h; }* e
- U) G4 ^5 G+ p+ r4 l( U1 `, D9 ~
    for metric in metrics_list:
  d$ F* e" N: |% E        command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \
& H9 G& U& E, p1 J* v5 I+ t                  %(metric, check_time_day, check_time_hour, check_time_day, check_time_hour)8 W! O3 \% k+ p6 I2 K
        file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)
4 C: H/ r, a3 M  e* d4 U, x$ s# F        metrics = json.loads(file_list)2 ]2 x2 G- B/ K! h% b
        for key in metrics['data']['result']:
* ^4 V5 M) `7 R, m( E- V: }7 n            # Mysql数据库巡检! C$ Z6 _/ `" N! \4 i- C
            Prometheus_job = key['metric']['job']+ v& H6 P) k% q6 W. b
            Prometheus_instance = key['metric']['instance']) ^' _3 J* z6 D8 }8 X# r) p
            for project in check_file_dict:
0 c+ R+ L9 N7 r  j                if Prometheus_job == project and key['metric']['__name__'] == 'up':3 C9 U: P( u' X2 R0 q' a7 L: \) @
                    metric_dict = {}, H$ O- V! S3 d$ ~( g9 a
                    metric_dict['instance'] = key['metric']['instance']" [- L2 \" [1 `/ P/ }2 r
                    metric_dict[metrics_list[metric]] = key['values'][0][1]
+ F% d; C( |/ E& r. ~3 g9 H1 W0 z& p) A: Q, s! v- a2 \* x8 C1 i
                    check_file_dict[key['metric']['job']]['value'].append(metric_dict)5 o7 Q( j% a4 q
                    # print(check_file_dict)
& }" v- c# t( y/ Y8 I6 h; p  [" c. t
. ~" u7 U) c0 E  g7 h4 P/ V                for instance in check_file_dict[project]['value']:
/ ^7 G& @& O3 v0 H' o6 [" U' ?                    if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:: V. }2 s5 H; q2 l
                        instance[metrics_list[metric]] = key['values'][0][1]
% t4 z/ C$ F0 Q1 T* G1 e; N  g5 W, Q

+ B" Y" T' ?6 B8 @7 y    for key in check_file_dict:' j4 W3 }9 h# o' ~9 q' g" t/ L$ r
        test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'* a' ]; M6 l% k
        print(test_report)
) n$ O0 Q+ u1 f! p! ~& K9 O        if os.path.exists(test_report):# s# Q" v0 N& w% T5 K* x
            os.remove(test_report)
$ j! t, s2 y0 N0 P        print(check_file_dict[key]['value'])6 Y9 k* T2 E" l' `! f" z4 D5 U* i  c
        write_to_dish(pd.DataFrame(check_file_dict[key]['value']),  L9 ?" ]1 a* |
                      fileDir=test_report)
) w- p' J2 C2 P  b! l6 l$ T4 ^2 r% `1 O( p8 n& \
        #发送企业微信机器人
. A6 D+ l) A6 r% a6 U, F2 C2 G3 P        wx_api_key = check_file_dict[key]['robot_key']  # 这个地方写你自己的key
$ h! |" I; j7 l' M9 k        wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key)
1 f. W0 _  a/ l+ W3 k. d! m5 B" z- E        wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)0 n: ], j$ y' W/ [  [% H! r
        media_id = upload_file(test_report, wx_upload_url)8 i( @% Z  t, v1 \* i8 e( J
        qi_ye_wei_xin_file(wx_url, media_id): ?; R) \- J7 t2 Q

4 q5 l6 o5 l9 r: P3 L6 l' ]5 `& \" w
$ Z4 z7 z3 |( G" U; Q& y
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

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

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

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

GMT+8, 2026-4-8 20:22 , Processed in 0.048540 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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