Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录
切换导航
U
ubains-module-test
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
1
议题
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
郑晓兵
ubains-module-test
Commits
9d887980
提交
9d887980
authored
7月 21, 2026
作者:
陈泽健
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
docs: 更新 HANDOFF 交接文档
Co-Authored-By:
Claude
<
noreply@anthropic.com
>
上级
9d90d646
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
141 行增加
和
128 行删除
+141
-128
HANDOFF.md
HANDOFF.md
+141
-128
没有找到文件。
HANDOFF.md
浏览文件 @
9d887980
# HANDOFF —
服务监测模块深度扩展与 SSH 连接问题
修复
# HANDOFF —
定时任务弹窗优化 + 通知配置 + 定时任务不执行
修复
> 最后更新:2026-07-2
0 18:26
| 分支:troubleshoot-ai-assistant | 负责人:czj
> 最后更新:2026-07-2
1 15:07
| 分支:troubleshoot-ai-assistant | 负责人:czj
---
## 1. 我们在做什么
本
项目是「运维辅助平台」(原"问题排查 AI 助手"),Flask Web 服务跑在
`192.168.5.60:8088`
。
本
次会话承接上一轮的"左侧菜单改造 + 定时自动巡检"功能,继续推进服务监测模块的完善,共完成三项任务:
本次会话有两项主要任务:
**任务一:定时任务弹窗交互优化**
。原弹窗使用 Cron 表达式(如
`0 8 * * *`
)配置调度周期,非技术人员无法理解。改为"每天/工作日/每周"三种重复周期 + 时间选择器 + 星期多选 + 起止日期的用户友好界面。来源 PRD:
`Docs/需求文档/服务监测/PRD_需求文档_定时任务弹窗优化.md`
### 任务一:SSH 连接测试失败问题修复
**任务二:通知配置功能**
。定时巡检完成后用户无法及时获知结果,新增"通知配置"菜单页,支持邮件(SMTP)、钉钉机器人、企业微信机器人三种通知渠道,可选择触发条件和测试发送。来源 PRD:
`Docs/需求文档/服务监测/PRD_需求文档_通知配置.md`
用户在服务监测平台新建远程目标服务器(192.168.5.44),点击"测试连接"提示"SSH 连接失败"。经排查发现服务器 5.60 上
**未安装 paramiko**
,且错误信息过于笼统,无法区分网络/认证/依赖问题。
**任务三:定时任务不执行问题修复**
。用户反馈设置了定时任务但到了时间不执行、不输出报告。排查发现三个根因:①Flask debug 模式的 reloader 机制导致 APScheduler 在错误进程初始化;②start_date/end_date 传字符串而非 datetime 对象给 APScheduler;③croniter 依赖未在 requirements.txt 声明。来源:
`Docs/需求文档/服务监测/PRD_问题处理_定时任务与报告优化.md`
### 任务二:服务监测模块深度扩展
---
在核心子集(7个模块)基础上,扩展更多检测能力:
-
补充常用系统模块:OOM检测、进程检测、网络检测、计划任务、端口检测
-
补充服务深度检测:Docker深度、MySQL深度、Redis深度
-
新增业务容器监测:UStorage、UTracker
## 2. 已经完成了什么
需求文档位置:
-
`Docs/需求文档/服务监测/PRD_需求文档_服务监测模块.md`
-
`Docs/需求文档/服务监测/PRD_计划执行_服务监测模块.md`
### ✅ 定时任务弹窗交互优化
---
-
删除 Cron 表达式输入框和预设按钮,改为
**重复周期单选组**
(每天/工作日/每周)
-
新增
**时:分下拉选择器**
(0-23 时,每5分钟)
-
新增
**星期多选按钮组**
(仅每周模式显示,至少选1个)
-
新增
**生效日期/失效日期**
选择器
-
列表"Cron"列改为
**"调度周期"**
,显示自然语言描述(如"工作日 09:30"、"每周一、周五 10:00")
-
后端
`schedule_service.py`
新增
`_build_cron()`
/
`_describe_schedule()`
函数,自动转换和描述
-
数据模型新增字段:
`repeat_mode`
/
`hour`
/
`minute`
/
`weekdays`
/
`start_date`
/
`end_date`
-
部署到 5.60 验证通过:创建"工作日巡检"显示"工作日 09:30",编辑回填正确
##
2. 已经完成了什么
##
# ✅ 通知配置功能
### 任务一:SSH 连接问题修复 ✅
-
左侧菜单新增 🔔 通知配置(在"定时任务"和"目标管理"之间,仅管理员可见)
-
新增
`notification_service.py`
:支持邮件/钉钉/企业微信三种渠道的配置 CRUD、测试发送、巡检完成后通知
-
新增
`notification.html`
:三个渠道配置卡片(启用开关 + 表单 + 测试按钮)+ 触发条件配置
-
`runner_service.py`
的
`run_inspection_sync()`
完成后调用通知服务
-
敏感字段(SMTP 密码、钉钉密钥)用 Fernet 加密存储(复用
`crypto.py`
的
`encrypt_password`
)
-
部署到 5.60 验证通过:页面功能正常,邮件配置展开后表单完整
1.
**部署 paramiko**
✅
-
在服务器 5.60 执行
`pip3 install --break-system-packages paramiko`
安装 5.0.0
-
重启服务验证 SSH 连接成功
### ✅ 定时任务不执行修复
2.
**增强错误分类**
✅
-
`executor.py`
新增
`DependencyError`
、
`SSHConnectionError`
异常类
-
新增
`classify_ssh_error()`
函数,按异常类型返回 6 种错误码
-
`BaseExecutor.test_connection()`
改为抛出分类后的异常
**根因 1:Flask debug reloader**
(核心问题)
-
修复:
`server.py`
的
`FLASK_DEBUG`
默认值从
`'1'`
改为
`'0'`
-
修复:
`schedule_service.init_scheduler()`
增加
`WERKZEUG_RUN_MAIN`
环境变量检查,仅在 reloader 子进程初始化
-
修复:
`deploy/upload_to_server.py`
启动命令显式设置
`FLASK_DEBUG=0`
3.
**API 返回详细错误**
✅
-
`target_service.test_connection()`
返回
`detail`
+
`error_code`
字段
-
`routes.py`
直接返回完整结果
-
前端
`targets.html`
显示详细错误,鼠标悬停查看详情
**根因 2:start_date/end_date 类型错误**
-
修复:
`_add_job()`
中将字符串转为
`datetime`
对象并附加
`timezone.utc`
4.
**上传脚本增加依赖检查**
✅
-
`deploy/upload_to_server.py`
新增
`_check_and_install_deps()`
函数
-
部署时自动检查并安装 paramiko/cryptography
**根因 3:croniter 依赖缺失**
-
修复:
`requirements.txt`
增加
`apscheduler==3.11.0`
+
`croniter==6.2.4`
-
修复:
`skill/code/requirements.txt`
增加
`apscheduler>=3.10.0`
+
`croniter>=2.0.0`
-
修复:
`deploy/upload_to_server.py`
的
`_REQUIRED_PACKAGES`
增加
`'croniter'`
5.
**输出 PRD 文档**
✅
-
`Docs/需求文档/服务监测/PRD_问题处理_SSH连接测试失败.md`
-
`Docs/需求文档/服务监测/PRD_计划执行_SSH连接测试失败修复.md`
**验证**
:
`/api/health`
返回
`scheduler: {'running': true, 'job_count': 3}`
,3 个定时任务全部注册
**验证结果**
:
-
认证失败返回
`"认证失败:用户名或密码错误"`
+
`AUTH_FAILED`
-
不可达 IP 返回
`"连接被拒绝:目标端口未开放或 SSH 服务未运行"`
+
`CONNECTION_REFUSED`
-
连接成功返回
`"连接成功"`
### ✅ 编辑保存提示
### 任务二:模块扩展 ✅
-
`schedule.html`
的
`saveSchedule()`
成功后增加
`alert('保存成功')`
/
`alert('创建成功')`
1.
**迁移 system 类模块**
✅
-
从
`临时目录/服务器监测/lib/system/`
迁移 5 个模块到
`assets/system/`
-
改造
`LIB_DIR`
从写死改为可注入模式
-
模块:05_oom_check、06_process_check、07_network_check、11_scheduled_tasks、12_port_check
### ✅ 执行状态显示
2.
**迁移 service 深度模块**
✅
-
从
`临时目录/服务器监测/lib/service/`
迁移 3 个模块到
`assets/service/
`
-
模块:21_docker_deep、23_mysql_depth、25_redis_depth
-
`schedule_service.py`
新增
`_update_current_status()`
函数
-
`_execute_scheduled_job()`
开始时标记
`running`
,成功标记
`success`
,失败标记
`failed
`
-
`schedules.json`
增加
`current_status`
字段
3.
**新增业务容器监测**
✅
-
新建
`37_ustorage_check.sh`
:容器状态、健康检查、存储容量与IO
-
新建
`38_utracker_check.sh`
:容器状态、健康检查、处理能力
### ✅ 批量删除报告
4.
**更新代码配置**
✅
-
`check_modules.py`
:ALL_MODULES 从 7→17 个
-
`display_names.py`
:新增 ~150 个 KEY 的中文显示名
-
`config.sh.template`
:添加 ustorge/utracker 容器匹配模式
-
`reports.html`
增加 checkbox、全选、批量删除按钮
-
`routes.py`
新增
`DELETE /api/service-monitor/reports/batch`
接口
5.
**修复空值问题**
✅
-
`parser.py`
新增
`_INVALID_VALUES`
过滤 N/A、无法获取、未知等无效值
-
`01_system_basic.sh`
修复
`check_command`
函数不存在的问题
-
`02_cpu_check.sh`
修复
`SCHEDULER_RUNQUEUE`
取值逻辑
### ✅ health 接口增强
**验证结果**
:
-
快速巡检:5 模块,61 项
-
全量巡检:17 模块,193 项(全部有效值,无空值/N/A)
-
已部署到 5.60 并验证通过
-
`routes/troubleshoot.py`
的
`/api/health`
增加
`scheduler`
状态字段,暴露 APScheduler 运行状态
---
## 3. 当前卡在哪
**无卡点**
。所有
任务已完成,等待用户下一步指令
。
**无卡点**
。所有
功能已实现并部署到 5.60
。
工作区有未提交的改动(本次会话的修改),建议提交后再结束
。
但有一个
**待验证项**
:定时任务到时间后是否真正执行并生成报告。APScheduler 已正确初始化(health 接口确认),但尚未等一个完整周期验证报告输出。建议创建一个 2 分钟后触发的定时任务来快速验证
。
---
## 4. 下一步计划
按优先级排序:
1.
**验证定时任务实际执行**
(P0)
-
在页面上创建一个 2 分钟后触发的定时任务
-
等待执行后检查巡检报告是否生成
-
检查
`schedules.json`
中
`last_run_at`
和
`last_report_id`
是否更新
1.
**提交代码**
(P0)
-
当前有 11 个修改文件 + 10 个新增文件未提交
-
建议拆分为 3 个提交:
-
`fix: SSH 连接测试错误分类与依赖检查`
-
`feat: 服务监测模块扩展(新增 10 个检测模块)`
-
`fix: 过滤无效检测值,修复 bash 脚本检测逻辑`
2.
**提交代码**
(P0)
-
当前有 13 个修改文件 + 7 个新增文件未提交
-
建议拆分为 3-4 个提交:
-
`feat(service-monitor): 定时任务弹窗交互优化(友好调度配置替代 Cron 表达式)`
-
`feat(service-monitor): 通知配置功能(邮件/钉钉/企业微信)`
-
`fix(service-monitor): 定时任务不执行修复 + 依赖补充 + 报告批量删除`
-
所有
`Docs/需求文档/`
下的新增 PRD 文件也需要提交
2.
**添加更多检测模块**
(P1,可选
)
-
参考 PRD,还有 system 类(40综合诊断/43安全合规/44系统日志/45时间同步
)
-
以及 service 类(EMQX/Java/Python/Nginx/Nacos/FastDFS)
3.
**清理 5.60 上的测试定时任务**
(P1
)
-
删除之前创建的测试任务(如不需要
)
-
确保 schedules.json 数据干净
3.
**远程目标巡检测试**
(P2)
-
新建 192.168.5.44 远程目标,执行快速/全量巡检
-
验证 SSH 远程执行全链路
4.
**配置实际通知渠道**
(P2)
-
配置邮件/钉钉/企业微信的真实凭据
-
发送测试验证
5.
**systemd 服务文件补充 FLASK_DEBUG=0**
(P2)
-
当前服务文件缺少此环境变量,依赖 server.py 的默认值
-
建议手动在
`/etc/systemd/system/troubleshoot.service`
的
`[Service]`
段加
`Environment=FLASK_DEBUG=0`
---
## 5. 踩过的坑(绝对不要再踩)
### 坑 1:服务器端 paramiko 未安装
**坑**
:点击测试连接返回"SSH 连接失败",但实际原因是服务器上没装 paramiko,
`import paramiko`
失败被吞掉。
**原因**
:HANDOFF 文档写了"待安装依赖",但部署时跳过了。
`upload_to_server.py`
只上传代码不检查依赖。
### 坑 1:Flask debug 模式的 reloader 导致 APScheduler 失效(最严重)
**避免**
:
-
`upload_to_server.py`
已增加依赖检查步骤,部署时自动安装
-
错误信息现在会明确提示"paramiko 未安装"
**坑**
:
`server.py`
默认
`FLASK_DEBUG='1'`
,Flask debug 模式使用 Werkzeug reloader,fork 出子进程后,父进程中初始化的 APScheduler 被丢弃,子进程中
`_scheduler`
全局变量重置为 None。定时任务注册在即将被丢弃的父进程中,实际处理请求的子进程没有调度器。
### 坑 2:Windows 换行符导致 bash 脚本无法执行
**为什么会踩**
:开发环境默认开启 debug 方便热重载,但 reloader 的双进程机制与 APScheduler 的单进程初始化冲突。症状是定时任务"看起来注册成功但永远不执行"。
**坑**
:bash 脚本从 Windows 上传后含
`\r\n`
,Linux 执行报
`$'\r': command not found`
。
**避免方法**
:
-
生产环境
**必须**
设置
`FLASK_DEBUG=0`
-
`init_scheduler()`
要检查
`WERKZEUG_RUN_MAIN`
环境变量,仅在子进程中初始化
-
health 接口暴露 scheduler 状态,方便快速诊断
**原因**
:Git 默认在 Windows 上检出 CRLF,SFTP 上传时没转换。
### 坑 2:APScheduler 的 start_date/end_date 需要带时区的 datetime
**避免**
:
-
`upload_to_server.py`
已增加
`_sftp_put_unix_lines()`
自动转换
`.sh`
/
`.template`
文件
-
未来上传脚本文档要强调换行符问题
**坑**
:直接把
`"2026-07-20"`
字符串赋值给
`CronTrigger.start_date`
,报错
`'str' object has no attribute 'astimezone'`
。改为
`datetime`
对象后又报错
`can't compare offset-naive and offset-aware datetimes`
。
### 坑 3:templates/service_monitor 子目录未上传
**避免方法**
:用
`datetime.strptime(date_str, "%Y-%m-%d").replace(tzinfo=timezone.utc)`
转换为 UTC 时区的 datetime 对象。end_date 当天也要执行,需设为
`23:59:59`
。
**坑**
:部署后模板目录为空,页面 404。
### 坑 3:croniter 依赖未声明
**
原因**
:
`DIRS_TO_UPLOAD`
只上传一层文件,
`templates/service_monitor/`
子目录被忽略
。
**
坑**
:
`apscheduler`
在
`upload_to_server.py`
的
`_REQUIRED_PACKAGES`
中声明了,但
`croniter`
没有。
`croniter`
是
`schedule_service.py`
的间接依赖(
`_calc_next_run()`
和
`create_schedule()`
中使用),缺失导致
`next_run_at`
为 null
。
**避免**
:已修改上传脚本,子目录递归上传。
**避免方法**
:
**所有 Python 依赖必须在三个位置同步声明**
:
1.
`requirements.txt`
(容器化部署)
2.
`skill/code/requirements.txt`
(开发环境)
3.
`deploy/upload_to_server.py`
的
`_REQUIRED_PACKAGES`
(SSH 部署)
### 坑 4:
检测项值为空/N/A 判定为"正常"
### 坑 4:
notification_service 导入了不存在的函数名
**坑**
:
报告显示大量 N/A 值被判定为"正常",误导用户
。
**坑**
:
导入了
`encrypt_value`
/
`decrypt_value`
,但
`crypto.py`
中的实际函数名是
`encrypt_password`
/
`decrypt_password`
。
**
原因**
:Parser 不过滤无效值,所有 KEY:VALUE 都解析成检测项
。
**
避免方法**
:新增模块前检查依赖模块的实际函数签名,不要凭记忆写函数名
。
**避免**
:
`parser.py`
已增加
`_INVALID_VALUES`
过滤,N/A、无法获取、未知等不再输出。
### 坑 5:5.60 服务器 pip install 需要特殊参数
### 坑 5:bash 脚本调用不存在的函数
**坑**
:5.60 服务器是 Ubuntu + Python 3.14,
`pip install`
报
`externally-managed-environment`
错误,需要加
`--break-system-packages`
参数。
**坑**
:
`check_command ulimit`
函数不存在,导致
`ULIMIT_INFO`
输出"无法获取"。
**原因**
:参考脚本中有
`check_command`
函数,但
`common.sh`
没有迁移。
**避免**
:迁移脚本时检查函数依赖,用
`command -v`
替代自定义函数。
**避免方法**
:
`upload_to_server.py`
的依赖安装命令已加此参数,后续手动安装时也要加。
---
## 6. 关键文件与命令速查
### 本次
修改的核心
文件
### 本次
新增
文件
| 文件 | 用途 |
|------|------|
|
`service_monitor/utils/executor.py`
| SSH 连接错误分类 |
|
`service_monitor/utils/parser.py`
| 过滤无效检测值 |
|
`service_monitor/utils/check_modules.py`
| 模块清单(7→17) |
|
`service_monitor/utils/display_names.py`
| KEY 中文显示名 |
|
`service_monitor/assets/system/*.sh`
| 新增 5 个系统检测模块 |
|
`service_monitor/assets/service/*.sh`
| 新增 5 个服务检测模块 |
|
`deploy/upload_to_server.py`
| 依赖检查 + 换行符转换 |
|
`skill/code/web/service_monitor/services/notification_service.py`
| 通知服务(邮件/钉钉/企业微信) |
|
`skill/code/web/templates/service_monitor/notification.html`
| 通知配置页面 |
|
`Docs/需求文档/服务监测/PRD_需求文档_定时任务弹窗优化.md`
| 弹窗优化 PRD |
|
`Docs/需求文档/服务监测/PRD_计划执行_定时任务弹窗优化.md`
| 弹窗优化计划 |
|
`Docs/需求文档/服务监测/PRD_需求文档_通知配置.md`
| 通知配置 PRD |
|
`Docs/需求文档/服务监测/PRD_计划执行_通知配置.md`
| 通知配置计划 |
|
`Docs/需求文档/服务监测/PRD_问题处理_定时任务与报告优化.md`
| 问题处理文档 |
|
`Docs/需求文档/服务监测/PRD_计划执行_定时任务与报告优化.md`
| 问题修复计划 |
### 本次修改文件
| 文件 | 改动要点 |
|------|---------|
|
`skill/code/web/server.py`
| FLASK_DEBUG 默认值改为
`'0'`
|
|
`skill/code/web/service_monitor/services/schedule_service.py`
| 新增 _build_cron/_describe_schedule/_update_current_status;init_scheduler 增加 reloader 防护;_add_job 修复 start_date 类型 |
|
`skill/code/web/service_monitor/services/runner_service.py`
| run_inspection_sync 完成后调用通知服务 |
|
`skill/code/web/service_monitor/utils/paths.py`
| 增加 NOTIFICATIONS_FILE |
|
`skill/code/web/service_monitor/routes.py`
| 新增通知配置 6 个路由 + 批量删除 API |
|
`skill/code/web/routes/troubleshoot.py`
| health 接口增加 scheduler 状态 |
|
`skill/code/web/templates/service_monitor/base.html`
| 左侧菜单增加"通知配置" |
|
`skill/code/web/templates/service_monitor/schedule.html`
| 弹窗全面重写(友好调度)+ 保存提示 |
|
`skill/code/web/templates/service_monitor/reports.html`
| 增加 checkbox + 批量删除 |
|
`requirements.txt`
| 增加 apscheduler==3.11.0 + croniter==6.2.4 |
|
`skill/code/requirements.txt`
| 增加 apscheduler>=3.10.0 + croniter>=2.0.0 |
|
`deploy/upload_to_server.py`
| _REQUIRED_PACKAGES 增加 croniter;启动命令加 FLASK_DEBUG=0 |
### 常用命令
```
bash
#
单元测试(51 用例,应全绿
)
cd
skill/code
&&
python
-m
pytest web/service_monitor/tests/
-v
#
本地启动(开发环境,debug 模式
)
FLASK_DEBUG
=
1 python skill/code/web/server.py
#
部署到 5.60
cd
deploy
&&
SSH_PASSWORD
=
'***'
python upload_to_
server.py
#
本地启动(生产模式,定时任务可用)
python skill/code/web/
server.py
#
登录密码
admin / Ubains@1357
#
部署到 5.60(用 ! 前缀在会话内执行)
!
cd
deploy
&&
SSH_PASSWORD
=
'***'
python upload_to_server.py
# 健康检查
# 健康检查
(含 scheduler 状态)
curl
-s
http://192.168.5.60:8088/api/health
# 快速巡检
curl
-s
-b
cookies.txt
"http://192.168.5.60:8088/api/service-monitor/run/stream?target_id=local&suite=quick"
# 全量巡检
curl
-s
-b
cookies.txt
"http://192.168.5.60:8088/api/service-monitor/run/stream?target_id=local&suite=full"
# 单元测试
cd
skill/code
&&
python
-m
pytest
-v
```
###
参考目录
###
服务器凭据
-
参考脚本:
`临时目录/服务器监测/lib/`
-
需求文档:
`Docs/需求文档/服务监测/`
-
会话交接:
`HANDOFF.md`
| 账号 | 用户名 | 密码 |
|------|--------|------|
| SSH | ubains | 见环境变量 SSH_PASSWORD |
| Web 管理员 | admin | 见 .env |
### 数据文件
| 数据 | 文件 |
|------|------|
| 监测目标 |
`service_monitor/data/targets.json`
|
| 巡检报告 |
`service_monitor/data/reports/*.json`
|
| 定时任务 |
`service_monitor/data/schedules.json`
|
| 通知配置 |
`service_monitor/data/notifications.json`
|
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论