feat: RESTART 走 NSSM 服务重启 + 失败原因可观测化

- RESTART 命令优先通过 nssm restart 重启主程序服务(假死场景可用),未配置服务名回退环回 HTTP
- nssm 输出按 UTF-16 解码并记录日志,权限不足时提示需以服务方式运行
- 环回管理接口 code=3001 时明确报鉴权失败,不再误报不可达
- 新增 nssm.path / main.service.name / log.dir 配置项
- 增加文件日志(RotatingFileHandler 5MB×5),服务方式运行可查日志
- HTTP 调用失败与状态码异常统一 WARNING 记录(原 DEBUG 不可见)
- 断线日志区分「网络不通」与「被服务器拒绝(未注册/token 错误)」
- 连接 URL 自动拼接 device.id,消除双处配置不一致

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-27 17:24:17 +08:00
co-authored by Claude
parent 86bbe8ef5a
commit f07bbbc49d
7 changed files with 144 additions and 26 deletions
+9
View File
@@ -10,8 +10,11 @@
- main.health.url 主程序健康检查地址(http://127.0.0.1:8082/api/admin/health
- main.admin.token 主程序管理接口 Token(与主程序 admin.token 一致)
- main.start.cmd 主程序启动命令(Windows: bin\\start.batLinux: bin/start.sh
- nssm.path NSSM 可执行文件路径(配置 main.service.name 时用于拉起服务)
- main.service.name 主程序注册的 Windows 服务名(配置后看门狗用 nssm restart 拉起,优先于 main.start.cmd
- heartbeat.sec 心跳间隔(默认 15 秒,须小于网关空闲超时)
- guard.enable 是否守护主程序(默认 true)
- log.dir 日志目录(默认 logs,相对部署根目录)
"""
import os
@@ -28,8 +31,11 @@ class AgentConfig:
main_health_url: str
main_admin_token: str
main_start_cmd: str
nssm_path: str
main_service_name: str
heartbeat_sec: int
guard_enabled: bool
log_dir: str
@classmethod
def load(cls, conf_path: str = "conf/agent.properties") -> "AgentConfig":
@@ -57,8 +63,11 @@ class AgentConfig:
main_health_url=_get(props, "main.health.url", "http://127.0.0.1:8082/api/admin/health"),
main_admin_token=_get(props, "main.admin.token", ""),
main_start_cmd=_get(props, "main.start.cmd", "bin/start.bat"),
nssm_path=_get(props, "nssm.path", ""),
main_service_name=_get(props, "main.service.name", ""),
heartbeat_sec=int(_get(props, "heartbeat.sec", "15")),
guard_enabled=_get(props, "guard.enable", "true").lower() == "true",
log_dir=_get(props, "log.dir", "logs"),
)