sar-报表集成多个网卡、CPU、内存,输出为PDF,并自动发日报邮件(mailx)
你这个需求可以通过以下组合来实现:
✅ 一、采集工具:sysstat
(提供 sar 数据)
-
默认安装后已自动收集网卡、CPU、内存等历史数据,保存在
/var/log/sysstat/saXX
。 -
确保服务启动:
sudo systemctl enable sysstat sudo systemctl start sysstat
✅ 二、数据提取 + 图表生成(Python 脚本)
用 Python 自动读取 sar 数据,生成图表,并导出 PDF 报告:
脚本功能:
-
使用
sar
提取:-
网卡流量(rx/tx)
-
CPU 使用率(idle, user, system)
-
内存使用(free, used, available)
-
-
使用
matplotlib
生成图表(折线图) -
用
reportlab
/matplotlib.backends.backend_pdf
导出 PDF 报告 -
最终用
mailx
自动发邮件
✅ 三、Python 示例脚本结构(建议每日运行)
🔧 依赖安装
sudo apt install sysstat mailx
pip install matplotlib pandas
📜 Python 脚本核心(简化结构)
import os
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import subprocess
from datetime import datetime
# 网卡、CPU、内存数据抓取命令
today = datetime.now().strftime("%d")
safile = f"/var/log/sysstat/sa{today}"
iface = "eth0"
def run_sar(cmd):
result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
return result.stdout.decode('utf-8').splitlines()
# 网卡流量
def get_net_data():
lines = run_sar(f"sar -n DEV -f {safile} | grep {iface}")
data = []
for line in lines:
parts = line.split()
if len(parts) >= 8 and parts[1] != 'IFACE':
data.append([f"{parts[0]} {parts[1]}", float(parts[4]), float(parts[5])])
df = pd.DataFrame(data, columns=["Time", "rx_kB", "tx_kB"])
return df
# CPU 使用率
def get_cpu_data():
lines = run_sar(f"sar -u -f {safile}")
data = []
for line in lines:
parts = line.split()
if len(parts) >= 8 and parts[1] != 'CPU':
data.append([f"{parts[0]} {parts[1]}", 100 - float(parts[7])]) # 使用率 = 100 - idle
df = pd.DataFrame(data, columns=["Time", "CPU_Usage"])
return df
# 内存使用率
def get_mem_data():
lines = run_sar(f"sar -r -f {safile}")
data = []
for line in lines:
parts = line.split()
if len(parts) >= 5 and parts[1] != 'kbmemfree':
total = float(parts[3]) + float(parts[1])
used_pct = 100 * float(parts[3]) / total
data.append([f"{parts[0]} {parts[1]}", used_pct])
df = pd.DataFrame(data, columns=["Time", "Mem_Used"])
return df
# 生成图表并导出为 PDF
def generate_pdf():
pdf_file = "/tmp/system_report.pdf"
with PdfPages(pdf_file) as pdf:
for title, df, ycol in [
("Net Usage (kB/s)", get_net_data(), ["rx_kB", "tx_kB"]),
("CPU Usage (%)", get_cpu_data(), ["CPU_Usage"]),
("Memory Usage (%)", get_mem_data(), ["Mem_Used"]),
]:
df.set_index("Time", inplace=True)
df[ycol].plot(figsize=(10, 4), title=title)
plt.xticks(rotation=45)
plt.tight_layout()
pdf.savefig()
plt.close()
return pdf_file
# 发送邮件
def send_mail(pdf_path):
subject = f"Daily System Report - {datetime.now().strftime('%Y-%m-%d')}"
cmd = f'echo "Please find the attached system usage report." | mailx -a {pdf_path} -s "{subject}" you@example.com'
subprocess.run(cmd, shell=True)
# 主逻辑
pdf = generate_pdf()
send_mail(pdf)
✅ 四、定时任务设置(crontab)
编辑定时任务:
crontab -e
添加:
0 8 * * * /usr/bin/python3 /opt/daily_report.py
每天 8 点自动发送日报邮件。
✅ 五、效果示例(PDF 报告)
每页一个图表(如折线图):
-
Page 1: eth0 接收/发送流量(rx_kB/s, tx_kB/s)
-
Page 2: CPU 使用率 %
-
Page 3: 内存使用率 %
如需支持多网卡(eth0, ens33, lo 等)、加上磁盘IO、TCP连接数、服务运行状态(如 nginx、mysql),都可以继续拓展脚本。
是否需要我帮你生成完整脚本并打包?或者加一个多主机日报支持?
No Comments