Operations 7 min read

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.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Automate Zabbix Alert Reports with Python and Email

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.

MonitoringPythonAutomationemailZabbix
Ops Development Stories
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.