Make stderr output exclusive to fatal paths and consistent across all fatal paths
维护者通常 1 天内回复
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 35/100
- Issue 类型
- 功能
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
调研方向
Start by reading the console logger and fatal reporting code in include/ccf/ds/logger.h and src/host/runtime_control.h, then trace the join callers in src/node/node_state.h and the post-join failure examples in src/node/rpc/frontend.h and src/host/socket.h. Review the Rust panic-hook handling in src/rust/ccf-app/src/lib.rs and existing regression tests for process output. Done means documenting the stderr contract and scope, covering fatal and recoverable paths, and ensuring fatal diagnostics avoid confidential request or KV data.
由索引模型根据 Issue 内容生成。
描述
Is your feature request related to a problem? Please describe.
CCF's stderr is not currently a consistent indicator of fatal failure.
Some fatal paths write to stderr, while others log only to stdout before aborting or exiting.
Operators therefore cannot rely on an empty stderr to mean that no fatal error occurred, or use stderr alone to capture fatal diagnostics.
Source inspection found the following behavior:
- Normal framework and application logging uses stdout at every severity, including
failandfatal, for both text and JSON console loggers.LOG_FATAL_FMTandCCF_APP_FATALdo not themselves terminate execution or write to stderr. RuntimeControlImpl::report_fatal_error()writes and flushes the first reported error to stderr, then requests enclave shutdown. All four current production call sites are on the join path: oversized join responses; non-retryable transport/TLS failures, including certificate trust failures; fatal join client errors, except the supported fresh-snapshot retry case; and startup-snapshot installation failures during join completion.- CLI11 writes command-line parsing errors to stderr. Help and version output use stdout.
files::slurp()writes required-file open/read failures to stderr and exits whenoptional == false.- Post-join fatal paths can log to stdout and call
abort()without a CCF stderr diagnostic. Examples include transaction serialisation failure in the RPC frontend and socket resolve/listen failure handlers.abort()itself does not print a diagnostic; a supervising shell may separately report the signal. - Native assertion failures can emit stderr diagnostics when assertions are enabled. Uncaught C++ exceptions and Rust's default panic hook can also produce runtime diagnostics. The experimental Rust SDK suppresses panic diagnostics for caught application-callback panics, but forwards other panics to the previously installed hook.
- Applications and dependencies can write directly to stderr, for example through Rust's
eprint!/eprintln!. Such output is not governed by CCF's logger today.
Describe the solution you'd like
Establish and enforce the following contract for CCF node stderr:
- Only fatal paths write to stderr. Recoverable errors, warnings, and ordinary application logging must not produce stderr output.
- All fatal paths consistently write a useful diagnostic to stderr before the node terminates, including failures after joining the network. This must not depend on whether the path uses
report_fatal_error(), logs and aborts, or exits through another mechanism.
Preserve useful stdout logging while ensuring stderr has the same meaning across startup, join, and steady-state operation.
Document the contract and its scope, including application/dependency writes and runtime-generated diagnostics.
Distinguish actual fatal termination paths from the fatal log-level label: emitting a log entry at that level does not currently imply termination.
Fatal diagnostics must not expose confidential request or KV data.
Add regression coverage demonstrating both sides of the contract: fatal paths emit stderr diagnostics, and recoverable paths do not.
Describe alternatives you've considered
Continue parsing stdout severity labels and combining them with process exit status.
This leaves stderr inconsistent, and the fatal severity label alone is not equivalent to a fatal termination path.
Routing all fail or fatal log entries to stderr without considering control flow would not establish the requested fatal-path-only contract.
Additional context
Findings are based on source inspection at commit 4bb1570da7264b0daa417f2c6e4e497124f0b8d0, rather than an exhaustive runtime reproduction.
Relevant source locations:
- 主要语言
- C++
- 星标
- 876
- 派生
- 264
- 平均合并
- 1 天 16 小时
- 30 天内合并 PR
- 127
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/CCF 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 48/100
microsoft/CCF#8688 · 1 个 reaction ·
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 35/100
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 8/100
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 35/100
维护者通常 1 天内回复
-
raft.h hardening未关闭
难度 5/5 一周以上 新手友好度 25/100
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 85/100
DarkCastleMUD/DarkCastle#283 ·
-
-priority- blocked good first issue help wanted
难度 2/5 1-3 小时 新手友好度 68/100
scribe-org/Scribe-Android#761 · 2 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
Bug Testing
难度 2/5 1-3 小时 新手友好度 78/100
SCIInstitute/SCIRun#2931 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 5 天内回复
-
难度 1/5 1-3 小时 新手友好度 85/100
维护者通常 1 天内回复