1 #!/usr/bin/python env
2 # -*- coding: utf-8 -*-
3 ###################################################################################################
4 # ops public tools
5 # file_ver: 1.0.1
6 # 增删改查 crontab
7 #
8 # create by PanBiao, 2020-08-05
9 # Copyright 2020 pb
10 # 本工具版权信息归作者所有,未经授权不可用于平台外的其它商业用途。
11 #
12 # Input variables:
13 #
14 #
15 # Output variables:
16 #
17 # Usage:
18 # 此脚本调用zabbix api来获取triggers top100,将数据发送至个邮箱
19 ########################################################################################################################
20
21 import requests,json,codecs,datetime,time,pandas,logging,string
22 from email import encoders
23 from email.header import Header
24 from email.mime.text import MIMEText
25 from email.utils import parseaddr
26 from smtplib import SMTP
27 import smtplib
28 # import logs_api
29
30 import logging
31
32 def logs_api(type):
33 ##生成一个日志对象,并定义一个默认日志级别
34 logger = logging.getLogger(type)
35 logger.setLevel(logging.INFO)
36
37 ##生成一个handler(处理器),输出到日志文件
38 dir = "/Users/panbiao/logs/"
39 fh = logging.FileHandler(dir+type+".log")
40 ##指定日志输出格式
41 formatter = logging.Formatter('{"time":"%(asctime)s","script":"%(name)s","thread":"%(thread)d",'
42 '"threadName":"%(threadName)s","loglevel":"%(levelname)s"} - %(message)s')
43 ##实例化formatter
44 fh.setFormatter(formatter)
45
46 ##输出到屏幕
47 ch = logging.StreamHandler()
48 formatter = logging.Formatter('{"time":"%(asctime)s","script":"%(name)s","thread":"%(thread)d",'
49 '"threadName":"%(threadName)s","loglevel":"%(levelname)s"} - %(message)s')
50 ch.setFormatter(formatter)
51
52 ##为hadder添加formatter,输入日志文件打开fh,输出到屏幕打开ch
53 logger.addHandler(fh)
54 #logger.addHandler(ch)
55
56 return logger
57
58 logger = logs_api("zabbix_trigger_top_100")
59
60 class Get_trigger_top_100:
61 def __init__(self):
62 """
63 初始化实例变量
64 """
65 ##定义url
66 self.URL = URL
67 self.USER = USER
68 self.PASSWORD = PASSWORD
69 self.HEADERS = {"Content-Type":"application/json"}
70
71 def get_token(self):
72 """
73 用户认证信息的部分,最终的目的是得到一个SESSIONID
74 :return: auth.content['result']
75 """
76 try:
77 data = {"jsonrpc": "2.0",
78 "method": "user.login",
79 "params": {
80 "user": self.USER,
81 "password": self.PASSWORD
82 },
83 "id": 1,
84 "auth": None,
85 }
86 auth = requests.post(url=self.URL, headers=self.HEADERS, json=data)
87 except Exception as e:
88 logger.error(e)
89 else:
90 if "result" in auth.text:
91 logger.info(auth.text)
92 return json.loads(auth.content)['result']
93 else:
94 logger.error("登录错误")
95
96 def time_frame(self):
97 """
98 定义取值时间范围
99 :return: startTime,endTime
100 """
101 self.TIME_FRAME = TIME_FRAME
102
103 startTime = int(time.mktime((datetime.datetime.now() -
104 datetime.timedelta(days=self.TIME_FRAME)).timetuple()))
105 endTime = int(round(time.time()))
106 logger.info("{0}{1}".format("startTime:",startTime))
107 logger.info("{0}{1}".format("endTime:",endTime))
108 return startTime,endTime
109
110 def get_data(self):
111 """
112 根据时间戳获取trigger数据
113 :return:
114 """
115 #定义一个空列表
116 self.triggers = []
117 self.triggers_data = {}
118 self.triggers_b = []
119 try:
120 data = {
121 "jsonrpc": "2.0",
122 "method": "event.get",
123 "params":{
124 "output": [
125 "name",
126 "severity"
127 ],
128 "value":1,
129 "time_from": self.time_frame()[0],
130 "time_till": self.time_frame()[1],
131 "selectHosts": [
132 # "hostid",
133 "name"
134 ]
135 },
136 "auth": self.get_token(),
137 "id": 1
138 }
139 getevent = requests.post(url=self.URL, headers=self.HEADERS, json=data)
140 triname = json.loads(getevent.content)['result']
141 for i in triname:
142 self.triggers.append(i["name"])
143 for i in self.triggers:
144 self.triggers_data[i] = self.triggers.count(i)
145 # print(self.triggers_data)
146
147 for key in self.triggers_data:
148 triggers_data_b = {}
149 triggers_data_b["name"] = key
150 # triggers_data_b["host"] = [i['hosts'][0]['name'] for i in triname if i['name']==key][0]
151 for i in triname:
152 # if i['name'] == key and i['hosts'] == []:
153 # triggers_data_b["host"] = ""
154 # else:
155 # triggers_data_b["host"] = [i['hosts'][0]['name'] for i in triname if i['name'] == key][0]
156 #有的主机可能已经被删除,这里hosts字段就是空的,所以写了一个try
157 try:
158 triggers_data_b["host"] =
159 [i['hosts'][0]['name'] for i in triname if i['name'] == key][0]
160 except:
161 triggers_data_b["host"] = ""
162 triggers_data_b['severity'] = [i['severity'] for i in triname if i['name'] == key][0]
163 triggers_data_b['count'] = self.triggers_data[key]
164 self.triggers_b.append(triggers_data_b)
165 #return self.triggers_b
166 return sorted(self.triggers_b, key=lambda x: x['count'], reverse=True)
167
168 except Exception as e:
169 print(e)
170 #
171 # def triggers_to_thml(self, result):
172 # """
173 # 定义返回格式
174 # :param result:
175 # :return:
176 # """
177 # triggers = {}
178 # title = ['主机', '触发器', '告警级别', '告警次数']
179 # index = 0
180 # for t in title:
181 # triggers[t] = result[index]
182 # index = index+1
183 # df = pandas.DataFrame(triggers)
184 # df = df[title]
185 # h = df.to_html(index=False)
186 # return h
187
188 def data_to_html(self):
189 tables = ''
190 list2 = self.get_data()
191 for i in range(len(list2)):
192 host, name, severity, count = list2[i]['host'], list2[i]['name'], list2[i]['severity'], list2[i]['count']
193 td = "<td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td>" % (host, name, severity, count)
194 tables = tables + "<tr>%s</tr>" % td
195 base_html = """
196 <!DOCTYPE html>
197 <html>
198 <head>
199 <meta charset="utf-8">
200 <title>zabbix监控告警</title>
201 </head>
202 <body>
203 <table width="900" border="0">
204 <tr>
205 <td colspan="2" style="background-color:#FFA500;">
206 <h4>告警级别: 1 表示:信息 2 表示:告警 3 表示:一般严重 4 表示:严重 5 表示:灾难</h4>
207 </td>
208 </tr>
209 <tr>
210 <td style="background-color:#FFD700;100px;">
211 <TABLE BORDER=1><TR><TH>主机</TH><TH>触发器</TH><TH>告警级别</TH><TH>告警次数</TH></TR>%s</TABLE>
212 </td>
213 </tr>
214 <tr>
215 <td colspan="2" style="background-color:#FFA500;text-align:center;">
216 zabbix告警统计</td>
217 </tr>
218 </table>
219 </body>
220 </html>
221 """ % tables
222 return base_html
223
224 def sendmail(self):
225 """
226 发送邮件
227 :return:
228 """
229 self.from_addr = from_addr
230 self.password = password
231 self.to_addr = to_addr
232 self.smtp_server = smtp_server
233 self.mail_port = mail_port
234
235 msg = MIMEText(self.data_to_html(), 'html', 'utf-8')
236 msg['From'] = self.from_addr
237 msg['To'] = ','.join(self.to_addr)
238 msg['Subject'] = Header('好哒金融云Zabbix最近一周监控报表', 'utf-8').encode()
239
240 try:
241 server = smtplib.SMTP()
242 server.connect(self.smtp_server) # 创建一个smtp对象
243 # server.starttls() #启用安全传输模式
244 server.login(self.from_addr, self.password) # 邮箱账号登录
245 server.sendmail(self.from_addr, self.to_addr, msg.as_string()) # 发送邮件
246 server.close() # 断开smtp连接
247 logger.info("邮件发送成功")
248 except Exception as e:
249 logger.error("无法发送邮件")
250 logger.error(e)
251
252 def logout(self):
253 """
254 退出登录
255 :return: auth.content
256 """
257 data = {
258 "jsonrpc": "2.0",
259 "method": "user.logout",
260 "params": [],
261 "id": 1,
262 "auth": self.get_token()
263 }
264 auth = requests.post(url=self.URL, headers=self.HEADERS, json=data)
265 logger.info(json.loads(auth.content))
266 return json.loads(auth.content)
267
268 if __name__ == '__main__':
269 #zabbix接口url
270 URL = "http://xxxx/zabbix/api_jsonrpc.php"
271 #zabbix用户密码
272 USER = "Admin"
273 PASSWORD = "zabbix"
274 #邮件账号密码,收件人等
275 # from_addr = 'xxx'
276 # password = 'xxx'
277 from_addr = 'xxxx'
278 password = 'xxxx'
279 mail_port = 25
280 to_addr = ['xxxx', ] #多个邮箱直接加在list
281 smtp_server = 'xxxx'
282 ##zabbix 需要取多少天的triggers数据
283 TIME_FRAME = 7
284 execute = Get_trigger_top_100()
285 # print(execute.get_data())
286 execute.sendmail()
287 execute.logout()