Skip to content

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Server Scan

服务器性能诊断工具集,自动生成标准 Markdown 分析报告。

支持两种使用方式:

  • 统一入口 server-scan:子命令风格,适合 Agent 调用
  • 独立脚本:直接执行各 .sh 脚本

工具列表

脚本 子命令 功能 适用场景
core/sys_overview.sh overview 系统瓶颈总览 快速扫描 CPU / 内存 / 磁盘 / 网络
core/cpu_mem_analyzer.sh cpu-mem CPU / 内存深度分析 排查负载高、内存不足、OOM 风险
core/disk_analyzer.sh disk 磁盘空间 / IO / 健康分析 排查磁盘满、IO 瓶颈、SMART 预警
core/network_analyzer.sh network 网络专项排查 接口、连通性、连接数、DNS
core/security_scanner.sh security 杀毒软件 / 主机安全防护检测 排查服务器上是否部署杀毒 / HIDS / EDR
core/cron_setup.sh cron 定时任务管理 交互式配置 crontab 定时巡检

目录结构

server-scan/
├── server-scan              # 统一入口(根目录下唯一的可执行入口)
├── core/                    # 各专项诊断脚本
│   ├── sys_overview.sh
│   ├── cpu_mem_analyzer.sh
│   ├── disk_analyzer.sh
│   ├── network_analyzer.sh
│   ├── security_scanner.sh
│   └── cron_setup.sh       # 定时任务管理
├── lib/                     # 共享库与语言包
│   ├── common.sh            # 通用函数(进度、报告、超时、配置加载)
│   ├── cli.sh               # 统一 CLI 参数解析
│   ├── alerts.sh            # 结构化告警收集与 JSON 输出
│   ├── notify.sh            # 通知推送(飞书)
│   └── i18n/                # 中英文语言包
├── output/                  # 扫描产物(报告 + 告警 JSON,运行后生成,不入库)
├── server-scan.conf.example # 统一配置示例(所有扫描脚本共用一份)
└── notify.conf.example      # 通知配置示例(含密钥,需 chmod 600)

分析脚本统一收拢在 core/,根目录只保留 server-scan 作为全局入口。 脚本通过 SCRIPT_DIR 自动定位项目根目录,因此 lib/、配置文件、通知配置的查找路径均不受影响。

快速开始

使用统一入口

# 赋予执行权限
chmod +x server-scan core/*.sh

# 查看帮助
./server-scan --help

# 运行系统瓶颈总览
./server-scan overview

# 磁盘专项分析
./server-scan disk

# 指定目录扫描(只扫描指定目录,跳过全盘扫描)
./server-scan disk -d /var/log
./server-scan disk -d /var/log -d /home/user
./server-scan disk -d "/var/log /home/user" --depth 5 --top 30

# 分类扫描(只关注部分类别,章节号自动连续)
./server-scan disk --only docker
./server-scan disk --only docker,temp
./server-scan disk --only usage

# Docker 数据目录非默认时(如 data-root 迁到 /data/docker),指定目录扫描
./server-scan disk --only docker --docker-dir /data/docker

# 扫描杀毒软件 / 主机安全防护
./server-scan security

# 运行所有诊断
./server-scan all

直接执行脚本

./core/sys_overview.sh
./core/cpu_mem_analyzer.sh
./core/disk_analyzer.sh
./core/network_analyzer.sh
./core/security_scanner.sh

公共 CLI 选项

所有脚本支持以下公共选项:

选项 说明
-o, --output PATH 报告输出路径(默认: output/<脚本>/<脚本>_<时间戳>.md,可用 OUTPUT_DIR 环境变量修改根目录)
-c, --config FILE 指定配置文件(覆盖默认配置文件查找)
-q, --quiet 静默模式(只输出报告路径一行,供 Agent 解析)
--json 在 stdout 输出一行 JSON 元数据(供 Agent 程序化消费)
--no-color 禁用 ANSI 颜色(Agent 调用时必需)
--lang LANG 指定输出语言(zh_CN / en_US,默认跟随系统 LANG)
--notify 启用通知推送(默认已启用,此参数用于显式声明)
--no-notify 关闭本次运行的通知推送
--notify-channel NAME 指定通知渠道(默认: feishu)
--webhook URL 指定 webhook 地址(覆盖配置文件)
--notify-test 发送一条测试消息,验证通知配置是否正确
-h, --help 显示帮助信息

脚本特定选项

core/disk_analyzer.sh:

选项 说明
-d, --dir DIR 指定扫描目录(可多次指定或使用空格分隔多个目录)
--depth N 子目录扫描深度(默认: 3)
--top N 显示 Top N 结果(默认: 20)
--only CAT[,CAT] 只扫描指定类别(默认 all),详见下方分类扫描
--docker-dir DIR 指定 Docker 数据目录(data-root 非默认时使用,优先级最高)
--docker-log-dir DIR 指定 Docker 容器日志目录(默认: <数据目录>/containers)

core/network_analyzer.sh:

选项 说明
--ping-targets "IP1 IP2" 连通性探测目标(默认: 8.8.8.8 1.1.1.1)
--dns-targets "D1 D2" DNS 解析测试域名(默认: www.baidu.com www.google.com)

core/cpu_mem_analyzer.sh:

选项 说明
--no-mpstat 禁用多核采样(Linux 下有效)
--interval N 采样间隔(秒,默认: 1)
--count N 采样次数(默认: 3)

磁盘分类扫描 (--only)

默认扫描全部类别。使用 --only 只扫描关注的部分,章节号会自动保持连续:

类别 覆盖内容
usage 磁盘基础信息、空间使用率、inode 使用率
io I/O 性能采样(含实时 I/O 快照,需 ENABLE_REALTIME_IO=true)
large 大文件与目录扫描
logs 日志文件专项扫描
lvm LVM 逻辑卷信息
health 磁盘健康状态 (SMART)
mount 挂载参数与文件系统特性
docker Docker 空间占用专项扫描
temp 临时文件与缓存占用
all 全部类别(默认)
# 只看 Docker 空间占用
./server-scan disk --only docker

# 同时看 Docker 与临时文件
./server-scan disk --only docker,temp

# 只看空间与 inode(最快速的健康检查)
./server-scan disk --only usage

docker 类别依赖 Docker 数据目录,解析优先级为:

--docker-dir 命令行参数 > 配置文件 DOCKER_DATA_DIR > docker info 探测 > 默认 /var/lib/docker

当 docker 的 data-root 被改为非默认路径(常见于数据盘独立挂载,如 /data/docker)时, 必须显式指定,否则会误扫 /var/lib/docker —— 该目录在迁移后常作为残留空目录保留, 会使空间统计严重失真。指定的路径无效时会输出告警并回退自动探测,不会静默出错。

容器日志目录默认取 <数据目录>/containers;若日志与数据目录分离,可用 --docker-log-dir 或配置文件 DOCKER_LOG_DIR 单独指定。即便 docker 命令不可用,只要显式指定了数据目录, 仍会执行目录级空间与日志扫描。

temp 类别会扫描 /tmp、/var/tmp 以及系统缓存目录(Linux: /var/cache、~/.cache;macOS: ~/Library/Caches), 输出各目录占用、大文件 Top N、长期未访问的清理候选与可清理空间合计。 脚本只给出清理建议,不会删除任何文件。

--only 与 -d/--dir 互斥:目录模式只扫描指定目录,分类过滤不适用。

Agent 集成

扫描产物

产物默认保存在项目根目录的 output/ 下,按脚本标识分目录归档,便于查看历史与清理:

output/
├── sys_overview/
│   ├── sys_overview_20260904_094218.md     # Markdown 报告(人类阅读)
│   └── sys_overview_20260904_094218.json   # 结构化告警(机器消费)
├── disk/
│   └── disk_20260904_094545.{md,json}
├── cpu_mem/
├── network/
└── security/
  • 同一文件名成对出现:.md 报告 + .json 结构化告警,JSON 路径即把报告后缀 .md 换成 .json
  • 产物根目录可用 OUTPUT_DIR 环境变量覆盖(如 OUTPUT_DIR=/var/log/server-scan),也可用 -o 完全自定义路径
  • 告警 JSON 与 Markdown 报告同源于一次扫描,避免两份结果不一致
  • 产物目录不纳入版本控制(见 .gitignore)

告警 JSON 结构(schema_version: 1.0):

{
  "schema_version": "1.0",
  "script": "sys_overview.sh",
  "hostname": "server01",
  "timestamp": "2026-09-04T01:42:21Z",
  "report_path": "output/sys_overview/sys_overview_20260904_094218.md",
  "summary": {"total": 2, "critical": 1, "warning": 0, "info": 0},
  "alerts": [
    {"level": "critical", "dimension": "磁盘", "metric": "磁盘使用率",
     "object": "/dev/disk5s1", "value": "97%", "threshold": "90%",
     "detail": "挂载点 /private/var/run/...", "suggestion": "清理该挂载点或扩容"}
  ]
}

字段含义:level(critical/warning/info)、dimension 维度、metric 指标名、object 对象 (如文件系统)、value 当前值、threshold 阈值、detail 补充细节、suggestion 建议。 每个 alert 压缩为单行,notify 用 grep/sed 即可零依赖解析,整体仍是合法 JSON。

通知推送(默认启用,可用 --no-notify 关闭)直接读取该 JSON 的 alerts 字段构造推送正文—— 字段语义明确,不依赖从 Markdown 文本反向解析告警行。五个分析脚本现已全部产出结构化告警 JSON。

静默模式

# 静默模式:只输出报告路径一行
./server-scan overview --quiet
# 输出: output/sys_overview/sys_overview_20240101_120000.md

# JSON 输出:输出结构化元数据
./server-scan overview --json
# 输出:
# {
#   "status": "success",
#   "report_path": "output/sys_overview/sys_overview_20240101_120000.md",
#   "timestamp": "2024-01-01T12:00:00Z",
#   "hostname": "server01",
#   "script": "sys_overview.sh",
#   "duration_sec": 5,
#   "summary": "",
#   "bottlenecks": ""
# }

退出码

退出码 含义
0 成功
1 发现瓶颈(或检测到防护软件)
2 参数错误

国际化 (i18n)

支持中英文双语输出,语言优先级:SS_LANG 环境变量 > 系统 LANG > 默认中文。

# 默认中文(跟随系统语言)
./server-scan overview

# 临时切换为英文(环境变量)
SS_LANG=en_US ./server-scan overview

# 通过参数指定语言(仅当次运行生效)
./server-scan --lang en_US overview

语言包位于 lib/i18n/(zh_CN.sh、en_US.sh),新增语言只需复制模板并翻译。

系统支持

  • Linux: CentOS / Ubuntu / Debian / RHEL
  • macOS: Intel / Apple Silicon

依赖安装

Linux:

# CentOS/RHEL
yum install -y sysstat smartmontools bc

# Ubuntu/Debian
apt install -y sysstat smartmontools bc

macOS:

brew install coreutils smartmontools

报告内容

系统总览报告 (core/sys_overview.sh)

  • CPU / 内存 / 磁盘 / 网络 快速扫描
  • 综合健康度评分与瓶颈结论
  • 各维度瓶颈清单

CPU / 内存报告 (core/cpu_mem_analyzer.sh)

  • CPU 基础信息与负载评估
  • CPU 时间分布与多核采样
  • 内存总体概况与 Swap 分析
  • OOM 风险评估
  • 进程状态分布与资源消耗 Top 10
  • 上下文切换与系统句柄统计

磁盘报告 (core/disk_analyzer.sh)

  • 块设备列表与 I/O 调度器
  • 磁盘空间与 inode 使用率
  • I/O 性能采样与实时负载快照
  • 大文件与日志扫描
  • LVM 逻辑卷信息
  • SMART 健康状态
  • Docker 空间占用专项扫描
  • 指定目录空间占用分析

网络报告 (core/network_analyzer.sh)

  • 网络接口状态与流量
  • 连通性测试(可自定义目标)
  • TCP 连接状态统计
  • 端口监听扫描
  • DNS 解析测试
  • 丢包与延迟分析

安全扫描报告 (core/security_scanner.sh)

  • 内置 20+ 款常见防护软件特征库(ClamAV / CrowdStrike / 云盾 / 云镜 / Wazuh 等)
  • 四类信号交叉检测:进程名、systemd 服务、安装包(rpm/dpkg)、特征路径
  • 按类别分类:传统杀毒 / 主机安全 (HIDS) / EDR 终端防护
  • 检测结论与部署建议(只读检测,不会停止或修改任何防护软件)

自定义配置

命令行配置

# 修改报告输出路径
./server-scan overview -o /var/log/report.md

# 指定目录扫描
./server-scan disk -d /var/log --depth 5 --top 30

配置文件配置

所有扫描脚本共用一份配置文件 server-scan.conf,按变量名前缀各取所需, 不需要为每个脚本各建一个配置文件:

cp server-scan.conf.example server-scan.conf
# ---- 磁盘专项(disk_analyzer.sh)----
# 磁盘使用率警告阈值(%)
DISK_USAGE_WARNING_THRESHOLD=80
# 磁盘使用率危险阈值(%)
DISK_USAGE_CRITICAL_THRESHOLD=90
# I/O await 优秀阈值(ms)
IO_AWAIT_EXCELLENT_THRESHOLD=10
# 自定义 Docker 数据目录
DOCKER_DATA_DIR=""
# Docker 镜像 Top N
DOCKER_IMAGE_TOP=15

# ---- CPU 与内存专项(cpu_mem_analyzer.sh)----
# 采样间隔(秒)
SAMPLE_INTERVAL=1
# Swap 使用率告警阈值(%)
SWAP_USAGE_WARNING_THRESHOLD=50
# 僵尸进程 critical 阈值(个)
ZOMBIE_CRITICAL_THRESHOLD=50
# D 状态进程告警阈值(个)
D_STATE_WARNING_THRESHOLD=5

书写约定:注释请独占一行,放在变量上方,不要写成 KEY=value # 注释。 这样可以从源头避免「值里含 # 时被误判为注释」的歧义。

  • 值含空格或特殊字符(含 #)时请用引号:KEY="a #b",引号内的 # 会完整保留
  • 未加引号的值中,空白之后的 # 仍按 shell 惯例视为注释(abc#def 不受影响)
  • 已有行内注释无需手工改,config upgrade 会自动整理为独占一行

完整示例见 server-scan.conf.example。

配置文件查找顺序(找到即用,优先级从高到低):

  1. 命令行 -c/--config 指定
  2. 环境变量 CONFIG_FILE
  3. $SCRIPT_DIR/server-scan.conf
  4. $SCRIPT_DIR/disk_analyzer.conf(旧版兼容,新文件不存在时才回退)

通知推送配置独立为 notify.conf:其中含 webhook 与签名密钥, 需单独设置 chmod 600,不与普通配置项混用。详见下方 通知推送 (Channel),示例文件为 notify.conf.example。

配置迁移与升级

配置会随版本演进(文件更名、新增或废弃配置项),用 server-scan config 自动处理, 无需手工复制粘贴:

./server-scan config check      # 检查: 生效文件、拼写错误/已废弃项、缺失的新增项
./server-scan config upgrade    # 用示例配置补齐新增项(保留已有值,自动备份)
./server-scan config migrate    # 旧版 disk_analyzer.conf 迁移到统一配置
./server-scan config show       # 显示当前生效的配置文件与内容
操作 行为 备份
check 报告生效文件与来源、不在示例中的可疑键、尚未写入的新增键;有问题时退出码 1 不修改
upgrade 只追加当前配置缺失的键(取自示例的默认值),已有值与注释原样保留 server-scan.conf.bak
migrate 统一配置不存在时以旧文件为基础生成;已存在时只补入旧文件独有键,不覆盖现有值 旧文件改名 disk_analyzer.conf.bak

若仍在使用旧版 disk_analyzer.conf,每次扫描会提示执行 config migrate。

通知推送 (Channel)

支持将扫描结果推送到外部 Channel,当前内置飞书自定义机器人。

快速配置

# 1. 复制配置文件模板
cp notify.conf.example notify.conf

# 2. 填入 webhook(飞书: 群设置 -> 群机器人 -> 添加自定义机器人)
vi notify.conf

# 3. 设置权限(配置文件含密钥,禁止其他用户读取)
chmod 600 notify.conf

# 4. 验证配置是否正确
./server-scan overview --notify-test

# 5. 执行扫描(默认即推送,无需额外参数)
./server-scan overview

配置项

配置项 默认值 说明
NOTIFY_ENABLED true 是否启用推送(默认启用);设为 false 可全局关闭
NOTIFY_CHANNEL feishu 通知渠道,当前支持 feishu
NOTIFY_WEBHOOK 空 Webhook 地址(必填)
NOTIFY_SECRET 空 签名密钥,机器人开启签名校验时填写
NOTIFY_MSG_TYPE text 消息类型:text 纯文本 / card 交互式卡片
NOTIFY_MODE summary summary 仅推送告警摘要 / full 推送完整报告
NOTIFY_MAX_BYTES 20000 全文模式下正文最大字节数
NOTIFY_TIMEOUT 10 HTTP 请求超时(秒)
NOTIFY_ON_ALERT_ONLY false 仅在检测到告警(🔴/🟡)时推送
NOTIFY_MENTION_ALL false 是否 @所有人
NOTIFY_MENTION_IDS 空 @指定用户 open_id,逗号分隔
NOTIFY_SUMMARY_LINES 20 摘要模式提取的告警行上限
NOTIFY_TABLE_STYLE kv 表格呈现:kv 转列表 / code 代码块 / raw 原样

默认启用,失败不阻塞:扫描结束后即推送通知,无需加 --notify。 若未配置 NOTIFY_WEBHOOK、网络异常或渠道不支持,只会输出一条 ⚠️ 告警并跳过推送, 扫描结果与退出码不受影响(告警写 stderr,且在 --json/--quiet 下静默)。 不需要推送时用 --no-notify(单次)或 NOTIFY_ENABLED=false(全局)关闭。

配置优先级

命令行参数 > 环境变量 > 配置文件。

配置文件查找顺序(找到第一个存在的文件即停止):

  1. $NOTIFY_CONFIG
  2. 脚本 -c/--config 指定的配置文件
  3. $SCRIPT_DIR/notify.conf
  4. $HOME/.server-scan/notify.conf
  5. /etc/server-scan/notify.conf

使用示例

# 默认即推送(无需额外参数)
./server-scan overview

# 单次关闭推送
./server-scan overview --no-notify

# 临时指定 webhook(调试用;webhook 会出现在进程列表中)
./server-scan disk --notify --webhook "https://open.feishu.cn/open-apis/bot/v2/hook/xxx"

# 定时巡检,仅在有告警时推送(避免正常状态刷屏)
NOTIFY_ON_ALERT_ONLY=true ./server-scan overview --notify

# 使用非默认路径的配置文件
NOTIFY_CONFIG=/etc/server-scan/notify.conf ./server-scan network --notify

# 推送完整报告并使用卡片消息
NOTIFY_MODE=full NOTIFY_MSG_TYPE=card ./server-scan overview --notify

消息呈现

飞书 text 与卡片 lark_md 都不支持 Markdown 表格,直接推送原报告会出现大量裸竖线, 可读性很差。脚本默认(NOTIFY_TABLE_STYLE=kv)把表格转换为结构化列表:

转换前(报告中的表格):

| 级别 | 维度 | 结论 |
|------|------|------|
| 🔴 | 磁盘 | /var 使用率 97%(>= 90%) |

转换后(飞书消息中):

🔴 **磁盘**: /var 使用率 97%(>= 90%)

卡片模式下 **加粗** 会被渲染,状态 emoji 也会正常显示。 如需保留原始表格,可设置 NOTIFY_TABLE_STYLE=code(表格以代码块等宽展示)或 raw(不做转换)。

安全提示

  • notify.conf 可能包含 webhook 与签名密钥,已加入 .gitignore,请勿提交到代码仓库
  • 建议设置 chmod 600 notify.conf;权限过宽时脚本会给出警告
  • --webhook 参数会出现在进程列表中,生产环境建议改用配置文件
  • 推送失败不会影响扫描本身,也不会改变脚本退出码

定时任务

交互式配置(推荐)

# 打开交互菜单:查看 / 添加 / 删除
./server-scan cron

# 也可直接使用子命令
./server-scan cron list      # 查看已有的定时任务
./server-scan cron add       # 添加
./server-scan cron remove    # 删除

添加流程会依次引导你选择:扫描任务 → 执行频率(每小时/每天/每周/每月/自定义)→ 时间 → 报告输出目录 → 是否推送飞书(可选仅告警时推送)→ 附加参数(如 --only docker), 最后预览生成的 crontab 条目并确认后才会写入。

生成的条目示例:

# server-scan:overview
# 报告默认写入产物目录 output/,如需自定义落点可在命令中加 -o <目录>
30 2 * * * PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /path/to/server-scan overview

安全设计:

  • 只操作带 # server-scan: 标记的条目,不会影响你已有的其他定时任务
  • 每次写入前自动备份原 crontab 到 ~/.server-scan/crontab.backup.<时间戳>
  • 条目内自动补全 PATH,避免 cron 环境下找不到 iostat、smartctl 等命令
  • 自动把报告文件名中的 % 转义为 \%(cron 特殊字符)

手动配置

也可以直接编辑 crontab:

# 每小时生成一次报告
0 * * * * /path/to/server-scan overview -o /var/log/sys_overview.md
0 * * * * /path/to/server-scan disk -o /var/log/disk_report.md

# 每天凌晨 2 点巡检,仅在发现告警时推送飞书
0 2 * * * NOTIFY_ON_ALERT_ONLY=true /path/to/server-scan overview

手动配置时注意:cron 的 PATH 与终端不同,建议使用绝对路径; 命令中的 % 需转义为 \%,否则其后的内容会被当作标准输入。

许可证

MIT

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages