当前位置: 首页 > news >正文

进程监控:通过 SSH 远程监测嵌入式设备进程重启

背景

dhcp频繁请求ip导致cpr反复重启。

为了量化这一问题,并精准捕捉重启发生的时间点(以便与网络日志对齐),我们需要一个外部监控工具。该工具需要满足以下需求:

  1. 非侵入式:无需修改设备固件,通过 SSH 远程监控。
  2. 多目标支持:只需配置 IP 列表,即可同时监控多台设备。
  3. 自动告警:当检测到 PID(进程ID)变化时,判定为重启并记录日志,特别是对 cpr 进程进行高亮标记。

解决方案

我们使用 Python 的 paramiko 库通过 SSH 连接设备,周期性执行 ps -ef 命令,通过比对前后两次采样中同一进程名的 PID 变化,来判断进程是否发生了重启。

1. 配置文件 (config.json)

将所有易变参数(如 IP、密码、端口)抽离到配置文件中,方便随时调整监控目标。

{"ssh": {"user": "root","password": "Jsst_168","port": 22},"router_ip": "192.168.7.150","targets": ["192.168.8.80","192.168.8.90"]
}

2. 监控脚本 (monitor.py)

import paramiko
import time
import logging
import json
import threading
import os# ================= 可配置变量 =================
CONFIG_FILE = 'config.json'
INTERVAL = 5  # 监控轮询间隔(秒)# 忽略名单:这些进程频繁启停是正常的,过滤掉以防日志刷屏
IGNORE_LIST = ['ping', 'jsm1689_ping_baidu.sh', 'top', 'sleep']# ================= 日志配置 =================
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(message)s',handlers=[logging.FileHandler("monitor.log", encoding='utf-8'), logging.StreamHandler() ]
)
logger = logging.getLogger(__name__)class DeviceMonitor(threading.Thread):def __init__(self, ip, ssh_config):super().__init__()self.ip = ipself.ssh_conf = ssh_configself.client = Noneself.last_proc_map = {} # 存储上一次的进程状态 { '进程名': {pid1, pid2} }self.running = Truedef connect(self):"""建立 SSH 连接,设置超时以便快速感知断线"""try:if self.client:try: self.client.close()except: passself.client = paramiko.SSHClient()self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())self.client.connect(self.ip, port=self.ssh_conf['port'], username=self.ssh_conf['user'], password=self.ssh_conf['password'], timeout=5,banner_timeout=5)return Trueexcept Exception as e:logger.error(f"[{self.ip}] 连接失败: {e}")return Falsedef clean_name(self, parts):"""清洗进程名逻辑:1. 处理 shell 脚本 (如 '/bin/sh app.sh' -> 'app.sh')2. 去除路径 (如 '/usr/bin/app' -> 'app')"""if not parts: return "unknown"cmd = parts[0]if cmd.endswith('sh') and len(parts) > 1 and not parts[1].startswith('-'):cmd = parts[1]if '/' in cmd:cmd = cmd.split('/')[-1]return cmddef get_processes(self):"""通过 SSH 执行 ps -ef 并解析数据"""if not self.client: return Nonetry:_, stdout, _ = self.client.exec_command('ps -ef', timeout=5)output = stdout.read().decode('utf-8')curr_map = {}lines = output.strip().split('\n')for line in lines[1:]: # 跳过标题行parts = line.split()# 简单校验:必须包含PID等基础列if len(parts) < 8 or not parts[1].isdigit(): continuepid = int(parts[1])cmd_parts = parts[7:]full_cmd = " ".join(cmd_parts)# 基础过滤:忽略内核进程([])、sleep命令和ps本身if full_cmd.startswith('[') or cmd_parts[0] == 'sleep' or 'ps -ef' in full_cmd:continuename = self.clean_name(cmd_parts)# 过滤白名单中的进程if name in IGNORE_LIST: continueif name not in curr_map: curr_map[name] = set()curr_map[name].add(pid)return curr_mapexcept Exception:return None # 发生任何异常都视为连接断开def compare(self, new_map):"""核心逻辑:比对前后两次 PID 集合"""prefix = f"[{self.ip}]"if not self.last_proc_map:self.last_proc_map = new_maplogger.info(f"{prefix} 初始化成功,监控进程数: {len(new_map)}")returnall_cmds = set(self.last_proc_map.keys()) | set(new_map.keys())for cmd in all_cmds:old_p = self.last_proc_map.get(cmd, set())new_p = new_map.get(cmd, set())# 业务相关:高亮显示 'cpr' 进程的报警alert_tag = " >>> CPR警报 <<<" if "cpr" in cmd.lower() else ""# 判定1:完全重启 (旧PID集合与新PID集合完全无交集)if old_p and new_p and old_p.isdisjoint(new_p):logger.warning(f"{prefix}{alert_tag} [!] RESTART: {cmd} (PID: {old_p} -> {new_p})")# 判定2:PID 数量或内容发生变化 (多进程服务变动)elif old_p != new_p:added, removed = new_p - old_p, old_p - new_pif added and removed:logger.warning(f"{prefix}{alert_tag} [*] CHANGE: {cmd} PID变化 (New:{added}, Old:{removed})")elif added:logger.info(f"{prefix} [+] NEW: {cmd} (PID: {added})")elif removed:logger.info(f"{prefix} [-] EXIT: {cmd} (PID: {removed})")self.last_proc_map = new_mapdef run(self):logger.info(f"[{self.ip}] 启动监控线程...")while self.running:# 1. 连接保活机制if not self.client or self.client.get_transport() is None or not self.client.get_transport().is_active():if not self.connect():time.sleep(10) # 连不上就休息10秒再试continueelse:self.last_proc_map = {} # 重连后重置状态,防止误报# 2. 获取数据procs = self.get_processes()# 3. 处理断线或比对if procs is None:logger.warning(f"[{self.ip}] 连接断开,尝试重连...")self.client = Nonecontinueself.compare(procs)time.sleep(INTERVAL)def load_config():if not os.path.exists(CONFIG_FILE):logger.error(f"找不到配置文件 {CONFIG_FILE}")return Nonetry:with open(CONFIG_FILE, 'r', encoding='utf-8') as f:return json.load(f)except Exception as e:logger.error(f"配置文件格式错误: {e}")return Noneif __name__ == "__main__":config = load_config()if config:router_ip = config.get('router_ip', '')targets = config.get('targets', [])ssh_conf = config.get('ssh', {})threads = []logger.info(">>> 进程监控系统启动 <<<")logger.info(f"目标设备: {targets}")# 为每个目标 IP 启动一个独立线程for ip in targets:if ip == router_ip:logger.info(f"跳过路由器 IP: {ip}")continuet = DeviceMonitor(ip, ssh_conf)t.daemon = True # 主程序退出时子线程跟随退出t.start()threads.append(t)try:while True:time.sleep(1) # 阻塞主线程except KeyboardInterrupt:logger.info("停止监控")

运行效果

运行脚本后,系统将自动监控配置文件中的设备。如果发生 cpr 进程重启,日志中会出现显著的高亮警报:

2025-12-06 21:15:30 - [192.168.8.80] >>> CPR警报 <<< [!] RESTART: cpr (PID: {23727} -> {24005})
http://www.jsqmd.com/news/64420/

相关文章:

  • 街头徒手健身3硬核核心训练
  • 我们的休闲娱乐区,会变成什么样子(哽咽)
  • 【ZeroRange WebRTC】对称加密 vs 非对称加密(从原理到实践) - 详解
  • Cloudflare成功抵御AISURU僵尸网络发起的破纪录29.7 Tbps DDoS攻击
  • 2025最新贵州伴手礼厂家/采购渠道/供应商/平台/卖场/超市TOP5推荐!地道风物+文化赋能权威榜单发布,甄选贵礼传递黔地心意
  • 从 Spring Boot 2.x 到 3.5.x + JDK21:一次完整的生产环境迁移实战 - Rainbow
  • 2025.12.6日21:24-incapacity无能力
  • 001.makdown快速入门
  • Focal Loss
  • 2025最新贵州/贵阳手信/伴手礼厂家 TOP5 评测!地道风物+文化赋能权威榜单发布,甄选贵礼传递山水心意
  • Oracel VirtualBox安装Windows11时无法找到ISO文件或不满足系统要求
  • 百度统计、Google Analytics平替开源网站分析工具:Umami - 教程
  • 19
  • 18
  • JavaScript 数组 对象 Map Set (映射,集合) 没有字典
  • 舆情处置高效的技术深度解析:Infoseek 字节探索的 AI 闭环架构与实现逻辑
  • FPS的实时处理能力
  • 构建个人知识库新选择:深度解析访答本地私有知识库
  • 数字马力一面-后端开发郑州岗(校招)
  • AIShareTxt入门:快速准确高效的为金融决策智能体提供股票实用的技术指标上下文
  • 麒麟ARM架构安装redis - show
  • I know only one topic but I wear glasses in 20s
  • 详细介绍:中颖AFE芯片:SH367303、SH367306 和 SH367309
  • 主动学习如何优化计算机视觉工作流程
  • IMX6ULL主频和时钟配置
  • 英语_阅读_Heroes come in all ages_待读
  • 云原生基石的试金石:基于 openEuler 部署 Docker 与 Nginx 的全景实录 - 指南
  • 收敛至约0.28
  • qemu如何和宿主机共享文件 - show
  • 2025贵州贵阳荣和酒坊采购渠道推荐!百年传承酱香白酒购买平台TOP5榜单发布,品味历史沉淀的醇香佳酿