Repository navigation
feat(logging): 插件与调试适配器接入结构化日志 v2 - #1699
Merged
Merged
Conversation
- Core 为插件进程协商独立的 litheLogging 1,校验 lithe/log 的四种受控事实
(finished/failed/degraded/recovered),按已安装插件身份写入
plugins/<id>/host,并把仍在途的 wire 请求号映射回宿主 op
- LSP window/logMessage、window/showMessage 按上游明确类型选择独立目录事件;
未分类 stderr 降为 DEBUG,真实失败在失败边界记 ERROR
- DAP 由 Core 在真实状态转换点记录生命周期、内部状态与失败;macOS 宿主只补
进程启动失败、初始化超时和异常退出
- Java Support 用 ${logDir}/jdt.log 承接 Equinox 原生日志,限制体积与备份,
关闭命令行记录,默认级别收紧为 WARNING
- 补齐插件契约、fixture、日志目录、Agent Note 与平台功能矩阵
xiaoyumuxi
marked this pull request as ready for review
November 4, 2026 02:41
- Core 的 lithe/log 操作白名单加入 lithe/keymap/import,SDK 为快捷键导入 上报的终态事实按线上方法名记录,不再被当作未注册操作拒绝 - 插件契约 README 的 operation 字段说明同步列出该方法 - 新增回归:build/vcs/keymap 请求方法无需函数注册即可通过校验
Lithe Review结论: 未发现需要阻塞合并的问题。 Findings
Scope Check
Suggestions
Summary协议字段、身份来源和严重度边界总体清晰。主要缺口在从 Core 入队到宿主持久化之间的通知机制;现有 decoder 和目录测试不能覆盖这一交付问题。 Verification
|
Lithe 运行验收版本: 对照:共同祖先
未覆盖:
工作副本与运行状态已清理;可复用编译缓存按 12 GiB / 7 天预算保留。 |
This was referenced Nov 4, 2026
Core 事实队列原先只在宿主事件、flush 或退出时被排空,插件 lithe/log 事实和后台清理事实在宿主空闲时会一直留在内存,既不落盘也不推给日志窗口。 - Core 队列旁增加单一唤醒回调槽位:drain 后第一条事实或丢弃计数触发 一次回调,同一周期内合并;drain 在队列锁内重新武装;安装时已有待取 事实立即回调;移除返回后不再使用宿主 context。 - 新增 C ABI lithe_core_install_log_waker / lithe_core_remove_log_waker, 同步头文件、桥接(含 weak 回退)与 rust-core-api 契约。 - MacLogStore.observeCoreFacts 只复用已有 100 ms 单次 drain 调度;仅进程 应用 writer 安装,finishSession 先移除回调再做最后一次 drain。 - 结构化日志 Note 记录唤醒决策和被否方案。 - 测试:新增 Rust core_log_waker 集成测试与 Swift 无宿主活动落盘测试; stderr 降为 DEBUG 后改用仍为 WARN 的事件作样本;Java 插件测试改为 WARNING 默认值并补 logDirectory、断言 -Dosgi.logfile。
This was referenced Nov 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
结构化日志 v2 的插件与调试适配器接入:Core 为官方插件进程新增独立的
litheLogging1 协商和lithe/log通知,插件只能上报四种受控事实,由 Core 统一校验、脱敏并写入plugins/<id>/host;LSP/插件/VCS 的上游消息按明确严重度拆成独立目录事件,未分类 stderr 降为 DEBUG;DAP 生命周期由 Core 记录;内置 Java Support 的 Equinox 原生日志改由宿主日志会话承接。目标分支为
preview。这是跨仓库改动的第一步,SDK 和各插件仓库的配套 PR 依赖本 PR 合并后的 Core(见文末“合并顺序”)。插件结构化诊断(logging protocol 1)
rust/lithe-core/src/lsp/interface/plugin_logging.rs:插件会话(plugin_owned)在 initialize 的experimental能力里声明litheLogging: {"versions":[1]},插件回答{"version":1}后才启用;未协商的会话不接受lithe/log。lithe/log只接受四种事实:operationFinished→ INFO、operationFailed→ ERROR、degraded→ WARN、recovered→ WARN;字段限定为operation、durationMs、code、count、operationId,不接受自由文本。plugins/<id>/host,对应新目录事件plugins.operation.finished/failed/fallback_selected/recovery_finished。未协商或字段不合法的通知每会话只记一次plugins.diagnostics.rejectedWARN,不回显被拒内容;每会话每分钟最多 600 条,越限只计丢弃数(由宿主汇总为log.dropped),不记 WARN。client.rs在协商成功时把该能力写入server_capabilities,engine.rs/engine_logging.rs接入路由;core_events.rs的note_dropped改为pub(crate)供限流计数复用。shared/contracts/plugins/v1/README.md新增“Structured plugin diagnostics (logging protocol 1)”一节,新增 fixtureshared/contracts/plugins/v1/fixtures/plugin-logging.json;shared/contracts/rust-core-api.md、shared/logging/README.md同步说明。快捷键导入请求的诊断事实(286c0090d)
lithe/keymap/import为快捷键导入请求上报终态事实。Core 的known_operation原先只认注册函数、SDK 自有阶段、lithe/build/*和lithe/vcs/*,会把它当作未注册 operation 拒收;现在白名单加入keymap_provider::IMPORT_METHOD。operation字段的说明同步列出lithe/keymap/import。plugin_logging.rs新增回归:lithe/build/model、lithe/vcs/status、lithe/keymap/import在没有任何函数注册时也能通过校验。评审 P2 修复:没有宿主活动时,Core 事实也会落盘
问题:Core 事实队列原先只在 MacLogStore 因宿主事件、flush 或退出而 drain 时被取走。插件
lithe/log事实、析构和后台清理事实如果发生在宿主空闲时,会一直留在内存,既不写盘,也不推给日志窗口。修复(不加轮询、不加第二个 writer):
rust/lithe-core/src/diagnostics/core_events.rs:队列旁新增一个唤醒回调槽位。drain 之后第一条事实或第一次丢弃计数触发一次回调,同一 drain 周期内的后续事实合并;drain()在队列锁内清除请求标记,之后入队的事实一定再次触发。安装时已有待取事实立即回调。回调在持有槽位锁时同步执行,移除也取这把锁,移除返回后 Core 不再使用宿主 context。rust/lithe-core/src/runtime/ffi.rs新增 C ABIlithe_core_install_log_waker/lithe_core_remove_log_waker(只有 context 匹配时才移除,返回 1/0);同步lithe_core.h、lithe_bridge.h、bridge.c(含 weak 回退)和shared/contracts/rust-core-api.md。MacLogStore.observeCoreFacts():回调只复用宿主事件已有的 100 ms 单次 drain 调度(已有调度时不重复安排),drain 本身仍在 writer 的串行队列上,不在 Core 线程。CoreLogWakeTarget弱引用 store,不延长 writer 生命周期;finishSession先停止接纳并移除回调,再做最后一次 drain;deinit也会移除。MacServiceContainer.makeApplicationLogWriter创建的进程应用 writer 安装回调;测试和其他临时 MacLogStore 不安装,避免两个 writer 争抢同一个进程队列。rust-core-api.md说明唤醒语义和回调约束;结构化日志 Note 记录这一决策,以及被否方案(宿主定时轮询、每条事实回调或在回调里直接 drain)。rust/lithe-core/tests/core_log_waker.rs(独立测试二进制,覆盖空队列不唤醒、突发合并、drain 后重新触发、非持有者不能移除、移除后不再回调、安装时已有事实立即回调);新增 Swift 测试coreFactsReachDiskAndSubscribersWithoutHostActivity,在隔离子进程里只触发 Core 事实、不调用 emit/flush,验证事实写入磁盘并推送给订阅者。CI 修复(本 PR 引入的失败)
MacLogStoreTests:本 PR 把未分类 stderr 降为 DEBUG 后,非诊断模式下 DEBUG 不落盘,原来用 stderr 事件做样本的保留、轮转和 Core 事实测试因此失败;样本改为仍为 WARN 的lsp.message.warning.logged/vcs.message.warning.logged(coreFactsUseCatalogFieldsAndNativeFilesStayInsideTheSession原来以 WARN 级别提交vcs.stderr.received,与目录里的 DEBUG 不一致,被 Core 目录校验拒绝)。原有的隔离子进程逻辑抽成runsInIsolatedCoreProcess,供新测试复用。PluginSettingsTests:Java 插件logLevel默认值断言从ALL改为WARNING;JVM 参数测试补logDirectory(${logDir}现在是必需输入),并断言-Dosgi.logfile=/logs/jdt.log。GitModuleTests(386/477/3140 行)和GitWorktreeAppearanceTests的失败来自 GIT-07 统一 ChangeList 归属与提交范围 #1697 把 changelist 投影改成异步;分支已合入最新preview,其中的 修复 ChangeList 工作树测试的异步投影 #1704 让这些测试等待投影完成,修复了这些失败。LSP / 插件 / VCS 消息严重度
window/logMessage和window/showMessage按上游明确的 type 选择独立目录事件:Error →*.message.error.logged|shown(ERROR)、Warning →*.message.warning.*(WARN)、Info 沿用原有*.message.logged|shown(INFO)、Log 及未知类型 →*.message.detail.*(DEBUG),覆盖lsp、plugins.host、vcs三类会话。lsp.stderr.received、plugins.host.stderr.received、vcs.stderr.received)由 WARN 降为 DEBUG:stderr 不代表严重度,真实失败在失败边界用新增的lsp.session.failed、plugins.host.session.failed、vcs.session.failed记 ERROR。shared/fixtures/diagnostics/logging-v2.json中lsp.stderr.received的归一化样例级别同步改为 DEBUG(否则严格目录校验会拒绝该样例)。DAP 生命周期
rust/lithe-core/src/debug/engine.rs在真实状态转换点记录debug.process.started、debug.session.initialized、debug.session.finished(INFO),debug.session.state_changed、debug.operation.cancelled(DEBUG),debug.session.failed、debug.operation.failed、debug.transport.failed(ERROR),通道为debug/<adapter>。程序输出和原始 stderr 仍只进调试控制台,不进日志。CoreDebugAdapterProtocolSession.swift只补 Core 看不到的三处传输失败:进程启动失败(stage: process-start)、初始化超时(initialization-timeout)、非零退出且会话尚未失败(transport-exit,带 exitCode),都关联调试会话 ID。Java Support 原生日志
Plugins/mac/Official/JavaSupport/plugin.json增加-Dosgi.logfile=${logDir}/jdt.log、-Declipse.log.include.commandline=false、-Declipse.log.size.max=1024、-Declipse.log.backup.max=2、-Declipse.log.level=WARNING:Equinox 日志写到宿主分配的日志会话目录(平台可写目录,不在 bundle),不记录启动命令行,1 MiB、两个备份。-Dlog.level由ALL收紧为WARNING(plugin.json设置默认值与rust/lithe-core/src/lsp/languages/jdt.rs的DEFAULT_LOG_LEVEL_ARGUMENT,测试同步)。OSGi 状态和索引不进入日志目录。目录、文档与功能矩阵
shared/logging/events/{debug,lsp,plugins,vcs}.json新增上述事件,重新生成LogEvents.generated.swift与catalog_generated.rs(合并 修复 IDE 快捷键导入与终端切换 #1695 后共 241 条)。2026-11-03-structured-logging-channels.md补严重度映射、“官方插件通过新的类型化协议交付事实”“DAP:记录状态与失败,保留程序内容边界”两节;2026-10-13-java-language-server-as-declarative-plugin.md新增“原生日志属于宿主日志会话”;2026-10-14-declarative-plugin-settings.md更新 JDT 默认级别。diagnostics-export、java-support-plugin、lsp-status-logs、plugin-debug-adapters补充实现文件与验证说明。验证
在最新
preview(含 #1695)上 rebase 后本地完成:cargo test --lib(workspace 全部):lithe-core 1683 项、lithe-agent-host 258 项(另 1 项既有 ignored)及其余 crate 全部通过;cargo fmt -p lithe-core -- --check通过。generate-log-events.mjs --check(241 条)、verify-log-usage.mjs(0 违规)、test-log-events.mjs。verify-app-language-localization.mjs、generate-i18n.mjs --check。verify-platform-feature-matrix.sh(234 项)与verify-platform-feature-matrix-change.sh origin/preview HEAD。verify-shared-contracts.sh、verify-rust-core-comments.sh、verify-agent-notes.sh(203 篇)、verify-windows-boundaries.sh、verify-runtime-bundle-immutability.sh。cargo test -p lithe-core --lib1683 项通过,cargo fmt -p lithe-core -- --check、verify-shared-contracts.sh、verify-rust-core-comments.sh通过。node scripts/sdk-e2e.mjs --source <本工作树> --ref codex/owned-plugin-logging(宿主 286c009),9/9 通过,含三种 SDK 的快捷键导入场景(此前 Codex 工作区的 6 项是在 SDK 加入快捷键导入场景之前跑的)。MacLogStoreTests+PluginSettingsTests40 项全部通过(含新测试coreFactsReachDiskAndSubscribersWithoutHostActivity);cargo test -p lithe-core --test core_log_waker与--lib core_events通过;cargo fmt -p lithe-core -- --check、verify-rust-core-comments.sh、generate-log-events.mjs --check、verify-log-usage.mjs、i18n 两项检查、verify-shared-contracts.sh、verify-runtime-bundle-immutability.sh、verify-windows-boundaries.sh、verify-agent-notes.sh、verify-platform-feature-matrix.sh通过。LitheDebugModule和生成日志类型在本机 Swift 6.4.2 编译通过。限制与评审重点
cargo fmt --all --check会报lithe-agent-host的格式差异,该 crate 本 PR 未改动,差异在preview上已存在。plugin_logging.rs的协商与校验边界(未协商拒收、限流、拒收只记一次、wire 请求号映射),以及 stderr 降级到 DEBUG 是否会让某些真实失败只剩 DEBUG(失败边界已补*.session.failed)。合并顺序(跨仓库)
preview。node scripts/contract.mjs sync --revision <本 PR 合并后的 preview commit>同步contract/v1,再合入 SDK PR。litheLogging1,在本 PR 合并前这些插件的 CI 会按预期失败(cargo、svn 报 “Selected Core lacks litheLogging:1”);正式发布前把各插件 vendored SDK 固定到合并后的 SDK commit。配套 PR: