feat: 巡检增强 / 拓扑大屏 / 远程 HTTP / portable 绿色打包
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
巡检模块:巡检调度器改为轮询驱动,新增每日报告存储、告警规则独立 Store、设备 Store 解耦,_executeSnapshot 补齐 DEBUG 声明,巡检中心 与告警中心页增强。 拓扑大屏:MonitoringTopologyView 扩展分组/布局控制, useMonitoringData 重构数据流。 远程 HTTP:新增 electron/remoteHttpServer.cjs,preload/api.cjs 暴露 IPC,registerBridges 注册 netcatty:http:open 桥。 portable 绿色打包: - electron-builder.config.cjs 恢复原始白名单(61MB app.asar), 收集器自动追踪运行时依赖; - portableData.cjs 重写为 .portable 标记检测; - scripts/migratePortableLocalStorage.cjs 离线脚本把 Local Storage 的 http://localhost:5173 origin 批量迁移为 app://netcatty; - scripts/scanWorkspaceDeps.cjs 扫描 workspace 运行时依赖。
This commit is contained in:
@@ -33,7 +33,8 @@ class InspectionScheduler {
|
||||
* @param {function} options.readFn - 读取存储 (key) => string
|
||||
* @param {function} options.writeFn - 写入存储 (key, value) => void
|
||||
* @param {function} options.getConnectionFn - 获取 SSH 连接 (hostId) => connection 或 null
|
||||
* @param {function} options.execFn - 执行命令 (hostId, command) => Promise<string>
|
||||
* @param {function} options.execFn - 执行单条命令 (hostId, command) => Promise<string>
|
||||
* @param {function} [options.execCommandsFn] - 批量执行多条命令 (hostId, commands) => Promise<{ results, stdout }>
|
||||
* @param {function} [options.onResult] - 单设备巡检完成回调
|
||||
* @param {number} [options.pollIntervalMs] - 轮询间隔
|
||||
* @param {number} [options.concurrency] - 并发数
|
||||
@@ -44,6 +45,7 @@ class InspectionScheduler {
|
||||
this.writeFn = options.writeFn;
|
||||
this.getConnectionFn = options.getConnectionFn;
|
||||
this.execFn = options.execFn;
|
||||
this.execCommandsFn = options.execCommandsFn;
|
||||
this.onResult = options.onResult || (() => {});
|
||||
this.onAlertChanged = options.onAlertChanged || (() => {});
|
||||
this.pollIntervalMs = options.pollIntervalMs || DEFAULT_POLL_INTERVAL_MS;
|
||||
@@ -93,6 +95,13 @@ class InspectionScheduler {
|
||||
if (!this._running) return;
|
||||
|
||||
try {
|
||||
// 全局自动巡检开关(一键启用/停止)
|
||||
const autoEnabledRaw = this.readFn("inspection-auto-enabled");
|
||||
const autoEnabled = autoEnabledRaw !== "false"; // 默认 true
|
||||
if (!autoEnabled) {
|
||||
return; // 全局停止 —— 跳过本次 tick
|
||||
}
|
||||
|
||||
// 1. 获取所有启用巡检的设备
|
||||
const devices = deviceStore.getEnabledDevices(this.readFn);
|
||||
|
||||
@@ -149,6 +158,8 @@ class InspectionScheduler {
|
||||
}
|
||||
|
||||
// 2. 创建采集器
|
||||
// connectionInfo 只传 { host: hostId } 作为标识——adapter 的 execCommands 会被 options.execCommands 覆盖,
|
||||
// 真正的 SSH 凭据由主进程 execCommandsFn 从 _hostConfigs 读取(和 execFn 同理)
|
||||
const adapter = adapterRegistry.createAdapter(
|
||||
catalog.adapter_class,
|
||||
{ host: hostId },
|
||||
@@ -157,6 +168,11 @@ class InspectionScheduler {
|
||||
if (!this.execFn) throw new Error("execFn 未配置");
|
||||
return this.execFn(hostId, cmd);
|
||||
},
|
||||
execCommands: this.execCommandsFn
|
||||
? async (commands, options) => {
|
||||
return this.execCommandsFn(hostId, commands, options);
|
||||
}
|
||||
: undefined,
|
||||
timeoutMs: this.timeoutMs,
|
||||
}
|
||||
);
|
||||
@@ -281,10 +297,8 @@ class InspectionScheduler {
|
||||
console.log(`[InspectionScheduler] 告警评估 device=${deviceName}(${deviceExt.host_id}) online=${metrics.online} 规则数=${rules.length}`);
|
||||
|
||||
for (const rule of rules) {
|
||||
// 特殊处理:online 指标
|
||||
if (rule.metric === "online") {
|
||||
const isOnline = metrics.online !== false;
|
||||
// threshold 为 "false" 表示离线时告警
|
||||
const shouldAlert = rule.threshold === "false" ? !isOnline : isOnline;
|
||||
console.log(`[InspectionScheduler] 离线规则: name=${rule.name} enabled=${rule.enabled} threshold=${rule.threshold} isOnline=${isOnline} shouldAlert=${shouldAlert}`);
|
||||
const alertResult = alertRecordStore.processAlert(
|
||||
@@ -308,8 +322,8 @@ class InspectionScheduler {
|
||||
|
||||
const isTriggered = alertRuleStore.evaluateRule(value, rule.operator, rule.threshold);
|
||||
|
||||
const hostInfo = this._hostInfo[deviceExt.host_id] || {};
|
||||
const deviceName = hostInfo.label || hostInfo.hostname || deviceExt.host_id;
|
||||
// 注意:hostInfo / deviceName 在函数顶部 L285-286 已声明,此处直接复用,
|
||||
// 避免同名 const 重复声明导致 TDZ(Cannot access 'deviceName' before initialization)
|
||||
const alertResult = alertRecordStore.processAlert(
|
||||
this.readFn,
|
||||
this.writeFn,
|
||||
|
||||
Reference in New Issue
Block a user