告别熬夜!用 Python 自动化生成服务器监控报告,运维效率翻倍
作为一名资深运维工程师,我深知服务器监控的重要性。每天登录服务器,手动查看 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:可以参考
最后,祝大家使用愉快!如果在使用过程中遇到任何问题,欢迎留言交流。