Skip to content

feat(instrument): give instrumented events stable event_name identities#3581

Open
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3576
Open

feat(instrument): give instrumented events stable event_name identities#3581
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3576

Conversation

@chet

@chet chet commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What this does

This gives every carbide_instrument::Event a stable semantic event_name, separate from its optional Prometheus metric_name. When a typed Event logs, those identities now show up as structured fields, and the tracing metadata name uses the same event_name.

Big picture: this starts establishing common, stable identities we can use for searchability, docs, and future schemas instead of inferring identity from messages or Rust type names.

  • migrates all 59 production Events to reviewed, globally unique event_name values
  • preserves the existing Prometheus names, labels, counts, and histogram units
  • adds a dependency-free observability schema crate for the event-name grammar and reserved Event-log fields
  • rejects reserved-field collisions in the derive without breaking metric-only legacy labels
  • adds cargo xtask check-event-names to pre-commit and CI so duplicate or invalid production identities fail closed
  • keeps human-readable messages required for log-enabled Events while allowing metric-only Events to remain silent
  • documents how event_name, metric_name, messages, plain tracing, and metric cardinality fit together

Verification

  • cargo make format-nightly
  • cargo make check-format-nightly
  • cargo make clippy
  • cargo make carbide-lints
  • cargo make check-workspace-deps
  • cargo make check-event-names
  • cargo test -p carbide-instrument -p carbide-observability-schema -p xtask -p carbide-dsx-exchange-consumer --all-features
  • focused DHCP and MQTT exporter tests for grandfathered metric-name compatibility
  • post-rebase CodeRabbit local review: no findings
  • post-rebase independent Claude review: no correctness or merge blockers

This supports #3576

@chet chet requested review from a team, lauragra-y and polarweasel as code owners July 15, 2026 21:14

chet commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@chet, you're welcome! I'll perform a full review of all changes in this PR now.

🐇✨

✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added stable, unique event identities separate from Prometheus metric names.
    • Event logs now include structured event_name and, when applicable, metric_name fields.
    • Added validation for event naming, reserved log fields, metric formats, and duplicate production event names.
  • Documentation

    • Updated instrumentation and logging guidance with the new naming rules and examples.
  • Bug Fixes

    • Improved compile-time diagnostics for invalid or legacy event metadata.

Walkthrough

This PR separates stable event_name identities from metric_name, adds compile-time and production uniqueness validation, migrates instrumented events, updates logging and metric APIs, expands tests and documentation, and integrates validation into CI and pre-commit checks.

Changes

Stable Event identity

Layer / File(s) Summary
Identity contract and macro generation
crates/observability-schema/*, crates/instrument-macros/*, crates/instrument/src/*
Adds shared name validation, reserved-field rules, explicit Event identity constants, metric-name handling, and generated log fields.
Production event-name checker
crates/xtask/*
Adds cargo xtask check-event-names to scan production targets, resolve modules and conditional declarations, validate identities, and report duplicates or unsupported patterns.
Production declaration migration
crates/api-core/*, crates/authn/*, crates/bmc-proxy/*, crates/dhcp*/*, crates/dns/*, crates/health/*, crates/mqtt*/*, crates/preingestion-manager/*, crates/secrets/*, crates/scout/*, crates/*/metrics.rs
Updates production Event declarations from legacy name forms to explicit event_name and metric_name metadata.
Identity capture and behavioral validation
crates/instrument/src/testing.rs, crates/instrument/tests/matrix.rs, crates/instrument-macros/src/lib.rs
Adds captured metadata and field helpers, updates matrix assertions, validates metric-only behavior, and tests logfmt identity rendering and diagnostics.
Workflow integration and guidance
.github/workflows/*, Makefile.toml, AGENTS.md, STYLE_GUIDE.md, docs/observability/*
Adds CI and pre-commit enforcement and documents event naming, metric naming, reserved fields, and emitted log identity fields.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: assigning stable event_name identities to instrumented events.
Description check ✅ Passed The description is directly aligned with the changeset and accurately describes the event_name and instrumentation work.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

chet commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@chet, you're welcome! I'll perform a full review of all changes in this PR again.

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
crates/api-core/src/listener.rs (1)

174-175: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent event_name prefixing across sibling TLS events.

TlsConnectionAttempted, TlsConnectionSucceeded, and TlsConnectionFailed all use the api_tls_connection_* prefix, but TlsCertsRefreshed (Line 174) is named just tls_certs_refreshed without the api_ prefix. Since these events all live in the same listener module and represent the same TLS subsystem, consider aligning TlsCertsRefreshed to api_tls_certs_refreshed for consistency.

✏️ Suggested fix
-    event_name = "tls_certs_refreshed",
+    event_name = "api_tls_certs_refreshed",

Also applies to: 188-189, 201-202, 231-232

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-core/src/listener.rs` around lines 174 - 175, Align the
`event_name` values for `TlsCertsRefreshed` and the other affected sibling TLS
events with the module’s `api_tls_*` prefix convention, while leaving their
`metric_name` values unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/xtask/src/event_names.rs`:
- Around line 887-893: Update cfg_truth to recognize the doctest path alongside
test, doc, and docsrs, returning Truth::False so doctest-only declarations are
excluded from production event scanning.
- Around line 717-738: Update has_production_possible_derive to recursively
inspect nested cfg_attr metadata after confirming each condition is not false,
while preserving direct derive detection and ignoring disabled branches. Add a
regression test covering nested cfg_attr conditions that eventually contain
derive(Event), ensuring the declaration reaches the uniqueness scan.

In `@docs/observability/instrumentation.md`:
- Around line 228-231: In the explanatory paragraph about the Prometheus
exporter and metric_name, replace “the two cancel out to exactly the attribute
string” with wording that uses “cancel” without “out,” preserving the existing
meaning and documentation content.

---

Nitpick comments:
In `@crates/api-core/src/listener.rs`:
- Around line 174-175: Align the `event_name` values for `TlsCertsRefreshed` and
the other affected sibling TLS events with the module’s `api_tls_*` prefix
convention, while leaving their `metric_name` values unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: cffd9af7-604a-4dd5-aa2e-549b77e34898

📥 Commits

Reviewing files that changed from the base of the PR and between 4468fbb and 124d4e2.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/workflows/ci.yaml
  • AGENTS.md
  • Makefile.toml
  • STYLE_GUIDE.md
  • crates/api-core/src/attestation/measured_boot.rs
  • crates/api-core/src/auth/middleware.rs
  • crates/api-core/src/handlers/utils.rs
  • crates/api-core/src/listener.rs
  • crates/api-core/src/machine_update_manager/metrics.rs
  • crates/api-core/src/machine_validation/mod.rs
  • crates/api-core/src/measured_boot/metrics_collector/mod.rs
  • crates/api-core/src/secrets/metrics.rs
  • crates/authn/src/middleware.rs
  • crates/bmc-proxy/src/bmc_proxy.rs
  • crates/bmc-proxy/src/metrics.rs
  • crates/certs/src/cert_renewal.rs
  • crates/dhcp-server/src/metrics.rs
  • crates/dhcp/src/metrics.rs
  • crates/dns/src/lib.rs
  • crates/dsx-exchange-consumer/src/metrics.rs
  • crates/firmware/src/downloader.rs
  • crates/health/src/otlp/mod.rs
  • crates/health/src/sink/mod.rs
  • crates/instrument-macros/Cargo.toml
  • crates/instrument-macros/src/lib.rs
  • crates/instrument/Cargo.toml
  • crates/instrument/src/lib.rs
  • crates/instrument/src/testing.rs
  • crates/instrument/tests/matrix.rs
  • crates/ipmi/src/metrics.rs
  • crates/machine-controller/src/handler.rs
  • crates/mqtt-common/src/metrics.rs
  • crates/mqttea/src/client/core.rs
  • crates/observability-schema/Cargo.toml
  • crates/observability-schema/src/lib.rs
  • crates/preingestion-manager/src/metrics.rs
  • crates/pxe/src/metrics.rs
  • crates/scout/src/metrics.rs
  • crates/secrets/src/forge_vault.rs
  • crates/site-explorer/src/bmc_endpoint_explorer.rs
  • crates/utils/src/managed_loop.rs
  • crates/xtask/Cargo.toml
  • crates/xtask/src/event_names.rs
  • crates/xtask/src/main.rs
  • docs/observability/instrumentation.md

Comment thread crates/xtask/src/event_names.rs Outdated
Comment thread crates/xtask/src/event_names.rs
Comment thread docs/observability/instrumentation.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/xtask/src/event_names.rs`:
- Around line 100-104: Update the TargetRoot construction in the target mapping
to convert target.src_path from camino::Utf8PathBuf into the expected
std::path::PathBuf, using an explicit conversion such as into_std_path_buf or
into while preserving the existing cloned path value.
- Around line 573-613: Update NestedItemVisitor’s expression and match-arm
traversal to check cfg_is_production_possible before recursing into
attribute-gated subtrees, preventing inactive nested Events from being scanned;
preserve traversal for production-possible nodes and add a regression test
proving #[cfg(test)] nested Events are ignored without duplicate-name
diagnostics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 46ca98e4-e243-4667-afa0-28d6ac5cb230

📥 Commits

Reviewing files that changed from the base of the PR and between 4468fbb and 124d4e2.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/workflows/ci.yaml
  • AGENTS.md
  • Makefile.toml
  • STYLE_GUIDE.md
  • crates/api-core/src/attestation/measured_boot.rs
  • crates/api-core/src/auth/middleware.rs
  • crates/api-core/src/handlers/utils.rs
  • crates/api-core/src/listener.rs
  • crates/api-core/src/machine_update_manager/metrics.rs
  • crates/api-core/src/machine_validation/mod.rs
  • crates/api-core/src/measured_boot/metrics_collector/mod.rs
  • crates/api-core/src/secrets/metrics.rs
  • crates/authn/src/middleware.rs
  • crates/bmc-proxy/src/bmc_proxy.rs
  • crates/bmc-proxy/src/metrics.rs
  • crates/certs/src/cert_renewal.rs
  • crates/dhcp-server/src/metrics.rs
  • crates/dhcp/src/metrics.rs
  • crates/dns/src/lib.rs
  • crates/dsx-exchange-consumer/src/metrics.rs
  • crates/firmware/src/downloader.rs
  • crates/health/src/otlp/mod.rs
  • crates/health/src/sink/mod.rs
  • crates/instrument-macros/Cargo.toml
  • crates/instrument-macros/src/lib.rs
  • crates/instrument/Cargo.toml
  • crates/instrument/src/lib.rs
  • crates/instrument/src/testing.rs
  • crates/instrument/tests/matrix.rs
  • crates/ipmi/src/metrics.rs
  • crates/machine-controller/src/handler.rs
  • crates/mqtt-common/src/metrics.rs
  • crates/mqttea/src/client/core.rs
  • crates/observability-schema/Cargo.toml
  • crates/observability-schema/src/lib.rs
  • crates/preingestion-manager/src/metrics.rs
  • crates/pxe/src/metrics.rs
  • crates/scout/src/metrics.rs
  • crates/secrets/src/forge_vault.rs
  • crates/site-explorer/src/bmc_endpoint_explorer.rs
  • crates/utils/src/managed_loop.rs
  • crates/xtask/Cargo.toml
  • crates/xtask/src/event_names.rs
  • crates/xtask/src/main.rs
  • docs/observability/instrumentation.md

Comment thread crates/xtask/src/event_names.rs
Comment thread crates/xtask/src/event_names.rs
@github-actions

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 259 16 29 79 7 128
machine-validation-runner 532 39 113 184 15 181
machine_validation 532 39 113 184 15 181
machine_validation-aarch64 532 39 113 184 15 181
nvmetal-carbide 532 39 113 184 15 181
TOTAL 2393 172 481 821 67 852

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

chet commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@chet, you're welcome! I'll perform a full review of all changes in this PR again.

(๑˃̵ᴗ˂̵)ノ✨🐇

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/observability/instrumentation.md (1)

184-192: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align both metric-backed examples with the describe contract.

Both examples declare metrics but omit describe, contradicting the documentation’s requirement that every metric provide HELP/catalogue text.

  • docs/observability/instrumentation.md#L184-L192: add a histogram description such as describe = "BFB copy duration.".
  • AGENTS.md#L185-L187: add describe = "Power control has failed.".

As per path instructions, Markdown examples must be technically correct and realistic.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/observability/instrumentation.md` around lines 184 - 192, Update the
metric-backed examples to include required HELP text via the derive attribute’s
describe field: in docs/observability/instrumentation.md lines 184-192, add a
histogram description such as “BFB copy duration.” to the bfb_copy_finished
event; in AGENTS.md lines 185-187, add “Power control has failed.” to the
corresponding power-control metric example.

Source: Path instructions

crates/instrument-macros/src/lib.rs (1)

394-403: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject conflicting units on unchecked histograms.

With metric_name_unchecked, a _seconds name plus unit = "ms" is accepted, and the explicit unit wins. Duration observations are then recorded in milliseconds under a metric named as seconds.

Proposed fix
+    if let (Some(explicit), Some(from_suffix)) = (&args.unit, histogram_unit)
+        && explicit.value() != from_suffix
+    {
+        return Err(syn::Error::new_spanned(
+            explicit,
+            "explicit unit conflicts with the metric_name suffix",
+        ));
+    }
     let unit_value: String = match (&args.unit, histogram_unit) {

Add a regression case covering the conflicting declaration. As per coding guidelines, histogram metric names must carry their units and existing metric names must not change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/instrument-macros/src/lib.rs` around lines 394 - 403, Update the
histogram unit validation around unit_value so metric_name_unchecked rejects an
explicit unit that conflicts with a recognized unit suffix, rather than letting
the explicit unit override it. Preserve accepted matching declarations and
existing metric names, and add a regression case covering a suffixed histogram
such as _seconds with a conflicting explicit unit such as ms.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/instrument-macros/src/lib.rs`:
- Around line 394-403: Update the histogram unit validation around unit_value so
metric_name_unchecked rejects an explicit unit that conflicts with a recognized
unit suffix, rather than letting the explicit unit override it. Preserve
accepted matching declarations and existing metric names, and add a regression
case covering a suffixed histogram such as _seconds with a conflicting explicit
unit such as ms.

In `@docs/observability/instrumentation.md`:
- Around line 184-192: Update the metric-backed examples to include required
HELP text via the derive attribute’s describe field: in
docs/observability/instrumentation.md lines 184-192, add a histogram description
such as “BFB copy duration.” to the bfb_copy_finished event; in AGENTS.md lines
185-187, add “Power control has failed.” to the corresponding power-control
metric example.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: df34b54b-bb30-43ae-a233-061a91838d53

📥 Commits

Reviewing files that changed from the base of the PR and between 7f74a07 and 8946a92.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/workflows/ci.yaml
  • AGENTS.md
  • Makefile.toml
  • STYLE_GUIDE.md
  • crates/api-core/src/attestation/measured_boot.rs
  • crates/api-core/src/auth/middleware.rs
  • crates/api-core/src/handlers/utils.rs
  • crates/api-core/src/listener.rs
  • crates/api-core/src/machine_update_manager/metrics.rs
  • crates/api-core/src/machine_validation/mod.rs
  • crates/api-core/src/measured_boot/metrics_collector/mod.rs
  • crates/api-core/src/secrets/metrics.rs
  • crates/authn/src/middleware.rs
  • crates/bmc-proxy/src/bmc_proxy.rs
  • crates/bmc-proxy/src/metrics.rs
  • crates/certs/src/cert_renewal.rs
  • crates/dhcp-server/src/metrics.rs
  • crates/dhcp/src/metrics.rs
  • crates/dns/src/lib.rs
  • crates/dsx-exchange-consumer/src/metrics.rs
  • crates/firmware/src/downloader.rs
  • crates/health/src/otlp/mod.rs
  • crates/health/src/sink/mod.rs
  • crates/instrument-macros/Cargo.toml
  • crates/instrument-macros/src/lib.rs
  • crates/instrument/Cargo.toml
  • crates/instrument/src/lib.rs
  • crates/instrument/src/testing.rs
  • crates/instrument/tests/matrix.rs
  • crates/ipmi/src/metrics.rs
  • crates/machine-controller/src/handler.rs
  • crates/mqtt-common/src/metrics.rs
  • crates/mqttea/src/client/core.rs
  • crates/observability-schema/Cargo.toml
  • crates/observability-schema/src/lib.rs
  • crates/preingestion-manager/src/metrics.rs
  • crates/pxe/src/metrics.rs
  • crates/scout/src/metrics.rs
  • crates/secrets/src/forge_vault.rs
  • crates/site-explorer/src/bmc_endpoint_explorer.rs
  • crates/utils/src/managed_loop.rs
  • crates/xtask/Cargo.toml
  • crates/xtask/src/event_names.rs
  • crates/xtask/src/main.rs
  • docs/observability/instrumentation.md

@poroh

poroh commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

How is connected to #3221 ? Do we need complex validation part if the generation will be implemented?

Split typed Event identity from its optional Prometheus metric name and emit both as structured fields when an Event logs.

Migrate all 59 production Events to unique semantic names, preserve existing metric contracts, and enforce the shared grammar, reserved fields, and workspace uniqueness in CI.

This supports NVIDIA#3576

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet

chet commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@chet, you're welcome! I'll perform a full review of all changes in this PR again.

🐇✨

✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/instrument/src/lib.rs (1)

351-363: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Centralize metric suffix normalization.

crates/instrument-macros/src/lib.rs already owns the histogram suffix mapping used during validation, while this runtime path duplicates it. If either mapping changes independently, an event can compile successfully but register under a name inconsistent with its declared metric_name. Move the conversion into one shared helper and cover each supported suffix with an end-to-end test.

Also applies to: 370-381

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/instrument/src/lib.rs` around lines 351 - 363, The runtime suffix
normalization in new_instrument duplicates the mapping maintained by the
instrument macros. Centralize conversion in a shared helper owned by the
macros/shared layer, reuse it for counter and histogram registration, and remove
the duplicate mapping from new_instrument. Add an end-to-end test covering every
supported suffix and verifying the registered metric name matches the declared
metric_name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/instrument/src/lib.rs`:
- Around line 351-363: The runtime suffix normalization in new_instrument
duplicates the mapping maintained by the instrument macros. Centralize
conversion in a shared helper owned by the macros/shared layer, reuse it for
counter and histogram registration, and remove the duplicate mapping from
new_instrument. Add an end-to-end test covering every supported suffix and
verifying the registered metric name matches the declared metric_name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ce053b3a-b4cf-4770-934b-a40e6aa4d334

📥 Commits

Reviewing files that changed from the base of the PR and between 8946a92 and e899806.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (41)
  • .github/workflows/ci.yaml
  • AGENTS.md
  • Makefile.toml
  • STYLE_GUIDE.md
  • crates/api-core/src/attestation/measured_boot.rs
  • crates/api-core/src/auth/middleware.rs
  • crates/api-core/src/handlers/utils.rs
  • crates/api-core/src/listener.rs
  • crates/api-core/src/machine_update_manager/metrics.rs
  • crates/api-core/src/machine_validation/mod.rs
  • crates/api-core/src/measured_boot/metrics_collector/mod.rs
  • crates/api-core/src/secrets/metrics.rs
  • crates/authn/src/middleware.rs
  • crates/bmc-proxy/src/bmc_proxy.rs
  • crates/bmc-proxy/src/metrics.rs
  • crates/certs/src/cert_renewal.rs
  • crates/dhcp-server/src/metrics.rs
  • crates/dhcp/src/metrics.rs
  • crates/dns/src/lib.rs
  • crates/dsx-exchange-consumer/src/metrics.rs
  • crates/firmware/src/downloader.rs
  • crates/health/src/otlp/mod.rs
  • crates/health/src/sink/mod.rs
  • crates/instrument-macros/Cargo.toml
  • crates/instrument-macros/src/lib.rs
  • crates/instrument/Cargo.toml
  • crates/instrument/src/lib.rs
  • crates/instrument/src/testing.rs
  • crates/instrument/tests/matrix.rs
  • crates/ipmi/src/metrics.rs
  • crates/machine-controller/src/handler.rs
  • crates/mqtt-common/src/metrics.rs
  • crates/mqttea/src/client/core.rs
  • crates/observability-schema/Cargo.toml
  • crates/observability-schema/src/lib.rs
  • crates/preingestion-manager/src/metrics.rs
  • crates/pxe/src/metrics.rs
  • crates/scout/src/metrics.rs
  • crates/secrets/src/forge_vault.rs
  • crates/site-explorer/src/bmc_endpoint_explorer.rs
  • crates/utils/src/managed_loop.rs
🚧 Files skipped from review as they are similar to previous changes (35)
  • .github/workflows/ci.yaml
  • crates/scout/src/metrics.rs
  • crates/bmc-proxy/src/metrics.rs
  • crates/site-explorer/src/bmc_endpoint_explorer.rs
  • crates/pxe/src/metrics.rs
  • crates/api-core/src/attestation/measured_boot.rs
  • crates/authn/src/middleware.rs
  • crates/api-core/src/machine_validation/mod.rs
  • crates/ipmi/src/metrics.rs
  • crates/api-core/src/auth/middleware.rs
  • crates/api-core/src/machine_update_manager/metrics.rs
  • crates/api-core/src/secrets/metrics.rs
  • crates/instrument/Cargo.toml
  • crates/api-core/src/measured_boot/metrics_collector/mod.rs
  • crates/mqttea/src/client/core.rs
  • crates/health/src/sink/mod.rs
  • crates/dhcp-server/src/metrics.rs
  • crates/preingestion-manager/src/metrics.rs
  • AGENTS.md
  • crates/mqtt-common/src/metrics.rs
  • crates/dns/src/lib.rs
  • crates/observability-schema/src/lib.rs
  • crates/instrument/src/testing.rs
  • crates/certs/src/cert_renewal.rs
  • Makefile.toml
  • crates/utils/src/managed_loop.rs
  • crates/secrets/src/forge_vault.rs
  • crates/machine-controller/src/handler.rs
  • crates/api-core/src/listener.rs
  • STYLE_GUIDE.md
  • crates/health/src/otlp/mod.rs
  • crates/bmc-proxy/src/bmc_proxy.rs
  • crates/dhcp/src/metrics.rs
  • crates/instrument/tests/matrix.rs
  • crates/instrument-macros/src/lib.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/instrument-macros/src/lib.rs`:
- Around line 157-160: Update the attribute parsing branches for event_name and
metric_name to reject a key when its corresponding args field is already
populated, rather than overwriting the earlier value. Return an appropriate
duplicate-attribute parse error and preserve the existing parsing behavior for
the first occurrence; apply this within the metadata parsing logic containing
args.event_name and args.metric_name.

In `@crates/xtask/src/event_names.rs`:
- Around line 988-1007: Update is_test_or_bench to recursively traverse nested
cfg_attr metadata, reusing the existing recursive cfg_attr traversal helper used
elsewhere instead of only checking direct arguments. Ensure nested conditions
such as cfg_attr(not(test), cfg_attr(not(doc), test)) classify the item as
test/bench, and add a regression case covering this chain.

In `@docs/observability/instrumentation.md`:
- Around line 19-22: Update the observability documentation sentence describing
#[context] fields so it states they appear only when the Event emits a log
record, rather than unconditionally appearing on a log line. Preserve the
clarification that these fields cannot become metric labels and ensure
metric-only Events with log = off are excluded.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ff882d7c-8221-47ec-90c4-9f4a766d4d3e

📥 Commits

Reviewing files that changed from the base of the PR and between 66c01b5 and e899806.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/workflows/ci.yaml
  • AGENTS.md
  • Makefile.toml
  • STYLE_GUIDE.md
  • crates/api-core/src/attestation/measured_boot.rs
  • crates/api-core/src/auth/middleware.rs
  • crates/api-core/src/handlers/utils.rs
  • crates/api-core/src/listener.rs
  • crates/api-core/src/machine_update_manager/metrics.rs
  • crates/api-core/src/machine_validation/mod.rs
  • crates/api-core/src/measured_boot/metrics_collector/mod.rs
  • crates/api-core/src/secrets/metrics.rs
  • crates/authn/src/middleware.rs
  • crates/bmc-proxy/src/bmc_proxy.rs
  • crates/bmc-proxy/src/metrics.rs
  • crates/certs/src/cert_renewal.rs
  • crates/dhcp-server/src/metrics.rs
  • crates/dhcp/src/metrics.rs
  • crates/dns/src/lib.rs
  • crates/dsx-exchange-consumer/src/metrics.rs
  • crates/firmware/src/downloader.rs
  • crates/health/src/otlp/mod.rs
  • crates/health/src/sink/mod.rs
  • crates/instrument-macros/Cargo.toml
  • crates/instrument-macros/src/lib.rs
  • crates/instrument/Cargo.toml
  • crates/instrument/src/lib.rs
  • crates/instrument/src/testing.rs
  • crates/instrument/tests/matrix.rs
  • crates/ipmi/src/metrics.rs
  • crates/machine-controller/src/handler.rs
  • crates/mqtt-common/src/metrics.rs
  • crates/mqttea/src/client/core.rs
  • crates/observability-schema/Cargo.toml
  • crates/observability-schema/src/lib.rs
  • crates/preingestion-manager/src/metrics.rs
  • crates/pxe/src/metrics.rs
  • crates/scout/src/metrics.rs
  • crates/secrets/src/forge_vault.rs
  • crates/site-explorer/src/bmc_endpoint_explorer.rs
  • crates/utils/src/managed_loop.rs
  • crates/xtask/Cargo.toml
  • crates/xtask/src/event_names.rs
  • crates/xtask/src/main.rs
  • docs/observability/instrumentation.md

Comment on lines +157 to +160
if meta.path.is_ident("event_name") {
args.event_name = Some(meta.value()?.parse()?);
} else if meta.path.is_ident("metric_name") {
args.metric_name = Some(meta.value()?.parse()?);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject duplicate identity attributes.

Repeated event_name or metric_name keys silently overwrite the earlier value, making the generated identity depend on attribute order. Reject duplicates here; the production checker already rejects duplicate event_name declarations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/instrument-macros/src/lib.rs` around lines 157 - 160, Update the
attribute parsing branches for event_name and metric_name to reject a key when
its corresponding args field is already populated, rather than overwriting the
earlier value. Return an appropriate duplicate-attribute parse error and
preserve the existing parsing behavior for the first occurrence; apply this
within the metadata parsing logic containing args.event_name and
args.metric_name.

Comment on lines +988 to +1007
fn is_test_or_bench(attrs: &[Attribute]) -> bool {
attrs.iter().any(|attr| {
if path_ends_in_test_or_bench(attr.path()) {
return true;
}
if !attr.path().is_ident("cfg_attr") {
return false;
}

let Ok(parts) = attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
else {
return false;
};
let mut parts = parts.iter();
let Some(condition) = parts.next() else {
return false;
};
cfg_truth(condition) == Truth::True
&& parts.any(|meta| path_ends_in_test_or_bench(meta.path()))
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '982,1015p' crates/xtask/src/event_names.rs
rg -n 'cfg_attr\(.*cfg_attr\(.*(test|bench)' crates/xtask/src/event_names.rs

Repository: NVIDIA/infra-controller

Length of output: 1252


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== outline =="
ast-grep outline crates/xtask/src/event_names.rs --view expanded || true

echo
echo "== relevant symbols =="
rg -n "fn (cfg_attribute_truth|cfg_truth|is_test_or_bench|cfg_is_production_possible|path_ends_in_test_or_bench)|cfg_attr" crates/xtask/src/event_names.rs

echo
echo "== tests mentioning test/bench/cfg_attr =="
rg -n "test|bench|cfg_attr|doctest|Event" crates/xtask/src/event_names.rs

Repository: NVIDIA/infra-controller

Length of output: 18986


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "cfg_attr_has_active_test_or_bench|path_ends_in_test_or_bench|cfg_attribute_truth|cfg_truth" crates/xtask/src

Repository: NVIDIA/infra-controller

Length of output: 1877


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

p = Path("crates/xtask/src/event_names.rs")
text = p.read_text()
for name in ["cfg_attribute_truth", "cfg_truth", "is_test_or_bench", "path_ends_in_test_or_bench"]:
    m = re.search(rf"fn {name}[^{{]*\{{", text)
    if m:
        start = m.start()
        print(f"\n--- {name} ---")
        # print a compact slice around the function
        print(text[start:start+1500])
PY

Repository: NVIDIA/infra-controller

Length of output: 6275


Recurse through nested cfg_attr when classifying test/bench items.
Nested chains like #[cfg_attr(not(test), cfg_attr(not(doc), test))] still fall through this check, so test-only bodies can be scanned and emit duplicate-event diagnostics. Reuse the recursive cfg_attr traversal already used elsewhere and add a regression case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/xtask/src/event_names.rs` around lines 988 - 1007, Update
is_test_or_bench to recursively traverse nested cfg_attr metadata, reusing the
existing recursive cfg_attr traversal helper used elsewhere instead of only
checking direct arguments. Ensure nested conditions such as cfg_attr(not(test),
cfg_attr(not(doc), test)) classify the item as test/bench, and add a regression
case covering this chain.

Comment on lines 19 to 22
- **Cardinality is enforced by the types.** `#[label]` fields must be bounded via
`LabelValue` -- usually a fieldless enum, with a manual impl on a bounded newtype as the
reviewed escape hatch; high-cardinality detail (`machine_id`, IPs, error text) goes in
`#[context]` fields, which appear on the log line only and *cannot* become a metric label.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clarify when #[context] fields are emitted.

This says context fields “appear on the log line only,” but log = off Events produce no log line. Specify that they appear only when the Event emits a log record, so metric-only Events are not documented as rendering those fields.

Suggested wording
-  `#[context]` fields, which appear on the log line only and *cannot* become a metric label.
+  `#[context]` fields, which appear only when the Event emits a log line and *cannot*
+  become metric labels.

As per path instructions, Markdown must be reviewed for technical correctness and clarity.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Cardinality is enforced by the types.** `#[label]` fields must be bounded via
`LabelValue` -- usually a fieldless enum, with a manual impl on a bounded newtype as the
reviewed escape hatch; high-cardinality detail (`machine_id`, IPs, error text) goes in
`#[context]` fields, which appear on the log line only and *cannot* become a metric label.
- **Cardinality is enforced by the types.** `#[label]` fields must be bounded via
`LabelValue` -- usually a fieldless enum, with a manual impl on a bounded newtype as the
reviewed escape hatch; high-cardinality detail (`machine_id`, IPs, error text) goes in
`#[context]` fields, which appear only when the Event emits a log line and *cannot*
become metric labels.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/observability/instrumentation.md` around lines 19 - 22, Update the
observability documentation sentence describing #[context] fields so it states
they appear only when the Event emits a log record, rather than unconditionally
appearing on a log line. Preserve the clarification that these fields cannot
become metric labels and ensure metric-only Events with log = off are excluded.

Source: Path instructions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants