易陆发现互联网技术论坛

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

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

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

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

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

x
- G# B! G: {6 D$ E& L( F
发送给企业微信机器人. H3 M0 ^7 g- V* b+ ^4 u" j2 n  t

" W' C! n$ Y* ]2 n. l5 _& r  [  V#  upload_file 是为了生成 media_id, 供消息使用8 @2 v' I5 h2 m0 @% f" h& ~5 a. o
! ~# z& P; M. s* u
# -*- encoding: utf-8 -*-
/ P1 O% y' u6 q* U7 ]! D' \import requests, paramiko, json, os, datetime
: o% K( o9 |4 U7 T# mimport pandas as pd
, b) ^% E( A  d0 ?: efrom copy import copy) ?6 p1 G( p- Y
from urllib3 import encode_multipart_formdata
; w* L) D# S' `! _2 E7 D& x
( K1 u. C2 i, t" d0 Mdef upload_file(file_path, wx_upload_url):( H, C! _9 }* I# M* m
    file_name = file_path.split("/")[-1]
1 m* F+ n$ \" k. ^, p* w    with open(file_path, 'rb') as f:( H( v$ o4 d- M6 M6 H1 a
        length = os.path.getsize(file_path); ^0 r" X. L& g6 B1 R8 T
        data = f.read()& ?( q- x2 k( n! u5 v% _
    headers = {"Content-Type": "application/octet-stream"}* I0 y/ a' }( u2 J6 Q7 V9 g9 h4 g) l( c
    params = {6 k8 d  b4 l8 I) J
        "filename": file_name,
  h# r/ z, }4 I; o6 F# l/ d* S        "filelength": length,& k, r( t8 N* q2 v( A# M' o
    }( m. d: L9 d5 e6 ]- l, i* b" s
    file_data = copy(params)
: m4 Y" U2 O. [0 m3 t    file_data['file'] = (file_path.split('/')[-1:][0], data)5 F9 S8 _  J8 ]" n: C
    encode_data = encode_multipart_formdata(file_data)
4 R; O: e" R/ a3 R+ i3 F( n$ B! X* d    file_data = encode_data[0], a  h* `! q4 F7 u' {
    headers['Content-Type'] = encode_data[1]/ `: o  e  f  E; j! \$ k
    r = requests.post(wx_upload_url, data=file_data, headers=headers)6 V7 A6 [' Z6 T6 m% q# r
    print(r.text). x' ^- b; }$ Y$ ^' Q' S
    media_id = r.json()['media_id']! o" G1 d1 W" y: K
    return media_id' n# v/ q& e) g; H; c! Q
# media_id 通过上一步上传的方法获得+ i3 w, M8 y/ f  P4 T8 ]9 h$ ?
; A4 b! T; o7 S, U% w* L4 |. A
def qi_ye_wei_xin_file(wx_url, media_id):. U+ Y' G& @) F; k5 f1 c
    headers = {"Content-Type": "text/plain"}
/ v' C: ?; ^% X    data = {
( b9 x; h+ X" E! s- n- t& w        "msgtype": "file",
8 r4 r6 V" @% A1 T/ N* j        "file": {- A( s1 E# \5 L& Q
            "media_id": media_id
: `' l8 V/ k# ~% {: F        }, f9 g7 }( C* b8 W' p
    }) F3 E$ Z( c. m: Q: K
    r = requests.post(. p6 R; W2 @; K) l; E8 B  _
        url=wx_url,1 D' F/ d4 r2 `6 u. |
        headers=headers, json=data)
' I- w9 |. Y" W- u# t    print(r.text). Y4 o1 l8 D* S
7 c# ?/ L+ |3 k
& F& j; N7 }5 c! e" B' \
/ M7 t! _& G. w0 m, I+ s' v
从Prometheus 上获取监控数据
6 @- N+ r" m( N' r* _$ o  v  ]; x5 B* [1 ~, Q
# 得到一个Overssh的返回值7 Y2 v: Z1 q# g7 U* v
def get_file_list(hostname, port, username, key_name, command):
$ l' t1 G: A% O- [5 _    ssh = paramiko.SSHClient()                       # 创建SSH对象
1 g, @; m9 f( Q1 G    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())      # 允许连接不在know_hosts文件中的主机
: V6 f* T0 m" \, T+ ?$ J    # ssh.connect(hostname='ip', port=22, username='user', password='密码')        # 连接服务器
$ v: m% j& @# I' x4 k1 O* {    ssh.connect(hostname=hostname, port=port, username=username,0 t( N. _' Y$ |5 G* ?% h0 i
                pkey=paramiko.RSAKey.from_private_key_file(key_name))                 # 连接服务器
- R" G6 I1 |  f( ~    stdin, stdout, stderr = ssh.exec_command(command)
! f8 Y8 o' [! p- B' I' ~: S, x, X) ?* e/ v! J
    file_list = str(stdout.read(), encoding="utf-8"), t/ C2 |" |& t8 \1 ?/ E
    ssh.close()  # 关闭连接5 W+ y6 o/ q! A6 n1 E

( ?9 M6 ^5 e9 W" g    return file_list
& h( y" T2 h+ J1 G3 r, P1 y: D/ L) F5 K/ P2 c0 d

5 [) H; B" {/ e1 }将PD写入到磁盘: R6 w) j8 j( A* R
! o% p- s+ R- v& D9 u2 i
def write_to_dish(results,fileDir):
& J& X) u$ Q+ l( H    writer = pd.ExcelWriter(fileDir)
( R5 \, D3 o& E; C$ ?' r- V    results.to_excel(writer,float_format='%.5f')
/ b' \* M% u# ~6 Q# p    writer.save()/ ^, J, S1 {0 k7 C" n/ u8 I. h
5 d$ W; _1 @* X
定义好需要查询的metric
$ W7 I( I5 G0 P, ]2 q$ K8 J; {5 t8 G
# 查询需要检查的数据,第一个必须为 up7 z% F2 D  h' d% Y+ J; l) ]8 H& f
def rds_metrics_list():
: v/ z3 C2 Z2 q9 O* i    return {'up': '状态',
& [$ R  k& @6 L                    'rds001_cpu_util': 'CPU使用率(%)',
  b) V0 h$ F* {; ~                    'rds002_mem_util': '内存使用率(%)',1 [  h4 r4 X' g; h% b. D, M, M  z+ s
                    'rds003_iops': 'iops',6 ^2 \1 c3 r9 K: ?5 _
                    'rds004_bytes_in': '网络流量入(Bytes)',
( F" Y$ G( Z' ~$ M# ~                    'rds005_bytes_out': '网络流量出(Bytes)',5 q0 u  ~% W* H3 q
                    'rds008_qps': 'QPS',0 Z/ Q3 d' q6 e$ D8 U1 y1 y
                    'rds009_tps': 'TPS',  e5 q: z0 ^9 T+ t" u3 p  n
                    'rds081_vm_ioutils': 'io使用率(%)',: z4 H+ W% M2 K' P# B
                    'rds047_disk_total_size': '磁盘总大小(G)',/ f: {. J, A  E
                    'rds048_disk_used_size': '磁盘使用(G)',$ a/ r* g/ I; C9 B  |) e3 a
                    'mysql_global_status_threads_connected': '当前连接数',4 C, N9 J! s9 M7 {: s3 V4 r' N; G
                    'mysql_global_variables_max_connections': '最大连接数',
1 u9 W7 ^3 M% h                    }( z" j* L, {) g

+ t! o; p2 B: S+ R
0 V8 q5 `% b2 d3 w, @) d) N) j) W& Y0 S+ }
Prometheus 获取数据落盘数据,并发送给企业微信机器人' z, d, T9 t( a) W
# o; L# t. e. p: H8 O2 S! W+ o" S& S
if __name__ == '__main__':
* V2 V6 n/ [) B! j& d3 _    # prometheus 主机信息, o* a: a% K4 t$ \! F3 N
    host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}
! o4 J1 _. N* `" P" ]1 v5 }8 j# |( Z  d    # 检查文件路径
8 w3 D7 l- g$ y    check_file_dir = 'check_files'
4 q1 c6 v8 A  J; O; C" X$ m' F. ]7 x! T3 {' V' K) |' ]
    # 检查文件时间,时区问题需要减去8小时
. F$ f: a4 Q0 _9 [( R6 p    curhour = -17  # 默认给-17 当前时间是-8.1
1 p% {" A3 X; z* X/ y2 ?1 `1 Z' l5 x. R& v4 n7 B
    # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人
7 V/ i0 m, q0 O' a8 k/ @% k
: }) S0 s$ q/ J    check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',
4 ]7 q5 f( d/ f' x                                            'robot_key': 'xxx'}}$ K2 C8 U0 f9 a) D7 X

6 [& z2 e0 N$ o% @    if not os.path.exists(check_file_dir):* v/ o* ~) Y3 {& k( V- y
        os.makedirs(check_file_dir)
8 n6 v, b; O" Z% v- }4 O
1 _% m$ v# V2 d# ^. s& _7 c0 u    metrics_list = rds_metrics_list()
2 P9 s6 K6 I: I2 C. c' D; {. ^
    check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")
! J: u5 o2 g+ v+ _: s    check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")8 ]6 v4 G2 L3 X/ f; t" a
    print(check_time_day, check_time_hour)$ A! ^9 G; F4 w# \  O
- l4 K! ]& B. I% e  F  \0 ?' Q( @
    for metric in metrics_list:
9 m- x9 ^- x3 L. ]1 y" z7 Q        command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \
( C3 F6 |9 {" L$ R                  %(metric, check_time_day, check_time_hour, check_time_day, check_time_hour)
* t) E- m! N* v0 z0 l; d" S* y7 y        file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)
8 T$ M6 B8 K7 ^' D8 b' D( G& G$ V0 G        metrics = json.loads(file_list)% w" x, L* X1 \  d2 a- ~
        for key in metrics['data']['result']:
- U- \; e! q7 z: E3 ]            # Mysql数据库巡检
6 V5 Q/ K, m: y2 X, n5 L% V            Prometheus_job = key['metric']['job']
! F+ P" i4 O$ d, |( p% R            Prometheus_instance = key['metric']['instance']# p# B  R% ^% E$ m* a+ {
            for project in check_file_dict:2 Z& x* z( X0 M. v9 S
                if Prometheus_job == project and key['metric']['__name__'] == 'up':
, o  x! L" Y. S, `                    metric_dict = {}- _* A1 D7 M& U$ f
                    metric_dict['instance'] = key['metric']['instance']& W$ Y: A! f" K" e& a7 B
                    metric_dict[metrics_list[metric]] = key['values'][0][1]( c! w, ^/ H) [$ m
' }( p( N6 _. i" f1 V
                    check_file_dict[key['metric']['job']]['value'].append(metric_dict)
" }5 ]% Y' t" |                    # print(check_file_dict), k- A  `# `: d/ J8 j
+ e/ }. `* h2 P: t) h2 m/ }6 T
                for instance in check_file_dict[project]['value']:3 W5 f# J+ X4 |$ I# N+ @9 B+ i; N( D+ p
                    if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:( r6 s  `6 V5 @
                        instance[metrics_list[metric]] = key['values'][0][1]5 U! u6 j8 `7 a6 v& X
1 w2 o3 ?) a0 y0 ^" q

( x# ]. T8 t- Y6 S6 _0 E) U8 g    for key in check_file_dict:
( g. L( Z' U& K& z$ n. j6 I        test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'  P6 D6 Y9 r% X
        print(test_report)
/ y! u( N; d, ]0 `) Z& C- z        if os.path.exists(test_report):8 `) |3 g3 [$ L, [1 j
            os.remove(test_report)% J4 H# q. Q7 e, X/ c/ z) m0 E
        print(check_file_dict[key]['value'])
) o0 W& f7 z! ?        write_to_dish(pd.DataFrame(check_file_dict[key]['value']),
5 c  E2 y( a6 L. C/ W  r: l0 T! d                      fileDir=test_report). t. U( m: S# k; s6 e/ J
& {, e4 y% G, _
        #发送企业微信机器人, B8 c7 X7 I" x8 p+ G
        wx_api_key = check_file_dict[key]['robot_key']  # 这个地方写你自己的key
$ W, W5 p( `7 A8 f1 O' X        wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key)2 F7 Q4 I0 s; M5 u. W
        wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)
/ ?7 H& F5 U  v1 ?8 }, e, W        media_id = upload_file(test_report, wx_upload_url)
' x  A& Q7 R5 u        qi_ye_wei_xin_file(wx_url, media_id)7 n  D) E% m: U; v) V5 w
. d9 l8 J) N+ L+ l* q" @

5 N' F7 W, o: j, C1 _! t
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

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

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

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

GMT+8, 2026-4-8 21:31 , Processed in 0.047390 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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