1. 原生Zabbix邮件报警设置
1.1 配置邮件服务器
# 编辑Zabbix Server配置文件
vim /etc/zabbix/zabbix_server.conf
# 添加邮件设置(示例使用SMTP)
AlertScriptsPath=/usr/lib/zabbix/alertscripts
1.2 创建邮件发送脚本
vim /usr/lib/zabbix/alertscripts/send_mail.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import argparse
def send_email(smtp_server, smtp_port, username, password,
from_addr, to_addrs, subject, content, is_html=False):
"""
发送邮件函数
"""
# 创建邮件对象
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = from_addr
msg['To'] = to_addrs
# 根据是否为HTML内容设置邮件正文
if is_html:
content_part = MIMEText(content, 'html', 'utf-8')
else:
content_part = MIMEText(content, 'plain', 'utf-8')
msg.attach(content_part)
# 连接SMTP服务器并发送邮件
try:
smtp = smtplib.SMTP(smtp_server, smtp_port)
smtp.starttls() # 启用TLS加密
smtp.login(username, password)
smtp.sendmail(from_addr, to_addrs.split(','), msg.as_string())
smtp.quit()
print("邮件发送成功!")
except Exception as e:
print(f"邮件发送失败: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='发送邮件')
parser.add_argument('--smtp_server', required=True, help='SMTP服务器地址')
parser.add_argument('--smtp_port', type=int, default=587, help='SMTP端口')
parser.add_argument('--username', required=True, help='SMTP用户名')
parser.add_argument('--password', required=True, help='SMTP密码')
parser.add_argument('--from_addr', required=True, help='发件人邮箱')
parser.add_argument('--to_addrs', required=True, help='收件人邮箱(多个用逗号分隔)')
parser.add_argument('--subject', required=True, help='邮件主题')
parser.add_argument('--content', required=True, help='邮件内容')
parser.add_argument('--html', action='store_true', help='是否为HTML内容')
args = parser.parse_args()
send_email(
smtp_server=args.smtp_server,
smtp_port=args.smtp_port,
username=args.username,
password=args.password,
from_addr=args.from_addr,
to_addrs=args.to_addrs,
subject=args.subject,
content=args.content,
is_html=args.html
)
1.3 设置脚本权限
chmod +x /usr/lib/zabbix/alertscripts/send_mail.py
chown zabbix:zabbix /usr/lib/zabbix/alertscripts/send_mail.py
2. 报警报表脚本
2.1 日报表生成脚本
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Zabbix报警日报表脚本
"""
import json
import sys
import os
import datetime
import pytz
from zabbix_api import ZabbixAPI
class ZabbixAlertReport:
def __init__(self, zabbix_url, username, password):
self.zabbix_url = zabbix_url
self.zabbix = ZabbixAPI(zabbix_url)
self.zabbix.login(username, password)
def get_daily_alerts(self, hours=24):
"""
获取指定时间段内的报警
"""
end_time = int(datetime.datetime.now().timestamp())
start_time = end_time - (hours * 3600)
# 获取触发器报警
triggers = self.zabbix.trigger.get({
'output': ['triggerid', 'description', 'priority', 'lastchange'],
'selectHosts': ['hostid', 'name'],
'selectLastEvent': ['eventid', 'clock', 'value'],
'time_from': start_time,
'time_till': end_time,
'sortfield': 'lastchange',
'sortorder': 'DESC',
'filter': {'value': 1} # 只获取触发状态的触发器
})
return triggers
def generate_html_report(self, alerts, report_date=None):
"""
生成HTML格式的报表
"""
if report_date is None:
report_date = datetime.datetime.now().strftime('%Y-%m-%d')
severity_map = {
'0': '未分类',
'1': '信息',
'2': '警告',
'3': '一般严重',
'4': '严重',
'5': '灾难'
}
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Zabbix报警日报表 - {report_date}</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 20px; }}
.header {{ background-color: #f8f9fa; padding: 20px; border-radius: 5px; }}
.report-title {{ color: #333; font-size: 24px; margin: 0; }}
.report-date {{ color: #666; font-size: 14px; }}
.summary {{ margin: 20px 0; padding: 15px; background-color: #e9ecef; border-radius: 5px; }}
.alert-table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
.alert-table th {{ background-color: #343a40; color: white; padding: 12px; text-align: left; }}
.alert-table td {{ padding: 10px; border-bottom: 1px solid #dee2e6; }}
.alert-table tr:nth-child(even) {{ background-color: #f8f9fa; }}
.severity-0 {{ background-color: #ffffff; }}
.severity-1 {{ background-color: #d1ecf1; }}
.severity-2 {{ background-color: #fff3cd; }}
.severity-3 {{ background-color: #f8d7da; }}
.severity-4 {{ background-color: #f5c6cb; }}
.severity-5 {{ background-color: #721c24; color: white; }}
.chart-container {{ margin: 30px 0; }}
.footer {{ margin-top: 30px; padding-top: 20px; border-top: 1px solid #dee2e6; color: #6c757d; font-size: 12px; }}
</style>
</head>
<body>
<div class="header">
<h1 class="report-title">Zabbix监控报警日报表</h1>
<div class="report-date">报表日期: {report_date}</div>
</div>
<div class="summary">
<h3>报警统计</h3>
<p>总报警数量: {len(alerts)}</p>
</div>
<table class="alert-table">
<thead>
<tr>
<th>时间</th>
<th>主机</th>
<th>报警信息</th>
<th>严重程度</th>
<th>持续时间</th>
</tr>
</thead>
<tbody>
"""
for alert in alerts:
host_name = alert['hosts'][0]['name'] if alert.get('hosts') else 'Unknown'
trigger_description = alert.get('description', '')
severity = severity_map.get(str(alert.get('priority', '0')), '未知')
# 转换时间戳
lastchange = datetime.datetime.fromtimestamp(int(alert['lastchange']))
lastchange_str = lastchange.strftime('%Y-%m-%d %H:%M:%S')
# 计算持续时间
duration = datetime.datetime.now() - lastchange
duration_str = str(duration).split('.')[0]
html_content += f"""
<tr class="severity-{alert.get('priority', '0')}">
<td>{lastchange_str}</td>
<td>{host_name}</td>
<td>{trigger_description}</td>
<td>{severity}</td>
<td>{duration_str}</td>
</tr>
"""
html_content += """
</tbody>
</table>
<div class="chart-container">
<h3>报警级别分布</h3>
<!-- 这里可以添加图表,如使用Chart.js -->
</div>
<div class="footer">
<p>本报表由Zabbix监控系统自动生成</p>
<p>生成时间: """ + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') + """</p>
</div>
</body>
</html>
"""
return html_content
def generate_text_report(self, alerts):
"""
生成纯文本格式的报表
"""
report_lines = []
report_lines.append("=" * 60)
report_lines.append("ZABBIX 报警日报表")
report_lines.append(f"生成时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
report_lines.append("=" * 60)
report_lines.append("")
severity_count = {}
for alert in alerts:
host_name = alert['hosts'][0]['name'] if alert.get('hosts') else 'Unknown'
trigger_description = alert.get('description', '')
lastchange = datetime.datetime.fromtimestamp(int(alert['lastchange']))
lastchange_str = lastchange.strftime('%Y-%m-%d %H:%M:%S')
severity = alert.get('priority', '0')
severity_count[severity] = severity_count.get(severity, 0) + 1
report_lines.append(f"主机: {host_name}")
report_lines.append(f"报警: {trigger_description}")
report_lines.append(f"时间: {lastchange_str}")
report_lines.append(f"严重程度: {severity}")
report_lines.append("-" * 40)
# 添加统计信息
report_lines.append("\n报警统计:")
report_lines.append(f"总报警数: {len(alerts)}")
for sev, count in sorted(severity_count.items()):
report_lines.append(f"级别 {sev}: {count} 个")
return "\n".join(report_lines)
def main():
# 配置参数
ZABBIX_URL = "http://your-zabbix-server/zabbix"
ZABBIX_USER = "Admin"
ZABBIX_PASSWORD = "zabbix"
# 创建报表实例
report = ZabbixAlertReport(ZABBIX_URL, ZABBIX_USER, ZABBIX_PASSWORD)
# 获取最近24小时的报警
alerts = report.get_daily_alerts(hours=24)
if alerts:
# 生成HTML报表
html_report = report.generate_html_report(alerts)
# 生成文本报表
text_report = report.generate_text_report(alerts)
# 保存报表文件
report_date = datetime.datetime.now().strftime('%Y%m%d')
with open(f"/tmp/zabbix_report_{report_date}.html", "w", encoding="utf-8") as f:
f.write(html_report)
with open(f"/tmp/zabbix_report_{report_date}.txt", "w", encoding="utf-8") as f:
f.write(text_report)
print(f"报表已生成: /tmp/zabbix_report_{report_date}.html")
print(f"报表已生成: /tmp/zabbix_report_{report_date}.txt")
return html_report, text_report
else:
print("没有发现报警")
return None, None
if __name__ == "__main__":
html_content, text_content = main()
3. 使用Zabbix API获取数据并发送邮件
3.1 安装必要的Python包
pip install pyzabbix
pip install pandas
pip install matplotlib
3.2 增强版报表脚本
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Zabbix报警统计报表与自动邮件发送
"""
import json
import sys
import os
import datetime
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
import pandas as pd
from pyzabbix import ZabbixAPI
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg') # 用于服务器环境
class ZabbixReportGenerator:
def __init__(self, config_file='config.json'):
"""
初始化Zabbix报表生成器
"""
with open(config_file, 'r') as f:
self.config = json.load(f)
# 连接Zabbix
self.zabbix = ZabbixAPI(self.config['zabbix']['url'])
self.zabbix.login(
self.config['zabbix']['username'],
self.config['zabbix']['password']
)
# SMTP配置
self.smtp_config = self.config['smtp']
def get_alerts_by_time_range(self, start_time, end_time):
"""
获取指定时间范围内的报警
"""
# 获取事件
events = self.zabbix.event.get({
'output': 'extend',
'select_acknowledges': 'extend',
'selectTags': 'extend',
'time_from': start_time,
'time_till': end_time,
'sortfield': ['clock'],
'sortorder': 'DESC',
'source': 0, # 触发器事件
'object': 0, # 触发器
'value': 1 # 问题状态
})
return events
def analyze_alerts(self, events):
"""
分析报警数据
"""
analysis = {
'total_alerts': len(events),
'by_severity': {},
'by_host': {},
'top_triggers': {},
'time_distribution': {}
}
for event in events:
# 按严重程度统计
severity = event.get('severity', '0')
analysis['by_severity'][severity] = analysis['by_severity'].get(severity, 0) + 1
# 获取主机信息
trigger = self.zabbix.trigger.get({
'output': 'extend',
'triggerids': event['objectid'],
'selectHosts': ['hostid', 'name']
})
if trigger and trigger[0].get('hosts'):
host_name = trigger[0]['hosts'][0]['name']
analysis['by_host'][host_name] = analysis['by_host'].get(host_name, 0) + 1
# 按时间分布统计(按小时)
event_time = datetime.datetime.fromtimestamp(int(event['clock']))
hour = event_time.strftime('%H:00')
analysis['time_distribution'][hour] = analysis['time_distribution'].get(hour, 0) + 1
# 触发器统计
trigger_name = event.get('name', 'Unknown')
analysis['top_triggers'][trigger_name] = analysis['top_triggers'].get(trigger_name, 0) + 1
return analysis
def create_charts(self, analysis, output_dir):
"""
创建图表
"""
# 严重程度饼图
if analysis['by_severity']:
plt.figure(figsize=(10, 8))
# 饼图
plt.subplot(2, 2, 1)
labels = [f'级别 {k}' for k in analysis['by_severity'].keys()]
sizes = list(analysis['by_severity'].values())
colors = ['#17a2b8', '#ffc107', '#dc3545', '#c82333', '#721c24']
plt.pie(sizes, labels=labels, colors=colors[:len(labels)], autopct='%1.1f%%')
plt.title('报警严重程度分布')
# 主机报警柱状图(前10)
plt.subplot(2, 2, 2)
top_hosts = sorted(analysis['by_host'].items(), key=lambda x: x[1], reverse=True)[:10]
if top_hosts:
hosts = [h[0] for h in top_hosts]
counts = [h[1] for h in top_hosts]
plt.barh(hosts, counts)
plt.title('Top 10 报警主机')
plt.xlabel('报警次数')
# 时间分布折线图
plt.subplot(2, 1, 2)
sorted_times = sorted(analysis['time_distribution'].items())
times = [t[0] for t in sorted_times]
counts = [t[1] for t in sorted_times]
plt.plot(times, counts, marker='o')
plt.title('报警时间分布')
plt.xlabel('时间')
plt.ylabel('报警次数')
plt.xticks(rotation=45)
plt.tight_layout()
chart_path = os.path.join(output_dir, 'alert_charts.png')
plt.savefig(chart_path, dpi=150, bbox_inches='tight')
plt.close()
return chart_path
return None
def generate_detailed_html_report(self, events, analysis, chart_path=None):
"""
生成详细的HTML报表
"""
severity_map = {
'0': '未分类',
'1': '信息',
'2': '警告',
'3': '一般严重',
'4': '严重',
'5': '灾难'
}
today = datetime.datetime.now().strftime('%Y年%m月%d日')
html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Zabbix监控报警日报表 - {today}</title>
<style>
body {{ font-family: 'Microsoft YaHei', Arial, sans-serif; margin: 20px; background-color: #f5f5f5; }}
.container {{ max-width: 1200px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }}
.header {{ text-align: center; padding: 20px 0; border-bottom: 3px solid #007bff; margin-bottom: 30px; }}
.report-title {{ color: #007bff; font-size: 28px; margin: 0; }}
.report-subtitle {{ color: #6c757d; font-size: 16px; }}
.summary-cards {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 30px 0; }}
.card {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; text-align: center; }}
.card-count {{ font-size: 36px; font-weight: bold; margin: 10px 0; }}
.card-label {{ font-size: 14px; opacity: 0.9; }}
.section {{ margin: 40px 0; }}
.section-title {{ color: #495057; border-left: 4px solid #007bff; padding-left: 15px; font-size: 20px; margin-bottom: 20px; }}
table {{ width: 100%; border-collapse: collapse; }}
th {{ background: #007bff; color: white; padding: 12px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #dee2e6; }}
tr:hover {{ background-color: #f8f9fa; }}
.severity-badge {{ padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: bold; }}
.severity-0 {{ background: #6c757d; color: white; }}
.severity-1 {{ background: #17a2b8; color: white; }}
.severity-2 {{ background: #ffc107; color: #212529; }}
.severity-3 {{ background: #dc3545; color: white; }}
.severity-4 {{ background: #c82333; color: white; }}
.severity-5 {{ background: #721c24; color: white; }}
.chart-container {{ text-align: center; margin: 30px 0; }}
.chart-img {{ max-width: 100%; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }}
.footer {{ margin-top: 50px; padding-top: 20px; border-top: 1px solid #dee2e6; text-align: center; color: #6c757d; font-size: 12px; }}
.no-data {{ text-align: center; padding: 50px; color: #6c757d; font-style: italic; }}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 class="report-title">Zabbix监控系统报警日报表</h1>
<div class="report-subtitle">报表生成时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</div>
</div>
<div class="summary-cards">
<div class="card">
<div class="card-count">{analysis['total_alerts']}</div>
<div class="card-label">总报警数量</div>
</div>
<div class="card">
<div class="card-count">{len(analysis['by_host'])}</div>
<div class="card-label">涉及主机</div>
</div>
<div class="card">
<div class="card-count">{len(analysis['top_triggers'])}</div>
<div class="card-label">报警类型</div>
</div>
</div>
"""
# 如果有图表,添加图表
if chart_path and os.path.exists(chart_path):
html += f"""
<div class="section">
<h2 class="section-title">统计图表</h2>
<div class="chart-container">
<img src="cid:alert_charts" alt="统计图表" class="chart-img">
</div>
</div>
"""
# 报警详情表格
html += """
<div class="section">
<h2 class="section-title">报警详情</h2>
"""
if events:
html += """
<table>
<thead>
<tr>
<th>发生时间</th>
<th>主机名称</th>
<th>报警信息</th>
<th>严重程度</th>
<th>持续时间</th>
<th>确认状态</th>
</tr>
</thead>
<tbody>
"""
for event in events[:50]: # 只显示前50条
# 获取主机信息
trigger = self.zabbix.trigger.get({
'output': 'extend',
'triggerids': event['objectid'],
'selectHosts': ['hostid', 'name']
})
host_name = 'Unknown'
if trigger and trigger[0].get('hosts'):
host_name = trigger[0]['hosts'][0]['name']
# 转换时间
event_time = datetime.datetime.fromtimestamp(int(event['clock']))
event_time_str = event_time.strftime('%m-%d %H:%M:%S')
# 计算持续时间
duration = datetime.datetime.now() - event_time
hours = duration.seconds // 3600
minutes = (duration.seconds % 3600) // 60
duration_str = f"{hours}小时{minutes}分钟" if hours > 0 else f"{minutes}分钟"
# 确认状态
ack_status = "已确认" if event.get('acknowledged') == '1' else "未确认"
# 严重程度
severity = event.get('severity', '0')
severity_text = severity_map.get(severity, '未知')
html += f"""
<tr>
<td>{event_time_str}</td>
<td>{host_name}</td>
<td>{event.get('name', 'N/A')}</td>
<td><span class="severity-badge severity-{severity}">{severity_text}</span></td>
<td>{duration_str}</td>
<td>{ack_status}</td>
</tr>
"""
html += """
</tbody>
</table>
"""
else:
html += """
<div class="no-data">
<h3>🎉 恭喜!</h3>
<p>在统计时间段内没有发现报警事件</p>
<p>系统运行状态良好</p>
</div>
"""
html += """
</div>
<div class="footer">
<p>本报表由Zabbix监控系统自动生成</p>
<p>如有疑问,请联系系统管理员</p>
</div>
</div>
</body>
</html>
"""
return html
def send_report_email(self, html_content, attachments=None, subject=None):
"""
发送报表邮件
"""
if subject is None:
today = datetime.datetime.now().strftime('%Y-%m-%d')
subject = f"Zabbix监控日报表 - {today}"
# 创建邮件
msg = MIMEMultipart('related')
msg['Subject'] = subject
msg['From'] = self.smtp_config['from_email']
msg['To'] = ', '.join(self.smtp_config['recipients'])
# HTML内容
html_part = MIMEText(html_content, 'html', 'utf-8')
msg.attach(html_part)
# 添加附件
if attachments:
for attachment_path in attachments:
if os.path.exists(attachment_path):
with open(attachment_path, 'rb') as f:
attach_part = MIMEApplication(f.read(), Name=os.path.basename(attachment_path))
attach_part['Content-Disposition'] = f'attachment; filename="{os.path.basename(attachment_path)}"'
msg.attach(attach_part)
# 发送邮件
try:
smtp = smtplib.SMTP(self.smtp_config['smtp_server'], self.smtp_config['smtp_port'])
smtp.starttls()
smtp.login(self.smtp_config['username'], self.smtp_config['password'])
smtp.send_message(msg)
smtp.quit()
print("邮件发送成功!")
return True
except Exception as e:
print(f"邮件发送失败: {str(e)}")
return False
def run_daily_report(self):
"""
运行日报表生成和发送
"""
print(f"开始生成Zabbix日报表 - {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
# 计算时间范围(昨天00:00到今天00:00)
today = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
yesterday = today - datetime.timedelta(days=1)
start_time = int(yesterday.timestamp())
end_time = int(today.timestamp())
print(f"统计时间范围: {yesterday} 至 {today}")
# 获取报警数据
events = self.get_alerts_by_time_range(start_time, end_time)
print(f"获取到 {len(events)} 条报警记录")
# 分析数据
analysis = self.analyze_alerts(events)
# 创建输出目录
output_dir = '/tmp/zabbix_reports'
os.makedirs(output_dir, exist_ok=True)
# 生成图表
chart_path = self.create_charts(analysis, output_dir)
# 生成HTML报表
html_report = self.generate_detailed_html_report(events, analysis, chart_path)
# 保存HTML报表
report_filename = f"zabbix_report_{datetime.datetime.now().strftime('%Y%m%d')}.html"
report_path = os.path.join(output_dir, report_filename)
with open(report_path, 'w', encoding='utf-8') as f:
f.write(html_report)
print(f"HTML报表已保存: {report_path}")
# 准备附件
attachments = [report_path]
if chart_path:
attachments.append(chart_path)
# 发送邮件
subject = f"Zabbix监控日报表 - {yesterday.strftime('%Y-%m-%d')}"
success = self.send_report_email(html_report, attachments, subject)
if success:
print("日报表邮件发送完成")
else:
print("日报表邮件发送失败")
return success
def main():
"""
主函数
"""
# 配置文件示例 (config.json)
config_example = {
"zabbix": {
"url": "http://your-zabbix-server/zabbix",
"username": "Admin",
"password": "zabbix"
},
"smtp": {
"smtp_server": "smtp.example.com",
"smtp_port": 587,
"username": "your_email@example.com",
"password": "your_password",
"from_email": "zabbix@example.com",
"recipients": ["admin1@example.com", "admin2@example.com"]
}
}
# 检查配置文件是否存在
if not os.path.exists('config.json'):
print("创建配置文件 config.json")
with open('config.json', 'w', encoding='utf-8') as f:
json.dump(config_example, f, indent=2, ensure_ascii=False)
print("请修改 config.json 中的配置信息")
return
# 运行报表生成
try:
generator = ZabbixReportGenerator('config.json')
generator.run_daily_report()
except Exception as e:
print(f"报表生成失败: {str(e)}")
sys.exit(1)
if __name__ == "__main__":
main()
4. 配置cron定时任务
# 编辑crontab
crontab -e
# 每天8:30发送日报表
30 8 * * * /usr/bin/python3 /path/to/zabbix_report.py
# 每小时发送报警汇总
0 * * * * /usr/bin/python3 /path/to/zabbix_hourly_report.py
# 每周一发送周报表
30 9 * * 1 /usr/bin/python3 /path/to/zabbix_weekly_report.py
5. 快速部署脚本
#!/bin/bash
# deploy_zabbix_report.sh
echo "安装必要的Python包..."
pip install pyzabbix pandas matplotlib
echo "创建配置文件..."
cat > config.json << 'EOF'
{
"zabbix": {
"url": "http://your-zabbix-server/zabbix",
"username": "Admin",
"password": "your_password"
},
"smtp": {
"smtp_server": "smtp.example.com",
"smtp_port": 587,
"username": "your_email@example.com",
"password": "your_email_password",
"from_email": "zabbix@example.com",
"recipients": ["admin@example.com"]
}
}
EOF
echo "请修改 config.json 文件中的配置信息"
echo "然后运行: python3 zabbix_report.py"
6. 使用说明
6.1 安装依赖
pip install pyzabbix pandas matplotlib
6.2 配置修改
修改配置文件中的Zabbix服务器地址和认证信息
配置SMTP邮件服务器信息
设置收件人列表
6.3 运行测试
# 测试邮件发送
python3 send_mail.py --help
# 运行日报表
python3 zabbix_report.py
# 测试API连接
python3 -c "from pyzabbix import ZabbixAPI; z = ZabbixAPI('http://your-zabbix-server/zabbix'); z.login('Admin', 'password'); print('连接成功')"
7. 高级功能扩展
7.1 添加邮件模板
def load_email_template(template_name, data):
"""
加载邮件模板
"""
template_path = f"templates/{template_name}.html"
with open(template_path, 'r', encoding='utf-8') as f:
template = f.read()
# 替换模板变量
for key, value in data.items():
template = template.replace(f'{{{{ {key} }}}}', str(value))
return template
7.2 数据库存储历史报表
import sqlite3
class ReportDatabase:
def __init__(self, db_path='reports.db'):
self.conn = sqlite3.connect(db_path)
self.create_tables()
def create_tables(self):
cursor = self.conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS daily_reports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
report_date DATE,
total_alerts INTEGER,
html_content TEXT,
sent_time TIMESTAMP
)
''')
self.conn.commit()
这个完整的解决方案提供了:
邮件发送功能
多种报表格式(HTML/纯文本)
数据统计分析
图表生成
定时任务配置
可扩展的架构
您可以根据实际需求调整和扩展这些代码。