# sar-报表集成多个网卡、CPU、内存，输出为PDF，并自动发日报邮件（mailx）

你这个需求可以通过以下组合来实现：

---

## ✅ 一、采集工具：`sysstat`（提供 sar 数据）

- 默认安装后已自动收集网卡、CPU、内存等历史数据，保存在 `/var/log/sysstat/saXX`。
- 确保服务启动：
    
    ```bash
    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 示例脚本结构（建议每日运行）

### 🔧 依赖安装

```bash
sudo apt install sysstat mailx
pip install matplotlib pandas

```

### 📜 Python 脚本核心（简化结构）

```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）

编辑定时任务：

```bash
crontab -e

```

添加：

```bash
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），都可以继续拓展脚本。

是否需要我帮你生成完整脚本并打包？或者加一个多主机日报支持？