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

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

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2023-7-3 17:00:11 | 显示全部楼层 |阅读模式
+ q# i% d: r/ F! d3 @6 B, l
发送给企业微信机器人) U! q/ q2 v0 {: {$ m3 }
7 ]- c; H) Y6 j6 b0 _+ I0 f( x/ `
#  upload_file 是为了生成 media_id, 供消息使用" ~, I8 I; F8 b4 l

8 E4 o; l! H7 x2 |# -*- encoding: utf-8 -*-
+ S1 O# r" E* aimport requests, paramiko, json, os, datetime
8 f# Q; T1 r, Y+ himport pandas as pd
3 ]3 L$ ?, d8 \) F1 }4 Sfrom copy import copy/ L$ ?/ P7 e+ [4 w! T( \
from urllib3 import encode_multipart_formdata
# _  j6 \2 T1 ^1 x* `" S" {# ]  H9 @6 N7 z( M  Y. X
def upload_file(file_path, wx_upload_url):  W8 q- q% `& f% B1 ?! ^& c
    file_name = file_path.split("/")[-1]0 ]: H* @) w# U, u8 _$ A  D# R
    with open(file_path, 'rb') as f:) S! x  T) |5 E1 o' t0 _
        length = os.path.getsize(file_path)
& A, R/ M& y  z& X0 y        data = f.read()
* O5 n5 ~# {( l) P    headers = {"Content-Type": "application/octet-stream"}+ D% X' t4 c: t$ R
    params = {, W: y" H' Y2 B" E# s. n
        "filename": file_name,
+ Y3 D9 X8 C. _, @        "filelength": length,
2 u/ o" m  R- C: ?2 p    }
- h, Q% _! b4 }4 Y    file_data = copy(params)
9 o9 G! E9 P, y1 u5 u" D4 f% x    file_data['file'] = (file_path.split('/')[-1:][0], data)
/ t& ~" J/ H) o+ A* n1 h. h' W0 {+ H    encode_data = encode_multipart_formdata(file_data)4 f3 i" z% S/ I0 F0 ~: u& z7 D
    file_data = encode_data[0]; j* V4 C: T1 \( z) `, Z* x
    headers['Content-Type'] = encode_data[1]3 w9 ^3 k6 C, q8 q" d
    r = requests.post(wx_upload_url, data=file_data, headers=headers)
" X2 V0 J- @7 H' A" j4 K/ e4 y    print(r.text)
/ M/ ]( p0 |! D+ e0 y( F! y    media_id = r.json()['media_id']  V4 F# r# {- t7 a
    return media_id
9 z3 k8 p# p; E4 M# media_id 通过上一步上传的方法获得
  `1 [+ s/ a3 w' Z% O1 O' j5 `9 |  k  y% ^" L- k) X
def qi_ye_wei_xin_file(wx_url, media_id):0 W3 Y3 B; j9 Y0 ]& W$ l. V. ?/ i
    headers = {"Content-Type": "text/plain"}- n9 V9 e' z4 m8 W
    data = {
, p! x" |: |& i: h5 e* L        "msgtype": "file",4 S( d/ f" W( A; S: b
        "file": {
$ [. P& o+ ], L% |: Z# Z: X) y            "media_id": media_id. g* }2 n  ?% z
        }
; @5 k& H& v- V# p    }
3 O# u9 u5 r" T: u    r = requests.post(
) C6 U# h9 a$ n! E: r$ y+ m        url=wx_url,
" G- L* Q+ N! u" h# g4 {; O8 D        headers=headers, json=data)1 {9 r6 A  C1 w9 Z: {
    print(r.text)* \  Y* y  I2 F! R9 m

' `6 {5 _( h# V5 z' V9 E% h: x! @- e4 S* N

, }0 P( A+ k5 D$ @2 \8 m从Prometheus 上获取监控数据$ A2 y( A7 F: F" a4 R

: J- h9 w. y7 ^1 u! O/ U! w# 得到一个Overssh的返回值+ s' \/ j& j0 u6 D. z
def get_file_list(hostname, port, username, key_name, command):
; s7 K# Y: l( g+ J1 n  X    ssh = paramiko.SSHClient()                       # 创建SSH对象8 t; c* ?8 @& m6 G& Y7 F0 z
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())      # 允许连接不在know_hosts文件中的主机4 h2 |9 A  @2 d2 t/ `0 p0 n, t
    # ssh.connect(hostname='ip', port=22, username='user', password='密码')        # 连接服务器
- t& m7 C: E8 J7 G    ssh.connect(hostname=hostname, port=port, username=username,2 x4 z% u5 X# ]% g% ?1 r" T2 n, A, Q
                pkey=paramiko.RSAKey.from_private_key_file(key_name))                 # 连接服务器0 A* D4 `: U; x1 n5 Z  W; v
    stdin, stdout, stderr = ssh.exec_command(command)7 }$ c# B3 v% u7 B

4 }; }  E  j4 Z0 [) j. e) h. j    file_list = str(stdout.read(), encoding="utf-8")
% p! v$ Y9 w) K- D# o    ssh.close()  # 关闭连接9 @2 Z4 R: ^  Z7 q  n

0 [$ p& [8 `7 h5 j3 O# ^9 |, ]    return file_list. k# j! B5 I% Y% B+ I9 e8 t: c

# l! O1 x* s. K
# O9 X1 a) r* x! l$ k# B4 t将PD写入到磁盘# I0 e* r8 Q: o  I4 Y6 t' m. F

; k% S5 L0 `. n8 m' L7 ?def write_to_dish(results,fileDir):
$ I. p6 X, _4 s# i, a3 O    writer = pd.ExcelWriter(fileDir)
/ ~, b1 t% P+ y4 g    results.to_excel(writer,float_format='%.5f')
2 Z2 D" e) {) T& G4 J    writer.save()/ a4 i/ K" Y- k, T6 {8 M

: \/ {8 Y6 Y/ p; o$ ~3 w* u2 e5 U( V定义好需要查询的metric$ s! ^0 W1 S3 G8 X8 e- E* D8 `
% E9 f2 |$ B% @5 @9 P5 {$ P
# 查询需要检查的数据,第一个必须为 up
& D; E. P& n! W: qdef rds_metrics_list():: c! ^# [7 i7 h" P1 S  Z/ p8 `
    return {'up': '状态',' Z9 {. b+ i3 \7 m# Z
                    'rds001_cpu_util': 'CPU使用率(%)',' H; A4 I' O3 N1 }7 z$ S
                    'rds002_mem_util': '内存使用率(%)',
0 R" E2 f# |  _7 Q- x                    'rds003_iops': 'iops',/ Y' ~( A+ N% X
                    'rds004_bytes_in': '网络流量入(Bytes)',9 Y' W5 ~) _# p
                    'rds005_bytes_out': '网络流量出(Bytes)',
' U: S2 r2 k# P; x8 B+ h; y4 o                    'rds008_qps': 'QPS',5 K' d; g. i+ p. p$ F) _" I( C
                    'rds009_tps': 'TPS',
5 }7 O% p. S2 u. R2 l& Y                    'rds081_vm_ioutils': 'io使用率(%)',. j; S! N7 s3 [9 `
                    'rds047_disk_total_size': '磁盘总大小(G)',
) h7 P3 Y$ U2 w" e9 M                    'rds048_disk_used_size': '磁盘使用(G)',8 y. {9 j) @3 N
                    'mysql_global_status_threads_connected': '当前连接数',
: D8 g6 A& z: n9 O                    'mysql_global_variables_max_connections': '最大连接数',' @) ?4 Y- \& k& y
                    }
! g0 q- U" t8 c7 R3 `# U# M, s# X7 B. c
' c6 r0 F! J. W: H" b

9 V1 y& z+ t, \7 D. f  LPrometheus 获取数据落盘数据,并发送给企业微信机器人
5 |2 [9 X6 S0 f$ V, N6 [$ ?( D6 s3 O& w
if __name__ == '__main__':
3 P0 g; }( r5 I( o1 j    # prometheus 主机信息- F% }* U; X, C6 n
    host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}
2 e- G1 @' V8 u' g    # 检查文件路径1 f" T" `3 z5 N, e8 @
    check_file_dir = 'check_files'
4 y( o, P+ H  p& u
& f* ~- p% S# P. h    # 检查文件时间,时区问题需要减去8小时
% t& H) e; Z0 }    curhour = -17  # 默认给-17 当前时间是-8.1
- g; A+ i+ X7 k5 r: L4 p5 S' ?: @% `" @! u% J
    # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人; C, L& d6 ]0 r1 w! n4 F% g5 d' x
1 U8 V5 l8 U' Y/ k: O7 B2 j
    check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',5 {, T& N1 u& x; v
                                            'robot_key': 'xxx'}}/ U6 f& m6 R! B

/ \0 I) J& g, e8 d3 `    if not os.path.exists(check_file_dir):
: b2 x8 P; x8 p4 b0 h: J, V        os.makedirs(check_file_dir)
" H) W7 o- C  W7 n- q8 L0 T7 X" L7 o: W9 v
    metrics_list = rds_metrics_list()6 P7 Y) i. Q5 C2 C% b: g
' ^  z2 x  S7 m& q5 K- L) Z: j3 w
    check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")" N# N, z, C* a+ `
    check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")9 F2 g/ g3 v$ P4 G
    print(check_time_day, check_time_hour)
8 B3 [( g0 _( C9 U7 Z  v6 u6 t
( @8 Z! p( c. N    for metric in metrics_list:6 b; Y; P1 {% J- B# L) T
        command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \2 y# O$ J* a. k" v% n5 S0 R; g
                  %(metric, check_time_day, check_time_hour, check_time_day, check_time_hour); I% D' O3 M# o! ]9 r& }
        file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)
  I# B# G" `) N4 [: l        metrics = json.loads(file_list); K0 r. Z" P+ r( z* G! J. s
        for key in metrics['data']['result']:
, j5 R9 Z; l' k9 O2 U+ f( |            # Mysql数据库巡检+ X- k2 o% q! e! r8 T$ R
            Prometheus_job = key['metric']['job']
+ \! s" J# e0 x& K  i            Prometheus_instance = key['metric']['instance']7 D9 c1 }! n, a5 T3 c* A
            for project in check_file_dict:% W+ O. D  D0 z  _8 [4 ^$ A
                if Prometheus_job == project and key['metric']['__name__'] == 'up':) F8 H3 S, g( L0 B4 j  w3 r
                    metric_dict = {}4 u4 P+ |+ Z/ f: f+ J' K0 n2 ?0 ]
                    metric_dict['instance'] = key['metric']['instance']( A3 P, U9 t3 D4 `( m
                    metric_dict[metrics_list[metric]] = key['values'][0][1]. X6 n% @4 _. Y

8 u( R2 f. G% l' E2 i                    check_file_dict[key['metric']['job']]['value'].append(metric_dict)
0 `" {+ J: R3 u! S9 V                    # print(check_file_dict)) s! Q# z& d5 C0 S6 ^0 Y! Y

) E# X7 }* P, W1 H7 i                for instance in check_file_dict[project]['value']:
9 |+ j+ |5 y! Y- b2 w7 O2 o  g5 M                    if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:
& ^% s  J% i+ w8 X5 m+ H0 _                        instance[metrics_list[metric]] = key['values'][0][1]/ s# z8 h/ m$ v' m, J

: K+ ?3 b8 m$ `" U5 p* t* c; {; R: \" t
    for key in check_file_dict:
) }1 |+ L1 W9 T9 \        test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'# ~4 C. K& R5 M& A" h
        print(test_report)+ A! g! z" x! S$ [
        if os.path.exists(test_report):) u8 M- q3 D5 V9 R3 T8 y
            os.remove(test_report)& L! b: f- r5 c; j5 R5 y8 `; H
        print(check_file_dict[key]['value'])+ B  z( _: ?, ]* J8 b  n1 }* t
        write_to_dish(pd.DataFrame(check_file_dict[key]['value']),7 h0 L4 ]( w1 i8 c, I% w
                      fileDir=test_report)6 p4 Y* r# D7 z/ n' w
% [# S6 l# {# O7 T6 L$ g: v
        #发送企业微信机器人8 N, N) @5 {# Z+ t. s- {) `
        wx_api_key = check_file_dict[key]['robot_key']  # 这个地方写你自己的key
- B- a, U# V2 P$ ^- \8 r" m        wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key)' ^' B' c' X0 w' R" K$ E
        wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)
, A/ [! K# E- ~1 K        media_id = upload_file(test_report, wx_upload_url)4 ?& m+ n- B" P9 v& }+ n) `
        qi_ye_wei_xin_file(wx_url, media_id)
8 N$ U0 H$ s( C( o' _" s5 G! K: u9 u0 A/ |, Z# k* X
( j; T! ]5 T3 B8 T4 D8 z
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 01:22 , Processed in 0.016279 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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