Automate Zabbix Alert Reports with Python and Email
This tutorial explains how to retrieve Zabbix alarm data via its API, deduplicate and count triggers, generate an HTML report, and automatically email the report using Python, with optional weekly scheduling via Linux cron.
Implementation Idea
Zabbix provides an API to fetch raw alarm events.
Aggregate the raw data, remove duplicate triggers, count occurrences, and store required fields in a list.
Iterate over the list to embed the data into an HTML table, optionally using pandas for modeling.
Send the generated HTML as the email body.
Define Time Interval
<code>x=(datetime.datetime.now()-datetime.timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S")
y=(datetime.datetime.now()).strftime("%Y-%m-%d %H:%M:%S")
def timestamp(x,y):
p=time.strptime(x,"%Y-%m-%d %H:%M:%S")
starttime = str(int(time.mktime(p)))
q=time.strptime(y,"%Y-%m-%d %H:%M:%S")
endtime= str(int(time.mktime(q)))
return starttime,endtime</code>This obtains alarm data for the past 30 minutes.
Fetch Event Data
<code>def getevent(auth,timestamp):
data={
"jsonrpc": "2.0",
"method": "event.get",
"params": {
"output": [
"name",
"severity"
],
"value":1,
"time_from":timestamp[0],
"time_till":timestamp[1],
"selectHosts":[
"name"
]
},
"auth": auth,
"id": 1
}
getevent=requests.post(url=ApiUrl,headers=header,json=data)
triname=json.loads(getevent.content)['result']</code>The Zabbix API returns event name, severity, host name, and other details.
Process Retrieved Data
<code>triggers=[]
a={}
for i in triname:
triggers.append(i['name'])
for i in triggers:
a[i]=triggers.count(i)
list2=[]
for key in a:
b={}
b['name']=key
b['host']=[i['hosts'][0]['name'] for i in triname if i['name']==key][0]
b['severity']=[i['severity'] for i in triname if i['name']==key][0]
b['count']=a[key]
list2.append(b)
return list2</code>This deduplicates triggers, counts occurrences, and assembles a list of dictionaries containing name, host, severity, and count.
Generate HTML Table
<code>def datatohtml(list2):
tables = ''
for i in range(len(list2)):
name,host,severity,count = list2[i]['name'], list2[i]['host'], list2[i]['severity'], list2[i]['count']
td = "<td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td>"%(name, host, severity, count)
tables = tables + "<tr>%s</tr>"%td
base_html="""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>zabbix监控告警</title>
</head>
<body>
<table width="900" border="0">
<tr>
<td colspan="2" style="background-color:#FFA500;">
<h4>告警级别: 1 表示:信息 2 表示:告警 3 表示:一般严重 4 表示:严重 5 表示:灾难</h4>
</td>
</tr>
<tr>
<td style="background-color:#FFD700;width:100px;">
<TABLE BORDER=1><TR><TH>主机</TH><TH>触发器</TH><TH>告警级别</TH><TH>告警次数</TH></TR>%s</TABLE>
</td>
</tr>
<tr>
<td colspan="2" style="background-color:#FFA500;text-align:center;">
zabbix告警统计</td>
</tr>
</table>
</body>
</html>
""" %tables
return base_html</code>The function builds an HTML page with a table showing host, trigger, severity, and count.
Send Report Email
<code>def sendmail(base_html):
from_addr = '[email protected]'
password = '没有故事的陈师傅'
to_addr = '[email protected]'
smtp_server = 'smtp.qq.com'
msg = MIMEText(base_html, 'html', 'utf-8')
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = Header('Zabbix本周监控报表', 'utf-8').encode()
try:
server=SMTP(smtp_server,"25")
server.login(from_addr,password)
server.sendmail(from_addr,to_addr,msg.as_string())
server.quit()
except smtplib.SMTPException as a:
print (a)</code>This sends the generated HTML via SMTP.
Result screenshot:
To schedule weekly sending, place the script in a Linux cron job. The full script is available on GitHub.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.