Bug 描述
INFO 当前返回大量硬编码值,与真实进程、配置、运行平台、Redis 8.8.1 兼容基线和 Raft 状态无关。监控系统、客户端和运维人员会把这些值当作服务事实,当前输出会提供错误的版本、OS、端口、PID、uptime 和 cluster 状态。
对比基线:
- Rust Kiwi:
main@3164d4a0fead580ac6701fb0595e50193c4edff9(2026-07-31)
- kiwi-cpp:
unstable@0fa4f1b95ff2f89873d06eb86de40532dd91d146;其 #176 也要求让 INFO 输出与 Redis 对齐
当前源码证据
InfoCmd::do_cmd() 不读取传入的 Storage,也没有 server/runtime/Raft 状态 provider,而是直接拼接常量:
redis_version:7.0.0,与项目固定的 Redis 8.8.1 兼容基线不一致;
os:Windows、multiplexing_api:select、gcc_version:0.0.0,在 Linux/macOS 和当前 Tokio 架构下均不代表真实运行时;
process_id:1、tcp_port:7379、uptime_in_seconds:1、executable:/path/to/kiwi-server,不读取实际进程和配置;
redis_mode:standalone、cluster_enabled:0、cluster_state:disabled,即使启用 OpenRaft 仍报告 standalone/disabled;
- 未知 section 被静默降级为一小段 Server 信息,且
default 只返回 Server/Cluster 两节,没有建立 Redis 8.8.1 的 section 选择合同。
项目自己的兼容要求已经把 INFO 列为必须验证的发现接口,系统稳定门禁也要求持续记录 请求延迟、吞吐、资源、compaction stall 和 Raft commit/apply latency。当前 INFO 既不满足兼容发现,也不能作为运维观测入口。
与现有 Issue 的关系
当前没有开放 Issue 对 INFO 的硬编码错误和 Redis 8.8.1 section 合同负责。
建议设计
1. 注入只读状态 Provider
不要在 cmd crate 引入无边界全局变量。为 InfoCmd 注入只读、可测试的 ServerInfoProvider/等价接口,由 server startup 组合真实来源:
- build identity:Kiwi 版本、Git SHA/build id、目标架构;
- process identity:OS、PID、可执行文件、启动时间、实际监听端口、配置文件身份;
- network/client:当前连接数、累计连接、拒绝/超时/协议错误;
- storage/RocksDB:实例数、路径身份、内存/缓存、WAL、compaction、读写错误与 keyspace;
- runtime/executor:queue、running worker、completed/failed/timed-out、queue wait/execution time;
- Raft:是否启用、node id、role/leader、term、membership、last log/applied/snapshot、commit/apply latency 和 unhealthy 状态。
Provider 返回一次有边界的 snapshot;组装 INFO 时不得在每个字段重复获取锁、执行无界 RocksDB 扫描或发起网络 RPC。
2. 固定 Redis 8.8.1 section 合同
先用仓库规定的 exact Redis 8.8.1 Oracle 获取 INFO 的参数、section、默认集合、未知 section、字段格式和 RESP2/RESP3 返回类型证据,再实现 Kiwi 支持的 section。
至少分阶段覆盖:
server、clients、stats、persistence、replication/cluster、keyspace;
memory、cpu、commandstats、latencystats、errorstats;
default、all、everything 和多 section 组合。
对 Redis 有字段但 Kiwi 暂无等价来源的情况,应根据兼容证据决定“真实的零/状态值”或“暂不输出”,不得继续填入看似真实的常量。Kiwi 扩展字段使用稳定的 kiwi_* 命名并写入文档。
3. 安全和性能边界
- 不输出 requirepass、完整命令参数、用户 key、凭据或未脱敏内部地址;
- command/错误指标使用固定命令表和有界 label,不允许攻击者输入制造无界基数;
- RocksDB property 获取必须有 timeout/缓存策略,单次
INFO 不得阻塞 storage runtime 或触发全库遍历;
- 指标读取失败应在对应 section 显示可诊断状态或省略字段,不能退回硬编码假数据;
INFO 自身应继续是只读命令,不改变 Raft/storage 状态。
验证范围
命令级兼容测试
- 用 exact Redis 8.8.1 对照无参数、单 section、多 section、
default、all、everything、未知 section 的 raw RESP;
- RESP2/RESP3 返回均为正确的 bulk payload,CRLF、section header、字段分隔和顺序合同有测试;
INFO server 不再出现固定 7.0.0、Windows、PID 1、端口 7379、uptime 1 或占位 executable。
真实进程测试
- 在 Linux 随机端口启动 standalone,校验 PID、port、OS/arch、uptime 单调增长、配置身份和实际模式;
- 建立/关闭客户端连接,验证
clients/stats 的真实变化;
- 执行读写、错误、timeout 和 compaction/RocksDB 活动,验证相关 counter/latency 来自真实调用点;
- 启动三节点 OpenRaft,验证 leader/follower、node id、term、membership、applied/snapshot 等字段与 Raft metrics 一致;
- 重启后 PID/uptime 更新,持久化/复制状态仍与实际数据一致;
- 未启用 Raft 时不得伪装 leader/cluster healthy;启用 Raft 时不得报告 standalone/disabled。
非目标
验收标准
Bug 描述
INFO当前返回大量硬编码值,与真实进程、配置、运行平台、Redis 8.8.1 兼容基线和 Raft 状态无关。监控系统、客户端和运维人员会把这些值当作服务事实,当前输出会提供错误的版本、OS、端口、PID、uptime 和 cluster 状态。对比基线:
main@3164d4a0fead580ac6701fb0595e50193c4edff9(2026-07-31)unstable@0fa4f1b95ff2f89873d06eb86de40532dd91d146;其 #176 也要求让INFO输出与 Redis 对齐当前源码证据
InfoCmd::do_cmd()不读取传入的Storage,也没有 server/runtime/Raft 状态 provider,而是直接拼接常量:redis_version:7.0.0,与项目固定的 Redis 8.8.1 兼容基线不一致;os:Windows、multiplexing_api:select、gcc_version:0.0.0,在 Linux/macOS 和当前 Tokio 架构下均不代表真实运行时;process_id:1、tcp_port:7379、uptime_in_seconds:1、executable:/path/to/kiwi-server,不读取实际进程和配置;redis_mode:standalone、cluster_enabled:0、cluster_state:disabled,即使启用 OpenRaft 仍报告 standalone/disabled;default只返回 Server/Cluster 两节,没有建立 Redis 8.8.1 的 section 选择合同。项目自己的兼容要求已经把
INFO列为必须验证的发现接口,系统稳定门禁也要求持续记录 请求延迟、吞吐、资源、compaction stall 和 Raft commit/apply latency。当前INFO既不满足兼容发现,也不能作为运维观测入口。与现有 Issue 的关系
main仍保留该实现;INFO内重新实现第二套 tracker;MONITOR是实时命令流,与INFO的状态快照和发现接口不同;INFO协议输出。当前没有开放 Issue 对
INFO的硬编码错误和 Redis 8.8.1 section 合同负责。建议设计
1. 注入只读状态 Provider
不要在
cmdcrate 引入无边界全局变量。为InfoCmd注入只读、可测试的ServerInfoProvider/等价接口,由 server startup 组合真实来源:Provider 返回一次有边界的 snapshot;组装
INFO时不得在每个字段重复获取锁、执行无界 RocksDB 扫描或发起网络 RPC。2. 固定 Redis 8.8.1 section 合同
先用仓库规定的 exact Redis 8.8.1 Oracle 获取
INFO的参数、section、默认集合、未知 section、字段格式和 RESP2/RESP3 返回类型证据,再实现 Kiwi 支持的 section。至少分阶段覆盖:
server、clients、stats、persistence、replication/cluster、keyspace;memory、cpu、commandstats、latencystats、errorstats;default、all、everything和多 section 组合。对 Redis 有字段但 Kiwi 暂无等价来源的情况,应根据兼容证据决定“真实的零/状态值”或“暂不输出”,不得继续填入看似真实的常量。Kiwi 扩展字段使用稳定的
kiwi_*命名并写入文档。3. 安全和性能边界
INFO不得阻塞 storage runtime 或触发全库遍历;INFO自身应继续是只读命令,不改变 Raft/storage 状态。验证范围
命令级兼容测试
default、all、everything、未知 section 的 raw RESP;INFO server不再出现固定7.0.0、Windows、PID 1、端口 7379、uptime 1 或占位 executable。真实进程测试
clients/stats的真实变化;非目标
MONITOR、SLOWLOG、在线 flame graph 或 Prometheus exporter;验收标准
InfoCmd中所有会冒充真实状态的硬编码字段;InfoCmd通过注入的只读 provider 获取一次一致、有限的状态快照;server、clients、stats、persistence、replication/cluster、keyspace首批 section 使用真实数据;INFO字段和 Kiwi 扩展字段有用户文档。