一台机器跑到半夜磁盘告警第一反应是查谁在写大文件翻下去发现是rustfs.log一个文件占了十几 G。这种事在没配日志目录的部署上很常见。RustFS 的日志行为由可观测性那一组环境变量管。轮转时间、保留份数、总大小预算这三个默认值单独看都合理合在一起却会互相影响这也是日志目录最容易悄悄涨满的原因。只是真涨满的时候往往不是这三条规则漏了。日志往哪儿走主要看目录变量怎么填RUSTFS_OBS_LOG_DIRECTORY是决定性的那个。它的默认值是未设置文档写明未设置时日志走 stdout如果给它一个 URL 值日志会发到远端端点给一个普通路径日志就落到本地磁盘。配套的几个是RUSTFS_OBS_LOG_FILENAME默认值rustfs.log决定落在目录下的文件名RUSTFS_OBS_LOGGER_LEVEL默认值未设置是日志级别的过滤器取值如info、debugRUSTFS_OBS_LOGS_EXPORT_ENABLED默认true控制是否把日志导出到 OTLP 端点。这几项是并行的不是互斥的。日志可以既写本地文件、又导出到 OTLP也可以只走 stdout。三种组合里最容易踩的是最后一种谁都没配日志全在 stdout 里容器重启之后就找不回来了。跑在容器里的时候问题不大因为平台会把 stdout 收走跑在裸机 systemd 上就没这个兜底了。目录的读写权限是这一节里最容易漏的一项。RUSTFS_OBS_LOG_DIRECTORY指向的目录运行 RustFS 的那个用户必须能写。容器里是 uid 10001裸机部署要看 systemd 单元里写的是哪个用户。权限不对的时候症状很安静日志写不进去服务照常响应请求读写成功率一片正常只有日志文件的修改时间不再往前走。RustFS 的文件日志走非阻塞写入写失败不会卡住业务线程所以不会有报错堆到应用层想发现它得主动看目录。轮转时间有三档默认按小时切RUSTFS_OBS_LOG_ROTATION_TIME的默认值是hourly可选daily、hourly、minutely三个值。这个默认值偏激进一台访问量正常的机器按小时切出来的日志量也不小一个月攒下来几十个文件很正常。把它设成minutely只在一种情况下有意义日志量小到按分钟才攒出几 KB需要精确的时间定位。生产环境按分钟轮转的常见问题在文件数上清理规则里的份数先到导致只保留了不到一天的内容真要回溯三天前的故障时才发现中间那段被截掉了。要缩短时间粒度顺手把保留份数按倍数抬上去两个值要一起算。还有一层风险更隐蔽它跟文件大小无关只跟文件个数有关inode。按分钟轮转一天就是 1440 个文件每个压缩后可能只有几十 KB加起来远远不到 2 GiB但目录里已经多了上千个条目。inode 是文件系统一级的固定配额磁盘剩一半也照样可能建不出新文件而容量告警在这个场景下完全不会响日志那边却已经开始丢。开minutely之前先df -i看一眼余量比等它真把文件数耗光了再去调保留份数省事。顺带说清两个默认值背后的时间窗。RUSTFS_OBS_LOG_MIN_FILE_AGE_SECONDS是3600意思是文件要满一小时才进入清理的视野RUSTFS_OBS_LOG_CLEANUP_INTERVAL_SECONDS是1800清理任务半小时才扫一次。这两个数字叠起来解释了为什么新部署的机器上日志会先攒一阵子才开始被回收也解释了为什么磁盘占用曲线是台阶状而不是平滑下降。判断保留策略是否生效要按小时看不要按分钟。按天轮转还容易忽略一件事轮转靠时间触发文件大小取决于这一段时间内的访问量业务高峰月的日志可能比平时大几倍。所以总大小预算是兜底份数规则才是常规约束。保留 30 个文件还有一条 2 GiB 的线RUSTFS_OBS_LOG_KEEP_FILES默认30含义是保留 30 个轮转后的文件。这条规则管的是「份数」。RUSTFS_OBS_LOG_MAX_TOTAL_SIZE_BYTES默认2147483648也就是 2 GiB文档对它的描述是清理前的日志目录总大小预算。这条规则管的是总量但它统计的范围比「目录里所有文件加起来」要窄当前正在写的那个活跃文件不计入。这跟清理任务的工作方式有关。它每隔一段时间扫一遍日志目录找的是已经不再活跃的文件压缩、按份数截断、按总量截断都发生在这批归档文件身上正在写的那一个从头到尾不参与。所以 2 GiB 约束的是历史文件跟目录当前实际占用是两码事。真正的上限要看另一个变量RUSTFS_OBS_LOG_MAX_SINGLE_FILE_SIZE_BYTES默认值0也就是不设限。活跃文件能长到多大只看日志级别和访问量这两条预算都管不到。开篇那个十几 G 的rustfs.log两条规则都拦不住它。想盯活跃文件只有一条现成的指标rustfs_log_cleaner_active_file_size_bytes。它采样的是当前那个文件的大小判断预算够不够、清理有没有跟上看它比拿磁盘总占用倒推要准。两条规则同时起作用实际效果是两者哪个先到算哪个。文件数量先到就按份数截断总大小先到就按大小截断。把轮转时间设成minutely而保留份数仍是 30一天就是 720 个文件磁盘还没到 2 GiB 但 inode 已经很紧张了反过来把保留份数调到 300 而轮转是daily文件数永远到不了 300最后起作用的一定是 2 GiB 那条线。RUSTFS_OBS_LOG_DIRECTORY/var/log/rustfs/ RUSTFS_OBS_LOG_ROTATION_TIMEdaily RUSTFS_OBS_LOG_KEEP_FILES14 RUSTFS_OBS_LOG_MAX_TOTAL_SIZE_BYTES1073741824 RUSTFS_OBS_LOGGER_LEVELinfo给这条路留预算的时候这一块要单独算。系统盘和数据盘分开的部署日志目录放在系统盘上给它 1 到 2 GiB 完全不影响数据面。日志目录和数据卷放在同一块盘上则更麻烦因为日志涨满的时机往往正好是业务最需要写进去的时候。故障期间重试、超时、连接拒绝会连着刷出大量错误日志日志在这一刻翻倍盘也在这同一刻被打满对象写入跟着失败失败又继续产出日志。走这条路的部署除了把 2 GiB 算进容量规划最好再往数据面留出一截能扛住日志尖峰的余量不然这三件事会挤在一起发生。压缩默认开着算法可换RUSTFS_OBS_LOG_COMPRESS_OLD_FILES默认true即轮转之后的文件会被压缩文档写明默认算法是zstd可以通过RUSTFS_OBS_LOG_COMPRESSION_ALGORITHM换掉。压缩能省多少取决于日志内容。结构化 JSON 日志压缩比通常在 5 到 10 倍之间这直接影响上面那条 2 GiB 预算的实际含义预算约束的是压缩后的体积所以开着压缩时2 GiB 的归档对应的是 20 GiB 上下的原始文本。反过来如果关掉压缩去省 CPU同样预算能留下的原始日志量就只有十分之一。这里有个排查上的实际用处。线上出问题需要回溯几小时前的日志时先确认压缩是开着的再按文件名定位不要以为文件不存在是日志被清掉了。同时留一份到 stdout 的使用场景RUSTFS_OBS_LOG_STDOUT_ENABLED默认值未设置文档的说法是当文件日志或 OTLP 日志处于激活状态时额外把日志镜像一份到 stdout。它在容器化部署里比较顺手日志以文件形式落在挂载的目录里便于持久化同时镜像到 stdout 让平台的日志采集器能直接收走不用额外配一个文件 tail。RUSTFS_OBS_USE_STDOUT是另一个开关默认值未设置作用是强制遥测输出走 stdout。两个名字接近作用范围不同一起写之前先确认自己要的是「镜像」还是「强制」设错了会出现日志只出现在一处、排查时以为没日志的情况。至于导出端RUSTFS_OBS_ENDPOINT是 traces、metrics、logs 三者的根地址文档给的例子是http://otel-collector:4318不设的话日志走 stdout 或本地文件。另有RUSTFS_OBS_TRACE_ENDPOINT、RUSTFS_OBS_METRIC_ENDPOINT、RUSTFS_OBS_LOG_ENDPOINT三个按信号覆盖的入口想只把日志送到一处、其余两路走默认时用它。指标采集间隔是另外一组变量日志归日志指标有独立的间隔配置。文档给出的命名规律是RUSTFS_METRICS_SCOPE_INTERVAL_SEC作用域包括DEFAULT、SYSTEM、CLUSTER、BUCKET、NODE、RESOURCE、AUDIT、NOTIFICATION和BUCKET_REPLICATION_BANDWIDTH例子中RUSTFS_METRICS_CLUSTER_INTERVAL_SEC60就是让集群指标的导出间隔变成 60 秒。指标这一组和日志是分开的它不跟随上面任何一条轮转配置改日志预算不会影响指标上报的频率反之亦然。排查「指标点太密 / 太稀」时往这一组里找排查「日志目录涨得快」时往轮转那五个变量里找两边不要混着试。本地文件完好不代表远端没丢OTLP 那侧的失败模型和审计日志不是一套别混着看。审计日志有个显式的磁盘队列开关形如RUSTFS_AUDIT_WEBHOOK_QUEUE_DIR_PRIMARY配了目录待投递的记录就先落到磁盘收集端恢复之后能接着重放不配的话这个目标会直接标成不启用重放。普通业务日志走的是 OTLP 导出器没有对应的落盘选项网络抖动或端点不可达时待发的那批日志只在进程内存里排队。这个区别在实际运维里的后果是OTLP 收集端停服的那段时间本地日志文件可能一个不少地按轮转规则留存远端那条时间线上却缺了一段。事后翻日志系统发现某一小时整段没有数据而磁盘上文件都在很容易往收集端的存储上怀疑。判断依据要分开建本地那侧看文件的修改时间和归档连续性远端那侧看到达量两边谁也替不了谁。内存队列还有一层含义进程一重启没发出去的那批跟着内存一起没了。调整日志级别、改端点配置之后重启服务不要假设远端能补上这一段。最后回到开关本身。RUSTFS_OBS_LOGS_EXPORT_ENABLED默认true导出到端点的日志在网络抖动时会自动重试本地文件仍然按轮转规则保留两者互不影响。想只留一份就用RUSTFS_OBS_LOG_DIRECTORY留空想两边都留就把RUSTFS_OBS_LOG_STDOUT_ENABLED打开。收尾前要过一遍的几件事检查项说明RUSTFS_OBS_LOG_DIRECTORY是否设置未设置时日志只走 stdout重启即丢日志目录的属主与权限运行用户写不进去时服务不报错只是日志静默不涨日志目录所在磁盘是否和数据卷分开是否留出日志尖峰的余量轮转时长与保留份数的组合两者哪一个先触发决定了实际上限文件系统的 inode 余量轮转粒度细的时候容量够不代表还能建文件是否需要镜像到 stdout容器化部署时避免采集器收不到日志把这几条过一遍日志这块基本不会在半夜给你制造惊喜。RustFS 的默认值对开发和小规模部署是合适的问题只出在没人看过它们。排查的时候还有一个开关值得试试。RUSTFS_OBS_LOG_DRY_RUN打开之后清理任务会把要删哪些文件、能腾出多少空间报出来但不真的删。拿它验证一遍保留策略是否符合预期比等磁盘真的满一次要早得多。还有一条顺序问题容易被跳过改了RUSTFS_OBS_*之后要完整重启服务才生效环境变量不会热加载。重启之后再用curl -fsS http://node:9000/health/ready确认节点回到就绪状态。多节点部署上按滚动方式重启各节点的日志目录如果落在不同大小的磁盘上总预算的实际效果会有差异逐个核对比一次全停更稳。还有一条实践上的看法日志量大的集群真正需要保留的是检索能力而不是原始文件。接进 OTLP 之后短期原始日志可以压到 3 到 5 天需要长期留存的部分放进检索系统。这样RUSTFS_OBS_LOG_KEEP_FILES可以调小2 GiB 的预算压力也随之下降而日志检索能力并不损失。日志级别也顺带说一下。RUSTFS_OBS_LOGGER_LEVEL默认未设置提到debug之后日志量常常涨一个数量级2 GiB 预算会在几天内被打满。排查问题时临时调高问题解决后调回来比长期开着更划算。