Repository navigation
Conversation
|
👋 Hi e-eygin! Thank you for contributing to ai-dynamo/nixl. Your PR reviewers will review your contribution then trigger the CI to test your changes. 🚀 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Enterprise Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe change updates ChangesDOCA Telemetry Exporter Update
Estimated code review effort: 1 (Trivial) | ~3 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
NIX-1591 removes a hot-path std::string allocation when exporting DOCA counter samples while preserving the published metric names. Signed-off-by: Efraim Eygin <eeygin@nvidia.com>
The shorter argument (event_name vs event_name.c_str()) lets the add_counter_increment call fit within the 100-col limit when wrapped, so clang-format-19 expects the compact form. No behavior change. Signed-off-by: Efraim Eygin <eeygin@nvidia.com>
6829b3d to
9ed5bfa
Compare
|
/build |
|
/ok to test 9ed5bfa |
|
👀 Investigating |
|
🤖 CI Triage Agent — This confirms the mechanism. The two branches were running concurrently on the same SLURM node ( The trigger is that when the first branch failed (exit 127 in branch 1's The root of branch 1's original failure: This is not a hang (timestamps show continuous test progress up to the failure) and not a legitimate test-logic bug — it is a CI infrastructure race between concurrently-scheduled parallel branches on a shared node. Summary: nixl-ci-gpu CPP test job failed with exit code 127 — the running job's working directory and Root cause: A filesystem race between the two parallel build/test branches ( Implicated commit: unknown (CI infrastructure/parallel-scheduling issue, not a source regression; the two touched CI scripts most recently were File: Suggested fix: Isolate the two parallel branches so one branch's teardown cannot delete the other's filesystem: give each matrix branch its own unique workspace directory and a per-branch Related: none found
|
|
👀 Investigating |
|
🤖 CI Triage Agent — I have enough evidence now. Let me summarize the timeline analysis conclusively. Timeline analysisThe nixlbench benchmark loop ran through all combinations (UCX/UCCL × READ/WRITE × DRAM/VRAM) with continuous output up to:
The largest inter-line gap is ~37 minutes (11:56:53 → 12:33:56), which is essentially the entire remaining wall-clock budget. Per triage rules, this is a hang, not slow work. The exit code 143 / "Cancelling due to timeout" is only the symptom. The last meaningful action before the silence was Notably, PR #1886 ("telemetry: avoid DOCA counter event name allocation") has nothing to do with the UCX/UCCL benchmark loop or ETCD teardown that hung. The only in-run anomalies are benign warnings: repeated Summary: The nixlbench GPU test job was killed by the Jenkins wall-clock timeout (exit 143) after hanging for ~37 minutes; all benchmark work had already completed successfully. Root cause: A hang during post-benchmark teardown. The last application activity was Implicated commit: unknown (the hang is in the benchmark test harness teardown / ETCD-reaping path, not in the PR's changed files; the harness File: benchmark test harness teardown path — the Suggested fix: Do not treat this as needing a longer timeout. Investigate why the shell does not return after Related: PR #1886 (the triggering PR, #1886 — content unrelated to failure); prior ETCD-cleanup fix #1227 ("prevent pkill etcd from killing other containers' processes") is the most relevant precedent for the ETCD-teardown code path. |
…ity) (#1894) ## What? Unifies the metric output of the two Prometheus-family telemetry exporters — the native (prometheus-cpp) exporter and the DOCA/CollectX exporter — so both emit **identical** `agent_*` series (same names, types, and coverage). A single shared `constexpr` descriptor (`telemetryMetricDescriptor` + `telemetry_metric_event_types` in `src/core/telemetry/telemetry_event.h`) now drives both exporters, replacing the two hand-written counter/gauge policies that had drifted (`initializeMetrics()`/`registerCounter()`/`registerGauge()` on the native side vs `isCounterEvent()`/`gaugeMetricName()` on the DOCA side). Net changes: - DOCA counters gain the OpenMetrics `_total` suffix and the previously-missing memory and xfer/post-time counters. - The native exporter gains the `agent_xfer_time` / `agent_xfer_post_time` last-op gauges. - `docs/telemetry.md` and both plugin READMEs updated to identical metric tables. Exporter-side only: no event-type or buffer-format change, and **no `TELEMETRY_VERSION` bump**. ## Why? The two exporters diverged for the same events — e.g. native exposed `agent_xfer_time_total` (counter) while DOCA exposed `agent_xfer_time` (gauge); DOCA counters lacked the `_total` suffix; DOCA emitted no memory counters. A user switching telemetry backends got different metric names/types and different dashboards. Consolidating onto one descriptor makes parity structural (a `switch` with no `default`, so `-Wswitch` turns any future missing metric into a compile error). Tracking issue: NIX-1598. Also a prerequisite for the DOCA IPC→DTS work (NIX-1599), which runs the DOCA exporter on a different CollectX backend and therefore inherits its series shape. Not a breaking change: the DOCA exporter has never shipped in a released NIXL version, so there are no DOCA scrape consumers — the `_total` rename just gets the OpenMetrics shape right before first release. ## How? - Add the shared descriptor + metric-event list to `telemetry_event.h`; both exporters and the tests read from it. - Native `initializeMetrics()` iterates the descriptor and stops appending `_total` locally; DOCA `exportEvent()` drives off it, and `isCounterEvent()`/`gaugeMetricName()` are deleted (this also removes DOCA's per-event `std::string` allocation, superseding #1886). Error counters keep the `status`-labelled path; `agent_errors_total` comes from the shared definition. - Tests (GoogleTest, run via CTest): - `telemetryMetricContract` pins the descriptor's exact name/type contract. - `prometheusTelemetryTest.ScrapeEmitsExactlyTheDescriptorSeries` and `docaNixlExporterTest.ScrapeEmitsExactlyTheDescriptorSeries` each scrape the live endpoint and assert the emitted `agent_*` series set equals the shared descriptor oracle — both using the **same** OpenMetrics parser. (The two exporters can't be co-linked — DOCA gRPC vs nixl-core gRPC — so each is validated in its own binary against the common oracle.) - Existing byte counter/last-gauge and error-status tests updated to `_total`. - `ninja -C build` green; telemetry gtests (43) + DOCA runtime tests (`doca_test`, `doca_nixl_test`, real CollectX) pass; clang-format clean. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Telemetry metrics are now driven by a unified descriptor contract, aligning Prometheus and DOCA series names and semantics. - Transfer-time and byte metrics now expose both cumulative `_total` counters and corresponding last-value gauges (when applicable). - **Bug Fixes** - Fixed inconsistent counter/gauge support and tx/rx byte-series naming between exporters. - **Documentation** - Updated telemetry documentation and exporter README tables to reflect the unified metric series and naming. - **Tests** - Added contract validation and scrape-coverage tests to confirm exporters emit exactly the expected series. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Efraim Eygin <eeygin@nvidia.com>
| #pragma GCC diagnostic push | ||
| #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||
| const std::string event_name(nixlEnumStrings::telemetryEventTypeStr(event.eventType_)); | ||
| const char *event_name = nixlEnumStrings::telemetryEventTypeStr(event.eventType_).data(); |
There was a problem hiding this comment.
Calling data() on a string_view and using the result as C-string should not be done, even in this case where the views happen to be, for now (!), constructed from C-strings, it's just such an anti-pattern. Perhaps return C-strings from the enum-to-name function?
…ity) (ai-dynamo#1894) ## What? Unifies the metric output of the two Prometheus-family telemetry exporters — the native (prometheus-cpp) exporter and the DOCA/CollectX exporter — so both emit **identical** `agent_*` series (same names, types, and coverage). A single shared `constexpr` descriptor (`telemetryMetricDescriptor` + `telemetry_metric_event_types` in `src/core/telemetry/telemetry_event.h`) now drives both exporters, replacing the two hand-written counter/gauge policies that had drifted (`initializeMetrics()`/`registerCounter()`/`registerGauge()` on the native side vs `isCounterEvent()`/`gaugeMetricName()` on the DOCA side). Net changes: - DOCA counters gain the OpenMetrics `_total` suffix and the previously-missing memory and xfer/post-time counters. - The native exporter gains the `agent_xfer_time` / `agent_xfer_post_time` last-op gauges. - `docs/telemetry.md` and both plugin READMEs updated to identical metric tables. Exporter-side only: no event-type or buffer-format change, and **no `TELEMETRY_VERSION` bump**. ## Why? The two exporters diverged for the same events — e.g. native exposed `agent_xfer_time_total` (counter) while DOCA exposed `agent_xfer_time` (gauge); DOCA counters lacked the `_total` suffix; DOCA emitted no memory counters. A user switching telemetry backends got different metric names/types and different dashboards. Consolidating onto one descriptor makes parity structural (a `switch` with no `default`, so `-Wswitch` turns any future missing metric into a compile error). Tracking issue: NIX-1598. Also a prerequisite for the DOCA IPC→DTS work (NIX-1599), which runs the DOCA exporter on a different CollectX backend and therefore inherits its series shape. Not a breaking change: the DOCA exporter has never shipped in a released NIXL version, so there are no DOCA scrape consumers — the `_total` rename just gets the OpenMetrics shape right before first release. ## How? - Add the shared descriptor + metric-event list to `telemetry_event.h`; both exporters and the tests read from it. - Native `initializeMetrics()` iterates the descriptor and stops appending `_total` locally; DOCA `exportEvent()` drives off it, and `isCounterEvent()`/`gaugeMetricName()` are deleted (this also removes DOCA's per-event `std::string` allocation, superseding ai-dynamo#1886). Error counters keep the `status`-labelled path; `agent_errors_total` comes from the shared definition. - Tests (GoogleTest, run via CTest): - `telemetryMetricContract` pins the descriptor's exact name/type contract. - `prometheusTelemetryTest.ScrapeEmitsExactlyTheDescriptorSeries` and `docaNixlExporterTest.ScrapeEmitsExactlyTheDescriptorSeries` each scrape the live endpoint and assert the emitted `agent_*` series set equals the shared descriptor oracle — both using the **same** OpenMetrics parser. (The two exporters can't be co-linked — DOCA gRPC vs nixl-core gRPC — so each is validated in its own binary against the common oracle.) - Existing byte counter/last-gauge and error-status tests updated to `_total`. - `ninja -C build` green; telemetry gtests (43) + DOCA runtime tests (`doca_test`, `doca_nixl_test`, real CollectX) pass; clang-format clean. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Telemetry metrics are now driven by a unified descriptor contract, aligning Prometheus and DOCA series names and semantics. - Transfer-time and byte metrics now expose both cumulative `_total` counters and corresponding last-value gauges (when applicable). - **Bug Fixes** - Fixed inconsistent counter/gauge support and tx/rx byte-series naming between exporters. - **Documentation** - Updated telemetry documentation and exporter README tables to reflect the unified metric series and naming. - **Tests** - Added contract validation and scrape-coverage tests to confirm exporters emit exactly the expected series. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Efraim Eygin <eeygin@nvidia.com>
What?
Removes a per-event
std::stringallocation in the DOCA telemetry exporter's counterhot path. In
nixlTelemetryDocaExporter::appendCounterSample, the event name is nowtaken directly from
nixlEnumStrings::telemetryEventTypeStr(event.eventType_).data()instead of constructing a temporary
std::stringjust to call.c_str().telemetryEventTypeStrisconstexprand returns astd::string_viewbacked entirelyby null-terminated string literals (every case plus the
"unknown_event"default), so.data()is a valid C string for the DOCA Metrics API. The-Wdeprecated-declarationspragma around the experimental DOCA call is kept as-is.
Why?
Pure hot-path overhead: a heap allocation on every exported counter event with no
behavioral benefit. This is the DOCA twin of the already-merged Prometheus Perf-5
(#1878 / NIX-1588), which removed the equivalent allocation on the Prometheus side.
Tracking: NIX-1591.
Behavior-preserving — identical series names, labels, and values. Covered by the existing
doca_nixl_test(test/doca-telemetry/telemetry_doca_nixl_test.cpp), which asserts counterseries names and cumulative values via the OpenMetrics scrape parser. All 5 tests pass.
How?
Scope is a single site: the gauge path already takes a
const char *(gaugeMetricName)and the error path uses the
"agent_errors_total"literal, soappendCounterSamplewas theonly allocation site. Exporter-side only — independent of the queue-architecture decisions.
Summary by CodeRabbit