已开启
[Feature]: 增加框架连接与运行时诊断日志 #74
yuheng_wang创建于  29 天前
yuheng_wang
yuheng_wang
29 天前 创建

🚀 背景描述

ScienceDiscovery 已通过 operational logger 将服务日志写入数据目录下的 logs/,默认位置为 .sciencediscovery-data/logs/。其中 api.log 已包含 API 启动、部分组件状态与未分类异常,runner.log 记录 Runner 请求和沙箱执行,run.log 记录 Agent Run 生命周期。

当前缺口集中在 Agent/LLM 看不到的框架内部链路:

  • MCP 客户端连接、重连、关闭及工具目录加载缺少完整的成功/失败日志;
  • MCP stdio 子进程的 stderr 被忽略,进程启动或协议握手失败时缺少服务端原始线索;
  • MCP 代理配置解析和运行时切换存在静默失败,且日志无法区分“配置了代理”和“当前传输实际应用代理”;
  • 远端 Runner 的主机探测、直连、断线与 SSH 隧道错误主要停留在内存状态中,进程退出后难以追溯;
  • 启动阶段部分组件初始化失败缺少统一、可检索的阶段事件;
  • 部署通过 SIGTERM 关闭 API 时,HTTP Server 与 MCP transport 的异步关闭没有统一编排,MCP 关闭事件可能来不及落盘。

本功能的目标是复用现有滚动日志,为这些框架链路补齐结构化、可关联、经过脱敏且有体积上限的诊断事件,让开发人员在 MCP、代理、远端 Runner、启动组件或进程关停发生故障时,能够仅通过日志定位失败阶段、目标、错误类别、耗时和重试情况。

本方案不是 Agent 操作审计能力,不要求 Agent 或 LLM 感知这些日志。

设计思路

1. 存储与日志形式

  • 复用现有 <dataDir>/logs/api.log,默认即 .sciencediscovery-data/logs/api.log;
  • 继续使用 operational logger 的文本行格式、级别过滤和滚动策略;
  • 框架组件初始化开始与完成事件均使用 info 级别,默认配置下成对可见;
  • 沿用 SCIENCE_AGENT_LOG_LEVEL、SCIENCE_AGENT_LOG_DIR、SCIENCE_AGENT_LOG_MAX_BYTES、SCIENCE_AGENT_LOG_MAX_BACKUPS 配置;
  • 默认单文件上限 10 MiB、保留 5 个备份;
  • 不新增独立 audit JSONL、日志索引、日志文件清单、数据库表或 UI。

2. 覆盖范围

链路 需要记录的事件 关键字段
框架启动 组件初始化开始、成功、失败 component、durationMs、errorCode、error
框架关停 SIGTERM 关停开始、成功、失败、超时 signal、timeoutMs、error
MCP 连接 开始、成功、失败、关闭、关闭失败 serverId、transport、endpointProtocol、endpointHost、durationMs
MCP 工具目录 全部加载成功、单服务加载失败 serverId、toolCount、errorCode、error
MCP 代理 配置加载、配置变更、解析失败 proxyMode、proxyApplied、代理协议与主机
MCP 调用 非语义性传输/服务端/超时/限流失败及重试调度 serverId、toolName、requestId、attempt、delayMs、errorCode
远端主机 SSH 主机探测开始、成功、失败 hostId、host、port、durationMs、errorCode
远端 Runner 连接开始、成功、失败、断线、关闭 runnerId、connectionMode、endpointHost、durationMs
SSH 隧道 转发、stream、socket 失败 hostId、runnerId、errorCode、error

启动组件首批覆盖 Skill Catalog、自定义 MCP Server、Session Store、Artifact 恢复和 Run 恢复。已有 Runner、Memory Graph 等模块的日志继续使用原通道,本功能不重复记录其业务载荷。

API 进程收到 SIGTERM 后先停止 HTTP Server,再等待 MCP transport 的 shutdown hook 完成。关闭流程幂等,重复调用复用同一个 Promise;MCP 关闭完成后才记录 service_shutdown_completed,确保已连接 session 的 mcp_connection_closed(reason=shutdown) 已写入。关停超过 15 秒则记录超时并失败退出。关停同时释放 MCP/Web cache 的 SQLite 句柄。

连接后若 listTools 失败,mcp_catalog_server_failed 附带受限、脱敏的 stdio stderrTail。

3. MCP stdio stderr

MCP stdio 子进程的 stderr 从忽略改为受控采集:

  • 内存中最多保留 4 KiB 尾部,避免持续输出导致内存增长;
  • 仅在连接、调用或关闭失败时附带最后 4 个非空行;
  • 单条日志中的 stderr 摘要不超过 1 KiB;
  • 成功路径不输出 stderr 内容;
  • 摘要进入日志前执行统一脱敏。

4. 代理语义

日志必须区分:

  • proxyMode:当前解析到的代理配置模式;
  • proxyApplied:当前 MCP transport 是否实际应用了该代理。

stdio transport 不经过 HTTP 代理;HTTP/SSE transport 若底层实现尚未接入代理,也不能仅因存在代理配置就记录为已应用。日志只记录代理协议和主机,不记录完整 URL、用户名、密码或敏感查询参数。

5. 脱敏、体积与可靠性边界

  • 统一通过 redactLogValue 处理日志字段;
  • 脱敏 Authorization/Bearer、token、secret、password、cookie、URL userinfo 及敏感 query 参数;
  • Remote Compute 在调用注入 logger 前复用 operational-logging 的 shortErrorMessage,不维护第二套脱敏规则;
  • 不记录 args、body、content、input、messages、output、prompt、request、response、完整 stdout/stderr 等大载荷;
  • 错误消息及 stderr 摘要设置明确长度上限;
  • 用户会话内容、模型输入输出、工具参数、工具结果正文不进入框架诊断日志;
  • operational logger 保持 best-effort,日志目录创建、写入或轮转失败不能打断服务主路径。

6. 代码落点

  • services/api/src/bootstrap/platform.ts:框架组件初始化,以及 MCP/远端计算 logger 注入;
  • services/api/src/mcp/node-client.ts:MCP 连接、目录、代理、调用重试与受控 stderr;
  • services/api/src/http/index.ts:幂等、可等待的 API/MCP 资源关闭;
  • services/api/src/server.ts:SIGTERM 关停入口、完成/失败/超时日志;
  • packages/executor/src/remote-compute.ts:主机探测、远端 Runner 与 SSH 隧道生命周期;
  • packages/operational-logging/src/index.ts:统一错误缩短及 URL 凭据、敏感查询参数脱敏。

7. 明确不在本功能范围内

  • 不提供日志查看、搜索或下载 UI;
  • 不生成日志索引或所有日志文件的清单;
  • 不新增 Agent 可见事件,也不改变 Agent、Tool、MCP 的业务返回值;
  • 不把用户会话、LLM 请求/响应、工具输入/输出复制到框架日志;
  • 不实现代理健康检查、自动故障转移或代理管理面板;
  • 不将本日志定义为不可篡改的合规审计账本;
  • 本轮只接入部署使用的 SIGTERM,不改变其他进程信号的既有语义;
  • 不在本轮扩展 Paper Worker、模型供应商 SDK、Web Search 或 Memory Graph 的业务级事件。

涉及到的对外API

无对外 API、SSE schema 或 UI 变更。运维侧继续使用现有日志环境变量,不增加新的必填配置。

内部接口变更:

  • MCP transport 增加可选异步 close();
  • API 内部增加可等待的 closeApiServer();
  • Remote Compute 使用命名 options 注入 logger/transport;
  • 未注入 logger 或 close hook 时保持兼容,不改变已有调用行为。

与其他模块的相关性描述

  • services/api:作为 composition root 注入已有 operational logger,并编排启动、关停和基础设施 adapter 生命周期;
  • packages/executor:记录 Remote Compute 生命周期,不反向依赖 API service;
  • packages/operational-logging:负责文件写入、级别过滤、轮转、集中脱敏和有界错误文本;
  • MCP Tool Registry、Agent Runtime、SSE 与 UI:业务接口和事件 schema 不变,不接收本功能新增的框架诊断事件;
  • Runner 与 Memory Graph:保留各自已有日志通道,不将既有业务日志重复写入 api.log。

测试设计与测试计划

功能测试

安全与可靠性测试

工程验证

likedislike
yuheng_wangyuheng_wang
29 天前 添加了label:feature
openJiuwen-bot成员
29 天前 评论:

欢迎来到 openJiuwen 社区

Hey @yuheng_wang , 感谢你对社区的贡献.

机器人使用手册

有关指令的使用,可以点击 此处 查看详情。开发人员可以在每个PR或Issue下方评论特定指令来触发机器人任务。

likedislike
yuheng_wangyuheng_wang
29 天前 修改了issue 的描述
yuheng_wangyuheng_wang
29 天前 关联了pull request:feat(api): 增加框架连接与运行时诊断日志
yuheng_wangyuheng_wang
29 天前 修改了issue 的描述
yuheng_wangyuheng_wang
29 天前 修改了issue 的描述
yuheng_wangyuheng_wang
29 天前 修改了issue 的描述
yuheng_wang
yuheng_wang
29 天前 评论:

设计补充:SIGTERM 关停时,HTTP Server 先停止接收新连接,并给普通在途请求 1 秒 drain 窗口;若仍存在 SSE、未完成请求或其他长连接,则记录 http_connection_drain_timed_out 并调用 closeAllConnections()。HTTP close 完成后再等待 MCP transport shutdown,从而保证长连接不会阻塞 mcp_connection_closed(reason=shutdown) 和后续 service_shutdown_completed。整体关停仍受 15 秒超时兜底约束。对应测试使用未完成的 HTTP 请求保持连接,断言 closeAllConnections() 被调用、MCP 异步关闭完成且重复关闭幂等。

likedislike
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述
yuheng_wangyuheng_wang
28 天前 修改了issue 的描述