Skip to content

feat: health nvidia oem metrics - #4730

Merged
yoks merged 6 commits into
NVIDIA:mainfrom
yoks:health-nvidia-oem-metrics
Aug 8, 2026
Merged

feat: health nvidia oem metrics#4730
yoks merged 6 commits into
NVIDIA:mainfrom
yoks:health-nvidia-oem-metrics

Conversation

@yoks

@yoks yoks commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

With nv-redfish support of OEM Nvidia CSDL, this PR adds support of this new OEM fields into metrics emite by hw-health.

Also expands bmc-mock to support some of the OEM fields.

Related issues

#4731

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

yoks added 5 commits August 7, 2026 09:13
Signed-off-by: ianisimov <ianisimov@nvidia.com>
Signed-off-by: ianisimov <ianisimov@nvidia.com>
Signed-off-by: ianisimov <ianisimov@nvidia.com>
Signed-off-by: ianisimov <ianisimov@nvidia.com>
@yoks
yoks requested a review from a team as a code owner August 7, 2026 22:11
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added a Redfish telemetry collector for metric definitions and reports.
    • Added NVIDIA GPU, HBM memory, OEM, and processor metrics support.
    • Added mock memory resources, metrics, and related Redfish endpoints.
    • Added configurable telemetry collection with a 60-second default interval.
  • Bug Fixes

    • Stale and nonnumeric telemetry readings are now excluded from collected metrics.
  • Configuration

    • Telemetry collection can be enabled through the health service configuration.

Walkthrough

The mock Redfish service now supports memory resources, HBM metrics, NVIDIA OEM processor metrics, and telemetry reports. The health crate adds a configurable telemetry collector with metric-definition lookup, stale-report filtering, numeric sample publishing, and discovery integration.

Changes

Redfish mock resources

Layer / File(s) Summary
Memory resource modeling
crates/bmc-mock/src/redfish/memory.rs, crates/bmc-mock/src/redfish/computer_system.rs, crates/bmc-mock/src/hw/*
The mock Redfish service adds optional memory collections, HBM resources, memory metrics, system routes, and hardware configurations.
Telemetry service reports and definitions
crates/bmc-mock/src/redfish/telemetry_service.rs, crates/health/src/collectors/projection_test_support.rs
The mock telemetry service adds metric definitions, fresh and stale reports, NVIDIA metadata, lookup routes, and fixtures.
NVIDIA OEM metric projection
crates/bmc-mock/src/redfish/processor.rs, crates/health/src/collectors/entity_metrics.rs, crates/health/src/collectors/projection_test_support.rs
The health collector projects NVIDIA processor and memory OEM fields. Tests cover GPU and HBM metrics.
Telemetry collector flow
crates/health/src/collectors/telemetry.rs, crates/health/src/collectors/mod.rs
The new collector discovers telemetry services, loads units, filters reports, normalizes metric identifiers, and publishes numeric samples.
Collector configuration and discovery wiring
crates/health/src/config.rs, crates/health/src/discovery/context.rs, crates/health/src/discovery/spawn.rs, crates/health/Cargo.toml, crates/health/example/*
Telemetry configuration, discovery state, startup handling, dependency features, and example settings are added.

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

Sequence Diagram(s)

sequenceDiagram
  participant Discovery
  participant TelemetryCollector
  participant RedfishTelemetryService
  participant DataSink
  Discovery->>TelemetryCollector: start with fetch interval and data sink
  TelemetryCollector->>RedfishTelemetryService: discover telemetry service
  TelemetryCollector->>RedfishTelemetryService: fetch metric definitions
  TelemetryCollector->>RedfishTelemetryService: fetch metric reports
  TelemetryCollector->>DataSink: publish valid numeric samples
Loading

Possibly related PRs

Suggested labels: rack health

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.06% 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 identifies the primary change: adding NVIDIA OEM metrics support to health.
Description check ✅ Passed The description accurately relates the changes to NVIDIA OEM metrics, mock support, testing, and the new feature scope.
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.

@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

🧹 Nitpick comments (1)
crates/health/src/collectors/entity_metrics.rs (1)

643-708: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider aligning the bank_count! parameter order with the resolution order.

The macro body reads $corrected first, but every call site passes the misspelled identifier first. The two identifiers differ by one character. An inverted call would silently prefer the legacy spelling and would not fail any current test, because the fixtures never send both spellings for the same counter.

Naming the parameters in resolution order removes that failure mode at no runtime cost.

♻️ Proposed parameter reordering
     macro_rules! bank_count {
-        ($misspelled:ident, $corrected:ident, $mt:literal) => {
+        ($corrected:ident, $legacy:ident, $mt:literal) => {
-            if let Some(value) = rr.$corrected.flatten().or(rr.$misspelled.flatten()) {
+            if let Some(value) = rr.$corrected.flatten().or(rr.$legacy.flatten()) {
                 out.push(MetricField {
                     metric_type: Cow::Borrowed($mt),
                     unit: "count",
                     value: value as f64,
                 });
             }
         };
     }
 
     bank_count!(
-        max_availablity_bank_count,
         max_availability_bank_count,
+        max_availablity_bank_count,
         "nvidia_max_availability_banks"
     );

Apply the same swap to the remaining four bank_count! invocations.

🤖 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/health/src/collectors/entity_metrics.rs` around lines 643 - 708,
Reorder the `bank_count!` macro parameters to match its resolution order,
placing the corrected identifier before the misspelled legacy identifier, and
swap the arguments in all five invocations within `nvidia_memory_metric_fields`
so corrected fields remain preferred.
🤖 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/health/src/collectors/telemetry.rs`:
- Around line 145-147: Update load_units and the initialization flow in the
telemetry collector so units is cached only when metric_definitions returns
Ok(None) or successful definitions; leave self.units as None when the request
errors, allowing the next iteration to retry. Add a test covering a failed first
definitions request followed by a successful second request and verifying units
are refreshed.
- Around line 266-268: Update the metric-reading logic in the telemetry
collector to reject parsed f64 values that are not finite, including NaN and
infinities, before emitting samples. Add a regression test covering a non-finite
MetricValue and verify it is not sent to metric sinks.

---

Nitpick comments:
In `@crates/health/src/collectors/entity_metrics.rs`:
- Around line 643-708: Reorder the `bank_count!` macro parameters to match its
resolution order, placing the corrected identifier before the misspelled legacy
identifier, and swap the arguments in all five invocations within
`nvidia_memory_metric_fields` so corrected fields remain preferred.
🪄 Autofix

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: 01155e51-bb3d-4641-b75b-a326ba2e8029

📥 Commits

Reviewing files that changed from the base of the PR and between e05a814 and b20828a.

📒 Files selected for processing (31)
  • crates/bmc-mock/src/hw/bluefield3.rs
  • crates/bmc-mock/src/hw/bluefield4.rs
  • crates/bmc-mock/src/hw/dell_poweredge_r750.rs
  • crates/bmc-mock/src/hw/dell_poweredge_r760_bf4.rs
  • crates/bmc-mock/src/hw/dgx_gb300_nvl.rs
  • crates/bmc-mock/src/hw/dgx_vr_nvl.rs
  • crates/bmc-mock/src/hw/generic_ami.rs
  • crates/bmc-mock/src/hw/hpe_proliant_dl380a_gen11.rs
  • crates/bmc-mock/src/hw/lenovo_gb300_nvl.rs
  • crates/bmc-mock/src/hw/liteon_power_shelf.rs
  • crates/bmc-mock/src/hw/nvidia_dgx_h100.rs
  • crates/bmc-mock/src/hw/nvidia_gb200.rs
  • crates/bmc-mock/src/hw/nvidia_switch_n5700_ld.rs
  • crates/bmc-mock/src/hw/nvidia_switch_nd5200_ld.rs
  • crates/bmc-mock/src/hw/supermicro_gb300_nvl.rs
  • crates/bmc-mock/src/hw/wiwynn_gb200_nvl.rs
  • crates/bmc-mock/src/redfish/computer_system.rs
  • crates/bmc-mock/src/redfish/memory.rs
  • crates/bmc-mock/src/redfish/mod.rs
  • crates/bmc-mock/src/redfish/processor.rs
  • crates/bmc-mock/src/redfish/telemetry_service.rs
  • crates/health/Cargo.toml
  • crates/health/example/config.bmc-mock.toml
  • crates/health/example/config.example.toml
  • crates/health/src/collectors/entity_metrics.rs
  • crates/health/src/collectors/mod.rs
  • crates/health/src/collectors/projection_test_support.rs
  • crates/health/src/collectors/telemetry.rs
  • crates/health/src/config.rs
  • crates/health/src/discovery/context.rs
  • crates/health/src/discovery/spawn.rs

Comment on lines +145 to +147
if self.units.is_none() {
self.units = Some(self.load_units(&telemetry_service).await);
}

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

Retry metric-definition loading after a fetch failure.

Line 146 caches an empty map after metric_definitions() returns Err. The collector then emits unknown units until restart, even when the BMC recovers on the next iteration.

Cache an empty map only for Ok(None). Keep units as None after an error so the next iteration retries the request. Add a test where the first definitions request fails and the second succeeds.

Also applies to: 212-234

🤖 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/health/src/collectors/telemetry.rs` around lines 145 - 147, Update
load_units and the initialization flow in the telemetry collector so units is
cached only when metric_definitions returns Ok(None) or successful definitions;
leave self.units as None when the request errors, allowing the next iteration to
retry. Add a test covering a failed first definitions request followed by a
successful second request and verifying units are refreshed.

Comment on lines +266 to +268
let Ok(reading) = reading.trim().parse::<f64>() else {
continue;
};

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 non-finite metric values.

parse::<f64>() accepts values such as NaN and infinity. These values can reach metric sinks as invalid measurements.

Check reading.is_finite() before emitting the sample. Add a regression case for a non-finite MetricValue.

Proposed fix
             let Ok(reading) = reading.trim().parse::<f64>() else {
                 continue;
             };
+            if !reading.is_finite() {
+                continue;
+            }
📝 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
let Ok(reading) = reading.trim().parse::<f64>() else {
continue;
};
let Ok(reading) = reading.trim().parse::<f64>() else {
continue;
};
if !reading.is_finite() {
continue;
}
🤖 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/health/src/collectors/telemetry.rs` around lines 266 - 268, Update the
metric-reading logic in the telemetry collector to reject parsed f64 values that
are not finite, including NaN and infinities, before emitting samples. Add a
regression test covering a non-finite MetricValue and verify it is not sent to
metric sinks.

@yoks
yoks enabled auto-merge (squash) August 8, 2026 00:09
@yoks
yoks merged commit 0b9f088 into NVIDIA:main Aug 8, 2026
64 checks passed
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.

2 participants