告别熬夜!用 Python 自动化生成服务器监控报告,运维效率翻倍
1. 需求分析
2. 技术选型
3. 代码实现
3.1 安装依赖库
3.2 编写监控脚本
3.3 配置邮箱
3.4 运行脚本
4. 优化建议
5. 总结
6. 常见问题解答
作为一名资深运维工程师,我深知服务器监控的重要性。每天登录服务器,手动查看 CPU、内存、磁盘、网络等指标,不仅耗时费力,还容易遗漏关键信息。更痛苦的是,领导时不时要一份服务器运行状况报告,加班熬夜整理数据更是家常便饭。
为了摆脱这种苦逼的状况,我决定用 Python 写一个自动化脚本,定期生成服务器监控报告,并自动发送给相关人员。经过一段时间的摸索和实践,我终于成功地实现了这个目标。现在,我每天早上上班第一件事就是打开邮件,查看自动生成的服务器监控报告,服务器的运行状况一目了然,再也不用担心错过任何异常情况了。领导对我的工作效率也赞不绝口,升职加薪指日可待!
今天,我就将这个自动化脚本的实现过程分享给大家,希望能帮助大家摆脱繁琐的服务器监控工作,提高运维效率,早日实现升职加薪的梦想。
1. 需求分析
在编写脚本之前,我们需要明确以下需求:
- 监控指标:CPU 使用率、内存使用率、磁盘空间、网络流量
- 报告格式:包含指标的趋势图和统计数据
- 报告发送:自动发送给指定邮箱
- 定时执行:每天定时执行一次
2. 技术选型
- 编程语言:Python
- 监控工具:psutil
- 绘图工具:matplotlib
- 邮件发送:smtplib
- 定时任务:schedule
3. 代码实现
3.1 安装依赖库
首先,我们需要安装所需的 Python 库:
pip install psutil matplotlib schedule
3.2 编写监控脚本
接下来,我们编写监控脚本 monitor.py
:
import psutil import matplotlib.pyplot as plt import datetime import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import schedule import time # 配置信息 EMAIL_HOST = 'smtp.example.com' # SMTP 服务器地址 EMAIL_PORT = 587 # SMTP 端口 EMAIL_HOST_USER = 'your_email@example.com' # 发件人邮箱 EMAIL_HOST_PASSWORD = 'your_email_password' # 发件人邮箱密码 EMAIL_TO = ['recipient1@example.com', 'recipient2@example.com'] # 收件人邮箱列表 # 数据存储 cpu_usage_history = [] memory_usage_history = [] disk_usage_history = [] network_sent_history = [] network_received_history = [] timestamps = [] def get_cpu_usage(): return psutil.cpu_percent(interval=1) def get_memory_usage(): return psutil.virtual_memory().percent def get_disk_usage(): return psutil.disk_usage('/').percent def get_network_usage(): net_io = psutil.net_io_counters() return net_io.bytes_sent, net_io.bytes_recv def collect_data(): cpu_usage = get_cpu_usage() memory_usage = get_memory_usage() disk_usage = get_disk_usage() network_sent, network_received = get_network_usage() timestamp = datetime.datetime.now() cpu_usage_history.append(cpu_usage) memory_usage_history.append(memory_usage) disk_usage_history.append(disk_usage) network_sent_history.append(network_sent) network_received_history.append(network_received) timestamps.append(timestamp) print(f"{timestamp}: CPU={cpu_usage}%, Memory={memory_usage}%, Disk={disk_usage}%, Network Sent={network_sent}, Received={network_received}") def generate_report(): # 创建图表 fig, axs = plt.subplots(2, 2, figsize=(16, 12)) # CPU 使用率 axs[0, 0].plot(timestamps, cpu_usage_history) axs[0, 0].set_title('CPU Usage (%)') axs[0, 0].set_xlabel('Time') axs[0, 0].set_ylabel('Usage (%)') axs[0, 0].tick_params(axis='x', rotation=45) axs[0, 0].grid(True) # 内存使用率 axs[0, 1].plot(timestamps, memory_usage_history) axs[0, 1].set_title('Memory Usage (%)') axs[0, 1].set_xlabel('Time') axs[0, 1].set_ylabel('Usage (%)') axs[0, 1].tick_params(axis='x', rotation=45) axs[0, 1].grid(True) # 磁盘使用率 axs[1, 0].plot(timestamps, disk_usage_history) axs[1, 0].set_title('Disk Usage (%)') axs[1, 0].set_xlabel('Time') axs[1, 0].set_ylabel('Usage (%)') axs[1, 0].tick_params(axis='x', rotation=45) axs[1, 0].grid(True) # 网络流量 axs[1, 1].plot(timestamps, network_sent_history, label='Sent') axs[1, 1].plot(timestamps, network_received_history, label='Received') axs[1, 1].set_title('Network Traffic (Bytes)') axs[1, 1].set_xlabel('Time') axs[1, 1].set_ylabel('Bytes') axs[1, 1].tick_params(axis='x', rotation=45) axs[1, 1].grid(True) axs[1, 1].legend() # 调整布局 plt.tight_layout() # 保存图表 report_filename = 'server_report.png' plt.savefig(report_filename) plt.close(fig) return report_filename def send_email_report(report_filename): msg = MIMEMultipart() msg['From'] = EMAIL_HOST_USER msg['To'] = ', '.join(EMAIL_TO) msg['Subject'] = '服务器监控报告' text = """尊敬的运维团队: 附件是服务器监控报告,请查阅。 祝您工作顺利! """ msg.attach(MIMEText(text, 'plain')) with open(report_filename, 'rb') as f: img_data = f.read() from email.mime.image import MIMEImage image = MIMEImage(img_data, name=report_filename) msg.attach(image) try: server = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) server.starttls() server.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD) server.sendmail(EMAIL_HOST_USER, EMAIL_TO, msg.as_string()) print('邮件发送成功') except Exception as e: print(f'邮件发送失败: {e}') finally: server.quit() def job(): print('开始收集数据...') collect_data() print('数据收集完成.') print('开始生成报告...') report_file = generate_report() print('报告生成完成.') print('开始发送邮件...') send_email_report(report_file) print('邮件发送完成.') # 每天早上 8 点执行任务 schedule.every().day.at("08:00").do(job) while True: schedule.run_pending() time.sleep(60) # 每分钟检查一次是否有任务需要执行
代码解释:
- 导入所需库:
psutil
用于获取系统信息,matplotlib
用于绘制图表,smtplib
用于发送邮件,schedule
用于定时执行任务。 - 配置信息:需要配置 SMTP 服务器地址、端口、发件人邮箱、密码、收件人邮箱等信息。
- 数据存储:使用列表存储 CPU、内存、磁盘、网络等指标的历史数据。
get_cpu_usage()
、get_memory_usage()
、get_disk_usage()
、get_network_usage()
:分别用于获取 CPU 使用率、内存使用率、磁盘空间、网络流量。collect_data()
:用于收集各项指标数据,并将数据存储到列表中。generate_report()
:用于生成监控报告,包括 CPU、内存、磁盘、网络等指标的趋势图,并将图表保存为server_report.png
文件。send_email_report()
:用于发送邮件报告,将server_report.png
文件作为附件发送给指定邮箱。job()
:定义一个任务,包括收集数据、生成报告、发送邮件。schedule.every().day.at("08:00").do(job)
:设置每天早上 8 点执行job()
任务。while True
:循环执行schedule.run_pending()
,用于检查是否有任务需要执行。
3.3 配置邮箱
在使用脚本之前,需要在邮箱中开启 SMTP 服务,并获取授权码。不同邮箱的开启方式可能有所不同,请参考相关文档。
注意: 为了安全起见,建议使用专门用于发送邮件的邮箱,并设置独立密码。
3.4 运行脚本
将脚本保存为 monitor.py
文件,并在终端中运行:
python monitor.py
脚本会每分钟检查一次是否有任务需要执行,当时间到达早上 8 点时,会自动执行 job()
任务,收集数据、生成报告、发送邮件。
4. 优化建议
- 数据持久化:可以将监控数据存储到数据库中,方便后续分析和查询。
- 告警功能:可以设置告警阈值,当指标超过阈值时,自动发送告警邮件或短信。
- 更丰富的监控指标:可以添加更多监控指标,例如进程状态、TCP 连接数等。
- Web 界面:可以将监控报告展示在 Web 界面上,方便用户查看。
- 日志记录:添加日志记录功能,方便排查问题。
- 异常处理:增加异常处理,例如网络连接失败、邮箱发送失败等。
5. 总结
通过编写 Python 脚本,我们可以自动化生成服务器监控报告,极大地提高了运维效率。当然,这只是一个简单的示例,大家可以根据自己的需求进行扩展和优化。
希望这篇文章能帮助大家摆脱繁琐的服务器监控工作,提高运维效率,早日实现升职加薪的梦想!
6. 常见问题解答
- Q:为什么我收不到邮件?
- A:请检查邮箱配置是否正确,包括 SMTP 服务器地址、端口、发件人邮箱、密码、收件人邮箱等。另外,请确保邮箱已开启 SMTP 服务,并获取授权码。同时检查邮件是否被拦截到垃圾箱。
- Q:为什么我的图表显示不出来中文?
- A:需要在代码中设置字体,例如:
plt.rcParams['font.sans-serif']=['SimHei']
。
- A:需要在代码中设置字体,例如:
- Q:为什么我的脚本运行报错?
- A:请检查是否安装了所需的 Python 库,例如
psutil
、matplotlib
、schedule
。另外,请仔细阅读报错信息,根据提示进行排查。
- A:请检查是否安装了所需的 Python 库,例如
- Q:如何修改定时执行的时间?
- A:修改
schedule.every().day.at("08:00").do(job)
中的时间即可,例如修改为schedule.every().day.at("10:00").do(job)
表示每天早上 10 点执行。
- A:修改
- Q:如何添加更多的监控指标?
- A:可以参考
psutil
库的文档,获取更多的系统信息,例如进程状态、TCP 连接数等。然后,将这些信息添加到collect_data()
函数中,并在generate_report()
函数中绘制相应的图表。
- A:可以参考
最后,祝大家使用愉快!如果在使用过程中遇到任何问题,欢迎留言交流。