Files
rustfs/.agents/skills/rustfs-logging-governance/SKILL.md
T
Zhengchao An 96d24bc006 docs(agents): make the structured-logging rule reachable and enforceable (#5828)
The RustFS event shape (`event`/`component`/`subsystem`/`result` + context,
message last) is specified only in
`.agents/skills/rustfs-logging-governance/SKILL.md`, and nothing routes a
change to it:

- `AGENTS.md`, which is what an agent actually loads by default, never
  mentions logging. Its only related line is "log unknown fields at `warn`"
  under Serde Safety, which is about level, not shape.
- The skill's `description` says "use when editing or reviewing RustFS logs",
  so a bugfix that adds one log line in passing — how most new log sites enter
  this repo — never matches it.
- `scripts/check_logging_guardrails.sh` is a blocklist: 500+ `rg -F` literals
  that retire log lines which already shipped. It cannot see a newly written
  one. For `crates/ecstore/src/disk/local.rs` the only check is that
  `#[tracing::instrument]` is TRACE-only; `warn!`/`info!` shape is unchecked.

PR #5822 landed `warn!("heal rename_data: purging ... {:?} failed: {}", ...)`
in `disk/local.rs` — sentence-style, no fields, directly beside `info!(event =
EVENT_DISK_LOCAL_RENAME_REJECTED, component = ..., subsystem = ...)` — with
every check green. That is the gap, not an authoring mistake.

Close all three:

- `AGENTS.md`: a Logging section stating the field shape, the level policy,
  the reuse-the-file's-constants rule, and that it applies to any `tracing`
  macro added in passing, not only to log-focused changes.
- Skill `description`: trigger on adding or editing any `tracing` macro,
  naming the single-line-added-in-passing case explicitly.
- Guardrail: assert the event shape positively on the already-governed disk
  files — `error!`/`warn!`/`info!` must open with fields or a `target:`, never
  a bare string. Commented-out macros are excluded; `debug!`/`trace!` stay out
  of scope as targeted diagnostics. Self-test fixtures cover both directions.

`crates/ecstore/src/disk/mod.rs` carried the one live violation in that file
set (`conv_part_err_to_int`), so it is converted here; the guardrail would
otherwise fail on an untouched file.

Verification:
- `./scripts/check_logging_guardrails.sh` — passes
- Negative control: re-inserting PR #5822's exact `warn!` line into
  `disk/local.rs` makes it exit 1 pointing at that line
- `cargo fmt -p rustfs-ecstore -- --check`, `cargo check -p rustfs-ecstore`
2026-08-07 23:05:57 +00:00

4.4 KiB

name, description
name description
rustfs-logging-governance Standardize and review RustFS logging with structured `tracing` events, lower noise on hot paths, preserve security-sensitive diagnostics, and extend guardrails to prevent legacy logging patterns from returning. Use whenever a change adds or edits any `tracing` macro call (`error!`/`warn!`/`info!`/`debug!`/`trace!`/`#[instrument]`) — including a single log line added in passing while fixing unrelated logic, which is how most new log sites enter the repo — and when reviewing RustFS logs, startup/config diagnostics, cloud metadata logs, request validation logs, or `scripts/check_logging_guardrails.sh`.

RustFS Logging Governance

Use this skill when RustFS logging needs to be added, cleaned up, reviewed, or protected against regressions.

Quick Start

  1. Identify the files whose logs are changing.
  2. Scan current tracing or log macros before editing.
  3. Convert sentence-style logs to short event-style logs.
  4. Demote hot-path success logs unless operators truly need them at info.
  5. Preserve failure, fallback, and security-relevant diagnostics.
  6. Update scripts/check_logging_guardrails.sh when a broad cleanup removes a legacy pattern class.
  7. Validate with formatting, targeted checks/tests, and the logging guardrail script.

Core Workflow

1. Scope the logging surface

  • Read the changed module in full before touching log lines.
  • Classify the log site:
    • lifecycle/startup
    • request or validation path
    • background loop or hot path
    • fallback/degraded behavior
    • cloud metadata or external fetch path
    • metrics/config summary
  • Do not rewrite business logic to make logging easier.

2. Use the RustFS event shape

  • Prefer fields first, message second.
  • Use short labels, not prose paragraphs.
  • Default field shape:
    • event
    • component
    • subsystem
    • state or result
    • key context fields
  • Reuse stable field names and avoid inventing near-duplicates.

See references/logging-governance.md for the event model, level policy, and anti-pattern list.

3. Choose the right level

  • error: operation failure that affects behavior or security guarantees.
  • warn: degraded path, fallback, suspicious input, or operator-actionable misconfiguration.
  • info: low-frequency lifecycle or mode selection.
  • debug: targeted diagnostics and low-volume detail.
  • trace: hot-path and repetitive success-path events.

When in doubt, lower the verbosity of normal success paths and keep structured detail in fields.

4. Preserve security and privacy boundaries

  • Do not log secrets, tokens, auth headers, raw credential payloads, or merged config dumps.
  • Avoid logging raw forwarded headers or full trusted network inventories above debug.
  • Keep warning/error logs useful without echoing attacker-controlled payloads unnecessarily.

5. Keep summaries aggregated

  • Replace multi-line startup banners or checklist logs with one structured event.
  • If metrics already express a concept, avoid duplicating it with many info! lines.
  • Prefer counts, modes, and sources over inventories unless debug detail is truly needed.

6. Update guardrails when needed

  • Broad logging cleanup should usually extend scripts/check_logging_guardrails.sh.
  • Add forbidden patterns only for styles the repo has intentionally retired:
    • sentence-style lifecycle logs
    • noisy hot-path info!
    • checklist-style summary logs
    • legacy fallback wording that has been replaced by structured fields
  • Keep guardrails concrete and grep-friendly.

7. Validate manually

Use the smallest relevant set:

cargo fmt --all --check
./scripts/check_logging_guardrails.sh
cargo check -p <affected-crate>
cargo test -p <affected-crate>

For broader Rust changes, add:

./scripts/check_unsafe_code_allowances.sh
./scripts/check_architecture_migration_rules.sh
cargo clippy -p <affected-crates> --all-targets -- -D warnings

RustFS-Specific Notes

  • The durable RustFS logging direction is event + component + subsystem + state/result + key context fields.
  • crates/concurrency and crates/trusted-proxies are examples of this style for lifecycle, fallback, and cloud metadata logs.
  • scripts/check_logging_guardrails.sh is the enforcement point for preventing removed log styles from returning.

References

  • Read references/logging-governance.md when you need the detailed field set, anti-pattern examples, or guardrail update checklist.