|
|
4 s; M# s* O6 ~/ I发送给企业微信机器人, M# B8 r- @" ~
) i8 X5 N3 o! J# upload_file 是为了生成 media_id, 供消息使用) X# ^8 N4 i# l0 z
' r2 d0 q1 v" K' u. `# O' _4 r# -*- encoding: utf-8 -*-6 K$ D6 w0 ?( G
import requests, paramiko, json, os, datetime ~3 G7 [7 X" Q/ D( g- _
import pandas as pd6 f/ H" [* r* J
from copy import copy
5 B# L L" T! g0 m5 ?/ Gfrom urllib3 import encode_multipart_formdata5 l0 F3 P" G4 @
1 T9 k; N# q$ g# Y }
def upload_file(file_path, wx_upload_url):
; e' Y: k* N3 z. h: S2 `$ K file_name = file_path.split("/")[-1]
; }# o5 _! {0 w with open(file_path, 'rb') as f:+ l% s8 U, N& f4 Z6 {7 [( _" m
length = os.path.getsize(file_path)
n) P# G4 h" p$ O data = f.read(). @# h. g2 d( l0 n& E* C) u" g% ^
headers = {"Content-Type": "application/octet-stream"}5 y9 r; {6 P0 D7 C2 @9 z# Q; r
params = {5 k8 x: B G: S6 g6 M
"filename": file_name,: @( o: M( V( l3 y9 N* M
"filelength": length,
! B0 H3 f/ r# Q9 _# p }
, z. }; _. H' F" v file_data = copy(params)
6 x/ ]6 v1 c6 z3 x# _3 _6 l2 v file_data['file'] = (file_path.split('/')[-1:][0], data)
' O: X: z4 p4 w& D encode_data = encode_multipart_formdata(file_data)
1 x& f" @/ c S" I7 p8 C file_data = encode_data[0]' W5 n& O$ q0 {* I" N
headers['Content-Type'] = encode_data[1]
9 A- T3 h- ^& \' @6 g+ B+ o# n r = requests.post(wx_upload_url, data=file_data, headers=headers)6 W3 _( b' \- @: k" J6 `, G, s1 L
print(r.text), q. I- i" t0 J* N1 `; ~
media_id = r.json()['media_id']1 s {6 ~/ i, d4 S
return media_id$ H: n X' u8 V
# media_id 通过上一步上传的方法获得
: X3 V( ~# R0 D& Q/ b) p) u. Y w3 s* \) B& M w8 p5 m, c6 u8 z
def qi_ye_wei_xin_file(wx_url, media_id):
1 |) g: w5 d; {5 P+ L" y+ D headers = {"Content-Type": "text/plain"}: v3 M. ~2 z w% n0 n
data = {& C4 ^$ D. I: j; T" a+ S" p! p) {
"msgtype": "file",- U; E0 u6 K3 F$ }/ b) W4 d: e& A
"file": {) ~9 d' `) Z. [+ a* N8 K) U1 J
"media_id": media_id
) Q0 Y# Q* ~4 a }
6 g9 R: E* n: s3 X1 B# ?! E% o }2 \1 j6 m$ \$ R' @+ n1 \
r = requests.post(
, M- c1 Z- d; [3 A9 M: w url=wx_url,
, e" P3 G! w# r9 J- |" i. |& C headers=headers, json=data)# J9 G1 e& _/ t J/ j z8 S
print(r.text)
# [8 y: ]1 Y5 m* T, U
) `1 X2 \; x1 x' }+ v y' O1 G: T8 ^ _% G: e5 z, `
% F: x7 v( n% G4 E7 j9 _ _: P6 _1 j
从Prometheus 上获取监控数据
4 g, y/ k5 T) v
' f6 C$ y4 C3 o, f+ ^, k. |# 得到一个Overssh的返回值5 Q8 p! U! M3 [% g. g( J8 a! {- p
def get_file_list(hostname, port, username, key_name, command):& d; j& ~; f; H0 |
ssh = paramiko.SSHClient() # 创建SSH对象' u& i& J$ A B
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 允许连接不在know_hosts文件中的主机
& j5 o, } w2 t( \; V6 u$ W: n # ssh.connect(hostname='ip', port=22, username='user', password='密码') # 连接服务器
% z+ N+ Y- d& C4 W$ V( q& h ssh.connect(hostname=hostname, port=port, username=username,
6 Q- c7 m" w; y% v: a* A9 J pkey=paramiko.RSAKey.from_private_key_file(key_name)) # 连接服务器
+ c% v* N l+ l, Y% p stdin, stdout, stderr = ssh.exec_command(command)
8 b/ o w0 p, q: ~( u6 i) F) L# B, Q: E
file_list = str(stdout.read(), encoding="utf-8")
9 M+ @! Y5 E% J2 G5 D% \9 M ssh.close() # 关闭连接( |$ a6 f' r: S7 D! G* @3 l4 V" C7 B
4 I! I' D1 b5 R5 [8 N9 F
return file_list: N" x- I% {3 n
% Y% h, R0 X# v; b
% w9 c1 n$ R+ S
将PD写入到磁盘& w& ]9 r. Y* F) \2 L; b5 Z, I9 T
: q$ s2 N% g% k0 O" ^3 N# T. udef write_to_dish(results,fileDir):
1 o- H. z- v; L. }1 A writer = pd.ExcelWriter(fileDir)
: ?1 B1 z5 s4 i3 C* l: v- ` results.to_excel(writer,float_format='%.5f')" N: D. m( _5 \0 C! k
writer.save()
! z' G$ [0 Q% h3 f+ o! |
2 |1 r6 e, w6 e9 g2 `定义好需要查询的metric
" a. l" C& s: k# l1 n% _: L9 s$ o# V6 Q# S, M4 O2 B' X4 D
# 查询需要检查的数据,第一个必须为 up
- y( }4 n- W* g8 c }4 _. N0 {- Udef rds_metrics_list():
8 X) V" h2 w( c return {'up': '状态',( n/ M A% J5 I: X
'rds001_cpu_util': 'CPU使用率(%)',, q5 V4 q7 z7 c
'rds002_mem_util': '内存使用率(%)',% t) M/ `+ S2 I% R* d
'rds003_iops': 'iops',3 S& E$ h. \1 X0 E9 Q
'rds004_bytes_in': '网络流量入(Bytes)',3 |" k2 ]$ K9 t& J/ r( b5 x
'rds005_bytes_out': '网络流量出(Bytes)',; ~/ U/ {$ v, A/ |
'rds008_qps': 'QPS',
2 T6 w( \; q2 F& i% ^* a k* U 'rds009_tps': 'TPS',& D& O5 D1 B, `" M0 L
'rds081_vm_ioutils': 'io使用率(%)',
+ }; X8 h. v$ C! R, {" m 'rds047_disk_total_size': '磁盘总大小(G)',
* a/ s7 M$ P: g 'rds048_disk_used_size': '磁盘使用(G)',6 G: y. A. W: `) _2 P7 p1 I1 I
'mysql_global_status_threads_connected': '当前连接数',$ N8 c0 Y. g0 z) c/ \- a5 `% e
'mysql_global_variables_max_connections': '最大连接数'," z$ a% z- `7 J$ Z# O2 {
}
- q1 J. S+ p" M/ |% J/ h
. l7 u: I }6 y a( D) L' f, }$ N/ v9 g( V
3 T3 N" O/ M& h. i) \& u; ?/ [0 K" u3 {3 t3 R" y$ Z6 D
Prometheus 获取数据落盘数据,并发送给企业微信机器人; [0 A4 ?$ Z8 w3 h$ Q
; I" L; }: I8 s. E6 ` x" fif __name__ == '__main__':
! I, T* _8 M/ P, P # prometheus 主机信息
, S3 s; l' L8 Y; S1 y host_info = {'hostname': 'xxx.xxx.xxx.xxx', 'port': 60028, 'username': 'root', 'key_name': './keys/xxx'}1 D7 V- I; n' V9 D1 ]2 M( [: }
# 检查文件路径
# d# c4 y$ o- B2 `- n8 K5 H check_file_dir = 'check_files'8 z4 b0 d9 `4 n: C! d
2 T& {* B: c+ S5 H1 h # 检查文件时间,时区问题需要减去8小时
% j `, z2 K3 b9 Z l3 Z2 A curhour = -17 # 默认给-17 当前时间是-8.1
( M9 s6 @% Q% |& z# ]8 m
9 \3 P+ t; w3 r' O8 |: N2 i # 检查项目 为job名prometheus 中的job, name 为项目的巡检名字, robot_key 为企业微信机器人
C! e' _" N! p! P, u( @
# p" n' a" c# A4 k8 x0 ] check_file_dict = {'job': {'name': 'name', 'value': [], 'key': 'xxx',/ T# s* B1 v: M3 W
'robot_key': 'xxx'}}
' v! u, M0 M3 u2 F; z* L( N
2 |' ~+ P5 f( j3 q! j if not os.path.exists(check_file_dir):: v" a0 [4 r' O1 L, l$ Q* J
os.makedirs(check_file_dir)
2 y0 a/ e3 h. d1 p+ A6 ?! F1 B$ h' g) W. i3 q7 b, |/ P
metrics_list = rds_metrics_list()& ~5 ]# t% n1 [' U
: S& k# F/ Z! {) O$ x0 a
check_time_day = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%Y-%m-%d")
+ _4 d% i5 _$ L4 `6 f" S1 r! { check_time_hour = (datetime.datetime.now() + datetime.timedelta(hours=curhour)).strftime("%H:%M")
/ S5 @& O/ [/ G G print(check_time_day, check_time_hour)
" [* Z& g2 J% R
* I9 s7 y. H7 o1 n% Q6 x0 m! I for metric in metrics_list: B5 u: {1 E" Y: x
command = 'curl http://127.0.0.1:9090/api/v1/query_range?query=%s\&start=%sT%s:00Z\&end=%sT%s:15Z\&step=15s' \ ~' P( b( d) {. L7 v0 W
%(metric, check_time_day, check_time_hour, check_time_day, check_time_hour)1 ^- r% A4 a& Y3 D2 [0 n* n# q3 r! W
file_list = get_file_list(host_info['hostname'], host_info['port'], host_info['username'], host_info['key_name'], command)( R7 @) q* K- D7 e8 x; R- t, `
metrics = json.loads(file_list)
- \0 U ? h4 k for key in metrics['data']['result']:
7 G: U: b. J( v1 A4 R # Mysql数据库巡检
' B2 D6 b5 s( B8 T i Prometheus_job = key['metric']['job']5 [: V# r! e0 \
Prometheus_instance = key['metric']['instance']! Q. ~' Z1 l8 j7 y) {# ?2 x
for project in check_file_dict:
- R2 w7 O9 E+ v, _ |2 Y1 { if Prometheus_job == project and key['metric']['__name__'] == 'up':
1 v8 B' \( J; W metric_dict = {}
' s+ e3 L% U7 k; \8 z5 V0 Y metric_dict['instance'] = key['metric']['instance']4 \) t \; F" I$ A2 M) S0 }2 d% C
metric_dict[metrics_list[metric]] = key['values'][0][1]' n" W8 g( j/ J- y
( H% z- [7 H+ n! k: z& c5 f J' I# j
check_file_dict[key['metric']['job']]['value'].append(metric_dict)" v# E2 s S3 }, P
# print(check_file_dict)+ O/ b; ]0 E/ t$ N
) `& j* e* |( a0 c$ ^( F
for instance in check_file_dict[project]['value']:
3 }" o! z1 f/ L5 Y5 d0 ? if key['metric']['job'] == check_file_dict[project]['key'] and key['metric']['instance'] == instance['instance']:" W2 [) y" h8 S) _# U
instance[metrics_list[metric]] = key['values'][0][1]0 }. e( l" x( E4 x/ J
7 x/ E8 C7 X' D6 E
- z& L! _8 U! E; i for key in check_file_dict:: J$ y( K1 P/ @ @
test_report = './'+check_file_dir+'/'+check_file_dict[key]['name']+'_'+check_time_day+'.xlsx'6 |9 t) e: F: j0 Y0 U8 Y
print(test_report)
. {& `; k1 h9 j# ?( ~* C if os.path.exists(test_report):# Q# S9 @$ ?3 U! D
os.remove(test_report)
/ t+ M5 l: o# [+ J, m print(check_file_dict[key]['value'])
7 ^' f1 _$ k. K( @: b write_to_dish(pd.DataFrame(check_file_dict[key]['value']),
- V* M! r; C1 g0 o% a1 B8 l8 S fileDir=test_report)
- d" F, \* S7 r( p* }1 b2 C$ t/ R" ^4 L
#发送企业微信机器人
8 d- J3 u8 D0 I0 _. W; r5 u: A wx_api_key = check_file_dict[key]['robot_key'] # 这个地方写你自己的key
5 E. M" _/ e# y3 F t- ^3 _ wx_upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={}&type=file".format(wx_api_key)% `# \) l) @, Q) ]
wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={}'.format(wx_api_key)
+ T x% m( L- p. @6 B/ S9 t media_id = upload_file(test_report, wx_upload_url)4 g1 D8 S a* Y9 S, B
qi_ye_wei_xin_file(wx_url, media_id)5 P* E v4 e% \4 \) i" \1 M: n
( Z5 G2 p/ `0 r9 E% R
- ?6 x7 ^) P3 w! d |
|