- 积分
- 16844
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
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 |
|