Codex SQLite反馈日志每年可写入约640 TB并迅速消耗固态硬盘的耐用性

Codex不断将大量数据写入本地SQLite反馈日志数据库:

~/.codex/logs_2.sqlite

~/.codex/logs_2.sqlite-wal

~/.codex/logs_2.sqlite-shm

在我的机器上,大约21天的正常运行时间,主要的SSD已经写到37 TB。进程/文件级检查显示Codex SQLite日志是主要的连续写入程序。

这大概可以推断出640 TB/年。在一个1 TB固态硬盘,那是关于每年640次全驱动器写入。一些消费级固态硬盘的评级约为600号,因此这可能会在不到一年的时间内消耗掉一个完整驱动器的保证写入耐久性。

证据

当前保留的行数logs_2.sqlite:

公制的 价值

保留的行 681,774

估计保留的日志内容 1035.6兆字节

等级分布:

水平 估计MiB 字节%

找到;查出 732.5 70.7%

信息 266.5 25.7%

调试 30.6 3.0%

警告 5.9 0.6%

最大目标+级别对:

目标 水平 估计MiB

codex_api::endpoint::responses_websocket 找到;查出 527.4

codex_otel.log_only 信息 141.2

codex_otel.trace_safe 信息 121.2

log 找到;查出 97.4

codex_client::transport 找到;查出 60.1

codex_core::stream_events_utils 调试 27.5

codex_api::sse::responses 找到;查出 19.1

主要来源是全局跟踪日志、镜像遥测日志和原始websocket/SSE有效负载日志。TRACE孤独是关于70.7%保留字节数。codex_otel.log_only + codex_otel.trace_safe添加另一个25.3%。过滤这些类别应大致移除96%在不完全禁用反馈日志的情况下。

来自最频繁跟踪源的净化示例:target=log

来自频繁信息源的净化示例

写放大

保留的数据库大小隐藏了真实的写卷。在15秒的样本中:

公制的 以前 在...之后

保留的行 681,774 681,774

最大行id 5,003,347,015 5,003,383,226

关于15秒内插入了36,211行,而保留的行数保持不变。这意味着连续的插入-删除写放大:行被插入、索引、写入WAL,然后被删除。

可能的原因

SQLite反馈日志接收器安装有全局跟踪默认值:

Targets::new().with_default(Level::TRACE)

默认情况下,这会在跟踪级别保存所有目标,包括依赖/内部日志和大型原始协议有效负载。

建议的修复

保持启用反馈日志,但缩小默认情况下保留的内容:

不要对SQLite反馈日志接收器使用全局跟踪。

降低或提高低值相关性噪声的阈值,www.ycsjb.com尤其是target=log, hyper_util、tokio-钨酸盐内部、inotify垃圾邮件和低级OpenTelemetry SDK日志。

默认情况下,避免持久保存完整的原始websocket/SSE有效负载。而是存储摘要:事件种类、持续时间、成功/错误、令牌使用和有效负载字节长度。

避免持续镜像codex_otel.log_only / codex_otel.trace_safe事件,除非它们对反馈调试明显有用。

添加全局日志数据库大小/写入上限。当存在许多线程/进程时,每个线程的上限是不够的。

可选的逃生出口,例如sqlite_logs_enabled = false仍然有用,但是主要的修正应该是更好的默认过滤。