|
|
+ 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
|
|