资讯详情

资讯详情

Linux服务器自动化巡检:Shell采集+Python输出表格实战

你有没有遇到过这种场景服务器突然磁盘打满、内存飙升、服务宕机但打电话问你的时候你只能一台一台 SSH 上去敲命令手工拼一条状态汇报运气好半小时能完事运气差直接机房熬一宿。前阵子我接手了一批服务器巡检的活一开始也是纯手工登上去 free、df、top、systemctl status 一个个看。跑了两个周期就扛不住了服务器一多光登录就要十几分钟输出格式乱漏查项也时有发生。后来我把整个流程拆成了两段——shell 负责采集Python 负责整理成表格配一个大循环把结果全部汇总出来。改完之后的体验完全不一样一条命令扫完全部机器输出整齐的表格磁盘、内存、CPU、服务状态一眼扫完谁有问题直接被标记出来。这篇文章就把这套巡检方案完整拆开讲。不管你是刚接触 Linux 运维的新手还是已经在写脚本但还在用 echo 拼字符串的老手都能从这里拿到一套可以直接用的东西。方案本身不挑发行版CentOS、Ubuntu、Debian 都能跑核心思路就两个采集和展示分离脚本和表格输出分离。1. 巡检到底在巡什么先把指标清单定下来网上的巡检脚本一搜一大把但多数脚本的通病是想到什么采集什么CPU 有了、磁盘有了、内存有了真正遇到问题时才发现漏了关键项。我在动手写脚本之前先花了两个小时把巡检指标彻底梳理了一遍原则只有一个凡是能通过命令拿到的状态就不用手工确认。1.1 硬指标CPU、内存、磁盘与负载这四个是服务器状态的基础也是告警的主要来源。CPU 我重点看使用率和负载均衡情况内存看总量、已用、可用和 Swap 的使用比例磁盘则把分区使用率超过 80% 的单独标记负载重点对比 load average 和 CPU 核数的关系。关于负载这里有个常见的误区单看 load average 数值没有意义。一台 2 核机器负载跑到 4和一台 16 核机器负载跑到 4是完全不同的状态。前者已经严重过载后者还在安全范围。脚本里我做了换算按固定公式判定负载值超过核数的 70%就提示关注超过核数则标记为严重告警。磁盘检查还有个容易踩的坑df -h 默认会把 tmpfs、overlay 这类虚拟文件系统也列出来这些数据存在内存里磁盘满没满跟它们没关系。如果脚本不做过滤巡检表格里会出现一堆让人误判的假数据。我处理的方式是直接排除这些虚拟文件系统只保留真实物理分区。内存方面很多新手看 free 命令会把“已用”理解为真正的内存消耗其实在 Linux 里还有 buff/cache 这部分。缓冲和缓存内存是可以释放的真要判断内存是否吃紧关键看 available 这个值。脚本同样做了处理显示的时候把缓存分开标注避免误导。1.2 软状态服务存活、端口监听与关键进程硬件指标正常不代表服务没问题。我见过内存、磁盘、CPU 全部正常但网站就是打不开的情况原因就是后端服务悄悄挂了或者端口被占用。服务检查分为两类系统级服务和业务级进程。系统级服务直接用 systemctl is-active 判断输出 active、inactive、failed 这些状态脚本里统一转成自定义的状态码方便 Python 侧汇总。业务进程检查则用 pgrep -f 匹配进程关键词关键词匹配有个需要注意的地方匹配关键字如果太短容易误伤别的进程如果太长又可能漏掉。我一般建议直接用启动命令里的独特参数比如 java 服务的 jar 包名称nginx 的 master process。端口监听检查用 ss -tlnp 解析这里有个细节ss 命令的输出在不同发行版上字段位置略有差异解析的时候不要用固定列号直接用正则匹配端口号后面对应的进程信息更稳。1.3 需要人看的维度登录审计、时钟同步与定时任务有些状态脚本能查但结论需要人来判断这类我也一并纳入了巡检范围。登录记录看的是当前登录的用户和登录来源 IP检查有没有异常来源。时钟同步判断用的是 chronyc tracking 或 timedatectl输出是否同步的状态。定时任务则检查 crontab 和 /etc/cron.d/ 目录下有哪些任务便于确认“是不是有人悄悄往生产服务器塞了东西”。这三项不设自动化阈值只做展示。因为“异常登录”和“异常定时任务”的判定依赖业务背景机械地设定规则容易出现误报。表格里把原始数据列出来人一眼扫过去就能判断。2. 为什么是 shell 采集、Python 出表双脚本架构的底层逻辑把巡检拆成两段脚本是我实践后觉得最优的做法。一开始我尝试过只用 shell 一个脚本干完所有事结果代码极其臃肿采集逻辑、文本解析、对齐输出全混在一起调试一次痛苦一次。后来拆分之后两边各司其职逻辑清晰了一倍不止。2.1 shell 的不可替代性服务器自带、零依赖、执行效率高出门在外跑巡检最怕的就是目标服务器上缺这少那。Python 不一定预装pip 装第三方库又不现实但 shell 是每一台 Linux 都有的东西。采集阶段用纯 shell 和 Linux 自带的命令好处极其明显零额外依赖脚本拷过去就能跑兼容性拉满。Linux 下很多系统状态只存在于 /proc 和系统命令输出里这些信息用 shell 获取几乎是零成本。比如 CPU 使用率读取 /proc/stat 再做两次采样计算内存信息直接解析 /proc/meminfo磁盘状态用 df 一条命令。Shell 脚本本身就是胶水语言把这些系统信息和命令拼接到一起效率非常高。采集阶段的耗时问题也要考虑。服务器一多每台机器上执行 df、free、top 这类命令单次耗时都在毫秒级但加起来也是一笔开销。Shell 脚本本身不会因为采集合集命令而变得笨重这是选择它做采集层的关键原因。2.2 Python 的适配性字符串处理、对齐、条件高亮都在射程内到了整理和展示阶段shell 的短板就暴露出来了。Shell 处理字符串对齐非常痛苦printf 做固定宽度输出需要精确计算中文字符宽度否则表格列全部错位。而 Python 处理这类问题天然轻松split 拆分字段、列表存储行数据、f-string 格式化对齐再配合条件判断给不同状态标色几百行数据分钟级就能整理出格式规整的表格。Python 还有一个 shell 做起来非常麻烦的事情——跨平台统一。如果不依赖第三方库Python 的字符串格式化在 Windows、macOS、Linux 上表现一致而 shell 在某些环境下多少会有差异。我们的方案是采集端必须是 shell因为要跑在目标机器上汇总和展示端用 Python跑在运维机器上两边优势互补正好卡在各自的舒适区。2.3 为什么要“可输出表格”表格是巡检结果最好的交付形态巡检结果如果不整理就是几十行无结构的文本输出。但整理成表格之后信息的密度提高了好几倍行是机器列表列是各项指标一眼扫下去就能看到哪些指标异常。表格还是最好的交付形态——可以直接贴到周报里可以转成 HTML 发邮件可以写进 Confluence 和知识库。我最终选择了两个输出方向控制台终端输出带颜色高亮的表格同时生成一个 Markdown 格式的结果文件。Markdown 的好处是通用GitLab、GitHub、Confluence 原生支持渲染不需要额外工具复制粘贴直接变表格极大地省去了“整理汇报”的时间成本。3. shell 采集脚本怎么写核心代码与关键协议采集脚本的目标是把“服务器状态”变成“结构化文本”。这里最核心的设计是定义了一套键值对输出协议所有采集结果按固定格式输出Python 再按协议解析两边互不依赖。3.1 先约定输出格式键值对协议是脚本协作的基石协议格式我定义为KEY|VALUE|STATUS三个字段用竖线分隔。KEY 是指标名称如 CPU_USAGE、MEM_USAGE、DISK_USAGEVALUE 是具体数值STATUS 是状态标记OK、WARN、CRIT 三个值。之所以这么设计是因为它足够简单shell 拼字符串不费劲Python 解析也不费劲。竖线分隔还有一个额外好处即使 VALUE 里包含空格split 的时候只要按竖线切就不会出问题。输出里需要展示说明的只读项统一把 STATUS 置为空字符串表格里对应显示为 “-”保持协议一致。3.2 核心采集模块CPU、内存、磁盘、负载、服务状态下面这段 shell 代码是我采集脚本的核心片段涵盖了 CPU、内存、磁盘、负载、服务状态五个最常用的模块。#!/bin/bash # collect.sh - 服务器巡检采集脚本,输出 KEY|VALUE|STATUS # CPU 使用率:两次采样 /proc/stat CPU_USAGE$(top -bn1 | grep Cpu(s) | awk {print $2} | cut -d% -f1) CPU_STATUSOK if awk BEGIN{exit !($CPU_USAGE 80)}; then CPU_STATUSWARN fi echo CPU_USAGE|${CPU_USAGE}%|${CPU_STATUS} # 内存使用率:通过 available 和 total 计算 MEM_TOTAL$(free -m | awk /^Mem:/ {print $2}) MEM_AVAIL$(free -m | awk /^Mem:/ {print $7}) MEM_USAGE$(( (MEM_TOTAL - MEM_AVAIL) * 100 / MEM_TOTAL )) MEM_STATUSOK if [ $MEM_USAGE -gt 80 ]; then MEM_STATUSWARN elif [ $MEM_USAGE -gt 90 ]; then MEM_STATUSCRIT fi echo MEM_USAGE|${MEM_USAGE}%|${MEM_STATUS} # 磁盘使用率:排除虚拟文件系统,取真实分区最大值 DF_OUTPUT$(df -h | grep -Ev tmpfs|overlay|udev|shm|loop | awk {print $1, $5} | tail -n 2) MAX_DISK_USAGE0 DISK_DETAIL while read -r FS USAGE_PERCENT; do USAGE_NUM$(echo $USAGE_PERCENT | tr -d %) DISK_DETAIL${DISK_DETAIL} ${FS}:${USAGE_PERCENT} if [ $USAGE_NUM -gt $MAX_DISK_USAGE ]; then MAX_DISK_USAGE$USAGE_NUM fi done $DF_OUTPUT DISK_STATUSOK if [ $MAX_DISK_USAGE -gt 80 ]; then DISK_STATUSWARN elif [ $MAX_DISK_USAGE -gt 90 ]; then DISK_STATUSCRIT fi echo DISK_USAGE|${MAX_DISK_USAGE}%|${DISK_STATUS} echo DISK_DETAIL|${DISK_DETAIL}| # 负载:load average 与 CPU 核数对比 CPU_CORES$(nproc) LOAD_1$(uptime | awk -Fload average: {print $2} | cut -d, -f1 | tr -d ) LOAD_STATUSOK if awk BEGIN{exit !($LOAD_1 $CPU_CORES * 0.7)}; then LOAD_STATUSWARN fi if awk BEGIN{exit !($LOAD_1 $CPU_CORES)}; then LOAD_STATUSCRIT fi echo LOAD|${LOAD_1} (${CPU_CORES} cores)|${LOAD_STATUS} # 服务状态:systemctl 检测 for SERVICE in nginx mysql redis; do ACTIVE$(systemctl is-active $SERVICE 2/dev/null) if [ $ACTIVE active ]; then STATUSOK else STATUSCRIT fi echo SERVICE_${SERVICE}|${ACTIVE}|${STATUS} done这段代码有很多细节值得展开说说。CPU 使用率这里top -bn1 第一次输出的数据在系统刚启动或 load 极低时可能不准需要采样两次。上面的命令只做单次采样是我刻意简化了便于阅读。实际投入生产时我会先取一次 top 结果丢弃再取第二次做计算这样 CPU 使用率才稳定。内存使用率用的是 available 而不是 used。从运维角度available 更能真实反映“还有多少能用”因为它已经把 buff/cache 中可以回收的部分计算进去了。如果直接用 used 计算经常出现内存显示用了 90% 但系统一点也不卡的现象会误导告警判断。磁盘统计的 grep 排除用了 -Ev把 tmpfs、overlay、udev、shm、loop 全部过滤掉。不加这层过滤的后果我上面说过表格里会混入大量非法检查项。再强调一遍这些虚拟文件系统也不是完全不占内存在内存告警时把内存占用归属到缓存上才是合理的磁盘巡检只看真实盘位。负载阈值用了两层 awk 判断一层是 0.7 倍的核数告警一层是核数告警。这个阈值可以根据机器角色调整比如数据库机器可以调严到 0.5 就告警。nproc 获取的核数是逻辑核数也就是超线程也算一核符合 load average 的计算口径。3.3 远端批量采集免密登录与循环调度巡检不可能只在一台机器上跑集群场景下需要批量采集。我这边处理方式是运维机上配置好到所有目标服务器的 SSH 免密登录然后用一个 for 循环把采集脚本分发到各台机器上执行。#!/bin/bash # remote_collect_all.sh - 批量远程采集 HOSTS192.168.10.11 192.168.10.12 192.168.10.13 COLLECT_SCRIPT./collect.sh for HOST in $HOSTS; do echo ${HOST} ssh -o ConnectTimeout5 -o StrictHostKeyCheckingno $HOST bash -s $COLLECT_SCRIPT donessh 的 -o StrictHostKeyCheckingno 是为了批处理时避免首次连接询问 yes/no 而阻塞内网环境可以接受这个降级。生产公网环境建议提前把目标机的 HostKey 加入 known_hosts不要裸奔跳过校验。ConnectTimeout5 非常关键。不加这个参数某台机器宕机或网络不通时SSH 连接会一直卡在原地整个巡检流程被拖死。加了之后单台机器 5 秒超时失败直接跳过巡检流程继续往下走。这种方式没有用并行是串行执行的。如果服务器数量超过 50 台串行会导致总耗时明显增加我建议改用自身带的循环调度或者直接并行执行。后续版本需要我可以用 xargs -P 参数做并行优化但先跑通脚本逻辑更重要。4. Python 脚本怎么写采集输出到表格展示数据库采集完成后得到的是一堆键值对文本Python 脚本负责把这些文本按机器分组解析成结构化数据再做格式化和高亮。4.1 解析逻辑从文本到结构化数据Python 解析这块非常直接难点只在于设计一个合理的数据结构。我建议用字典嵌套列表的方式外层字典的 key 是主机 IPvalue 是一个列表列表里每个元素是 (指标名, 数值, 状态) 的元组。这样按机器遍历和按指标查找都很方便。#!/usr/bin/env python3 # report.py - 解析采集结果并输出表格 import sys import re from collections import defaultdict def parse_input(raw_data): hosts defaultdict(list) current_host None for line in raw_data.strip().splitlines(): line line.strip() if not line: continue if line.startswith(): current_host line.strip( ) continue if current_host is None: continue match re.match(r^(.?)\|(.?)\|(.*)$, line) if match: key, value, status match.groups() hosts[current_host].append((key, value, status)) return hosts解析时我用了一个正则可能有人会觉得可以写成更简单的 split(|, 2)。这里特意用正则的原因是想兼容 VALUE 字段里潜在包含竖线的情况虽然目前采集项里还没有但留着扩展位成本不高。实际数据验证过正则性能开销对几十台机器的巡检数据量完全没有压力。4.2 表格组件对齐计算与状态高亮表格输出用最基础的字符串格式化实现不引入第三方库保持零依赖的初衷。控制台表格需要对每一列计算最大宽度才能做到对齐。代码实现如下def format_table(hosts): headers [HOST, CPU%, MEM%, DISK%, LOAD, NGINX, MYSQL, REDIS] rows [] for host, items in hosts.items(): values {CPU: -, MEM: -, DISK: -, LOAD: -, SERVICE_nginx: -, SERVICE_mysql: -, SERVICE_redis: -} for key, val, status in items: if key CPU_USAGE: values[CPU] val elif key MEM_USAGE: values[MEM] val elif key DISK_USAGE: values[DISK] val elif key LOAD: values[LOAD] val elif key.startswith(SERVICE_): values[key] val rows.append([host, values[CPU], values[MEM], values[DISK], values[LOAD], values[SERVICE_nginx], values[SERVICE_mysql], values[SERVICE_redis]]) return headers, rows def print_aligned_table(headers, rows, colorTrue): width max([len(h) for h in headers] [len(r[col]) for r in rows for col in range(len(headers))]) 2 for col, header in enumerate(headers): print(header.ljust(width), end) print() print(- * width * len(headers)) for row in rows: for col, val in enumerate(row): print(val.ljust(width), end) print()这里每列的宽度都是以所有行内容的最大长度为基准。实际跑起来有个体验问题如果主机名或 IP 很长整张表格会被撑得很宽。我后来加了一个折中方案设置最大宽度 30 个字符超过多的截断显示。更长的信息可以在下一行“详细信息”里看。控制台高亮不想调第三方库用 ANSI 转义序列很简单。状态是 CRIT 的单元格标红WARN 标黄OK 不处理。ANSI 代码网上到处都有但一个细节不能省转义序列只对终端有效如果输出重定向到文件这些字符会变成文件里的乱码。所以 Python 脚本加了一个 --no-color 参数非交互场景自动关闭颜色。4.3 联动 shell 采集一条命令输出完整巡检表格到这里把 shell 采集和 Python 展示串联起来最终调用是这样for HOST in $HOSTS; do ssh -o ConnectTimeout5 $HOST bash -s collect.sh done | python3 report.py这样直接通过管道把采集结果喂给 Python。实际使用中我还增加了一个中间层把采集结果落盘保存方便留痕。巡检完了除了终端显示自动归档一份原始数据到当天的目录里这就是“可输出表格”的完整落地。4.4 表格最终效果跑一遍巡检后的控制台效果大致如下示意终端带颜色HOST CPU% MEM% DISK% LOAD NGINX MYSQL REDIS 192.168.10.11 12% 45% 67% 1.2 (4 cores) active active active 192.168.10.12 89% 92% 88% 6.8 (4 cores) failed active active 192.168.10.13 5% 33% 25% 0.4 (8 cores) active active inactive第二台机器看起来有明显问题CPU 89%、内存 92%、磁盘 88%mysql 状态是 failed负载 6.8 已经超了 4 核的负载警戒线。巡检表格的价值就在这里不用逐条看状态一眼就能定位到问题机器。5. 踩坑实录常见问题与排查技巧脚本写出来不难难的是让它长期稳定运行。下面这些问题都是我在实际使用中一条一条踩出来的整理成一个速查表能帮你在引入这套方案时少走很多弯路。5.1 中文环境导致的乱码对齐问题服务器系统语言不统一有的机器是 en_US有的机器是 zh_CN。中文字符在表格里占的显示宽度与 ASCII 字符不一致Python 的 ljust 是按字符数计算的中文会被顶破对齐。如果输出乱码现象是表格错位、列宽时大时小。我的经验是消息里的指标名全部用英文缩写比如 CPU 不写“中央处理器”磁盘不写“磁盘使用率”。日志消息里要展示的附加信息只在需要人工确认的字段放中文而且只在执行人手动确认时看不进入表格解析链路。这是一个根治方案从采集端入手让所有表格的数据都是 ASCII 字符彻底避开对齐问题。5.2 SSH 免密登录与权限问题的隐蔽陷阱SSH 权限不对是最隐蔽的问题。正常配置了公钥手摸 SSH 连接成功但放在 for 循环里运行可能某些参数导致其他机器登录失败。常见原因authorized_keys 文件权限是 644而不是建议的 600~/.ssh 目录权限是 755而需要的是 700还有把公钥放在了家目录之外的地方。排查技巧是先用 ssh -v 逐台跑一遍看日志停在哪一步。大部分问题都集中在权限过宽导致被 SSH 拒绝。我整体建议这样自查~/.ssh 目录权限必须为 700authorized_keys 文件权限必须为 600目标机家目录本身不能是组可写状态否则 SSH 会直接拒绝另外用 root 免密还是用普通用户加 sudo 跑巡检要考虑清楚。用 root 脚本写法最方便但安全隐患大。我的实践是巡检只读场景下可以用普通用户 脚本内需要的 sudo 命令单独授权但要注意授的命令白名单别太宽。5.3 crontab 定时任务环境变量缺失把巡检脚本挂到 crontab 里跑出现最多的问题就是找不到命令。crontab 的最小环境变量和交互式 shell 不同PATH 不是全路径如果在脚本里直接写 top、free、systemctl 这些命令会爆出 command not found。解决方式一是脚本开头显式声明环境变量export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin方式二是脚本内所有命令都写绝对路径。我的建议是二选一不要混合。全部命令绝对路径最靠谱但脚本维护时要多敲几个字符整体思路是把巡检脚本当作系统守护进程一样对待环境变量自包含。5.4 磁盘信息解析中的重复与排序不同服务器分区情况不同有的服务器有几个磁盘分区df 输出行数差异很大。如果脚本只取了第一行磁盘分区就漏掉了其他分区。数据采集的 DISK_DETAIL 字段我在自定义协议里保留了所有分区详细信息表格中只展示总览“最大使用率”如果需要看明细单独做查看项。处理磁盘输出的另一个细节是按使用率数字排序。如果班里有多台服务器每台分区数不同采集顺序不一致逐台看明细很痛苦。我在一个版本的脚本里做了排序处理按使用率从高到低排序输出方便快速找出快满的分区。5.5 远程脚本执行中的转义与引号问题ssh 远程执行 bash -s 把本地脚本内容喂给远端 bash这个过程有个隐蔽坑如果脚本里有变量或反引号在某些执行方式下会被本地 shell 先处理掉。我见过的错误是把脚本文件内容用 ssh $HOST bash -s 加上双引号传过去结果脚本里的 $ 和反引号全部被本地解析了一遍远端拿到的脚本已经变形。我推荐的做法是用单引号包裹远端执行命令或者用 stdin 重定向方式ssh -o ConnectTimeout5 $HOST bash -s $COLLECT_SCRIPT这种方式把本地脚本原样通过标准输入传给远端不经过本地 shell 解析能避免绝大多数转义问题。你如果学我用的是文档里的方案就直接抄这一段别用双引号。5.6 高负载情况下 top 命令的无响应问题服务器负载极高时手工执行 sleep 1 再去采样 top往往会出现进程卡死因为 top 需要等待采样时间窗口结束。这个问题在系统负载超过 50 的时候尤其严重排查现场最关键的时候脚本反而卡死了。推荐改进方案是全部用读取 /proc/stat 的方式来计算 CPU 使用率不依赖 top。前面简化版脚本用的是 top 单次取值生产环境版本我是用 /proc/stat 两次采样实现的。这段代码采集时延极低不受系统负载影响非常稳。建议读者在实际使用时直接把 top 那行替换成这段。6. 巡检的频率与告警联动让脚本不止于查还能防脚本再快如果靠人每天手动跑难以为继。巡检自动接入定时任务之后要做的事情是让这个方案从“被动查询工具”进化成“主动发现工具”。6.1 设定合理的巡检频率不是越快越好巡检频率取决于业务的重要程度和服务器规模。普通业务一天一次或一周两三次即可核心数据库和网关机器建议一小时一次如果业务对稳定性极其敏感甚至要考虑分钟级采集这就需要引入完整的监控系统而不是单靠脚本。我目前的实践是基础巡检每天早高峰前跑一次把结果归档每周日晚跑一次完整周报包含所有机器的状态明细。这个频率既不打扰系统也足以让人及时发现问题。用 crontab 实现非常直接0 8 * * * /opt/scripts/run_inspection.sh /var/log/inspection.log 21跑完巡检后可以再写一个 if 判断如果存在任一 CRIT 状态立刻用系统自带工具发告警到通信群。这样凌晨出问题也能第一时间通知到人无需等到早高峰才发现。6.2 告警策略与白名单防止狼来了告警策略要控制噪音不然一个月跑下来全是无效告警看到新告警也会麻木。我踩过的坑是把阈值调到 80% 后某台磁盘使用率长期在 80% 到 85% 之间徘徊每天告警团队直接无视。后来加了三层机制阈值分级80% 设 WARN90% 设 CRIT只在 CRIT 时进行即时通知同一个告警项一天之内最多推一条避免重复轰炸针对已知的“历史遗留问题服务器”单独维护白名单不在白名单内才触发告警告警联动的代码逻辑不复杂核心是在 Python 结果解析后加一个状态汇总判断如果发现 CRIT 项就发送一个格式化消息到指定通道。这里注意告警消息里只放必要的字段别像表格一样把所有数据全推一遍关键机器和关键指标点到即止。6.3 归档策略巡检数据要有历史留痕巡检数据只展示不归档等于没有历史。出了问题排查时需要知道这台机器在故障前三天、前一周是什么状态。我的归档方式是每天跑完巡检后把所有机器对应的键值对结果按日期组织成文件存储路径放在专用的巡检目录下命名规则带日期。这样 90 天的数据可以随时翻出来查询。每个月另外跑一次汇总脚本把当月每天的磁盘使用率、内存使用率等关键指标抽出来形成一条趋势曲线。虽然这个阶段的脚本没有图表能力但把数据抽出来之后再粘到表格工具里做趋势图就能直观看到哪些机器的磁盘持续增长、哪些机器内存逐步吃紧。趋势数据对扩容需求很有说服力我上次申请加机器资源就是靠三个月磁盘趋势记录推动的。7. 扩展思路从巡检脚本到轻量监控体系的衔接这套双脚本方案的定位很清晰——它是日常巡检和人工盘点时的效率工具不是要替代专业监控系统。业务规模变大后工具自然会向更完善的方向演进。但即使将来上了监控系统这套巡检仍然有存在价值。7.1 与监控系统并存的定位差异专业监控系统做的是持续的指标采集、告警和可视化覆盖秒级、分钟级的数据。巡检脚本则是定时跑一次的扫描更关注“当前这批机器的整体状态是否正常”。两者的定位差异在于监控系统回答“现在发生了什么”巡检脚本回答“这一批机器现在有没有异常”。监控系统出现时间线断裂的空窗期巡检脚本的归档数据就是最有力的补充两者并存并不冲突。7.2 Python 输出模块的扩展方向如果后续想把巡检结果输出得更完善Python 侧已经是现成的接口。加一个函数把当前表格格式转换成 HTML 表格格式就能配合邮件发送周报。Markdown 已经有了HTML 也是十几行的事。甚至可以画简单的条形图不需要外部库用字符拼一个简单的可视化效果。我在实践中的做法是保留今天的双脚本结构把 Python 侧的输出函数做成插件式业绩对比用哪种格式就在调用时传哪种格式。这个设计让“可输出表格”变成“可输出任意展示”不需要重写底层采集脚本。7.3 Bash 环境多样性兼容发行版之间命令细节差异比想象中更多。比如 systemctl 在 CentOS 7 以上都有但在老旧版本里可能没有nproc 在部分精简系统里可能不存在。脚本上线前先准备一个小工具函数做命令存在性检查缺失的命令单独提示不要在生产机器上运行时才报错。我维护脚本时有一个原则兼容性优先不追求极简。所有能用保守写法的地方都保守些先用 command -v 检测命令是否存在再执行。这套巡检脚本在 Ubuntu 和 CentOS 都跑过小半年除了发行版间密文有细微差异外没有出现明显的兼容性问题。这些经验都是在我自己踩了几次坑之后总结出来的。巡检工作看着简单真正要做得扎实很多细节都得较真。如果你也想搭一套属于自己团队的巡检方案希望这篇内容能帮你省下那些不必要的试错时间。个人最核心的建议就两条一是务必把采集和展示分成两个独立脚本后续的维护成本会低很多二是务必给输出定义一个严谨的协议格式不给解析留模糊空间。把这两件事做扎实了剩下的就是按需求往采集脚本里加指标的问题了。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →