Skip to content

refactor(scout): pair action and reconnect records with their counters#3739

Merged
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3730
Jul 21, 2026
Merged

refactor(scout): pair action and reconnect records with their counters#3739
chet merged 1 commit into
NVIDIA:mainfrom
chet:gh-issue-3730

Conversation

@chet

@chet chet commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Scout action outcomes and stream reconnects each described one occurrence with two calls: a counter update followed by its operator record.

Typed sibling Events now own both sides while preserving the existing metric names, labels, log levels, messages, and log-only context. Stream connection outcomes remain metric-only because their surrounding lifecycle records describe a broader boundary.

Table-driven tests cover each paired emission and the deliberately silent connection outcome.

Related issues

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.)

The action and stream-connection outcome matrices use named check_values rows, while the reconnect contract remains a focused test.

Verified with:

  • cargo test -p carbide-scout
  • cargo make format-nightly
  • cargo make clippy
  • cargo make carbide-lints
  • cargo make check-event-names

Additional Notes

Event labels are also written into the log record, so action records now carry action=firmware_upgrade (the bounded metric spelling) alongside action_name=FIRMWARE_UPGRADE (the historical protobuf spelling). This keeps the existing metric contract and retains the original action value.

Closes #3730

@chet
chet requested a review from a team as a code owner July 20, 2026 21:30
@chet

chet commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • Observability
    • Action handling logs now include the action name, outcome, and error details when applicable.
    • Stream reconnection attempts now generate warning logs with endpoint and machine information.
    • Connection and action metrics continue to be recorded with improved context.

Walkthrough

Scout telemetry now emits structured logs with action outcomes, action names, errors, reconnect endpoints, and machine identities while preserving metric counters. Service and stream paths populate the expanded events, with tests covering log contents and metric increments.

Changes

Scout telemetry enrichment

Layer / File(s) Summary
Action event logging and context
crates/scout/src/main.rs, crates/scout/src/metrics.rs
ScoutActionHandled emits outcome-specific info logs with action and error context. run_as_service supplies those values from action results, and tests validate logs and metric increments.
Reconnect event context and validation
crates/scout/src/stream.rs, crates/scout/src/metrics.rs
Reconnect events include endpoint and machine identity and emit warning logs. Tests validate reconnect metrics and confirm stream connections remain metric-only.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the refactor: pairing Scout action and reconnect records with their counters.
Description check ✅ Passed The description clearly matches the changeset, describing paired metric/operator records, tests, and the preserved metric contract.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll perform a complete review of #3739.

🐇✨

✅ Action performed

Full review finished.

@chet chet changed the title refactor(scout): emit action and reconnect events refactor(scout): let action and reconnect records move their counters Jul 20, 2026
@chet

chet commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@chet Understood. I’ll perform a complete review of #3739, including correctness, telemetry semantics, error handling, and test coverage.

🐇🔎

✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 17 minutes.

@chet

chet commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Hey @coderabbitai can you do a full_review when you get a chance? CICD isn't letting me continue because the CodeRabbit check "failed". Thanks!

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@chet Understood. I’ve triggered a complete review of #3739 to refresh the CodeRabbit check.

🐇🔎

✅ Action performed

Full review finished.

@chet chet changed the title refactor(scout): let action and reconnect records move their counters refactor(scout): pair action and reconnect records with their counters Jul 21, 2026
Scout action outcomes and stream reconnects each described one occurrence with two calls: a counter update followed by its operator record.

Typed sibling `Event`s now own both sides while preserving the existing metric names, labels, log levels, messages, and log-only context. Stream connection outcomes remain metric-only because their surrounding lifecycle records describe a broader boundary.

Table-driven tests cover each paired emission and the deliberately silent connection outcome.

This supports NVIDIA#3730

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

chet commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll perform a complete review of #3739.

🐇🔎

✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 21 minutes.

chet commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll perform a complete review of #3739, including correctness, telemetry semantics, error handling, and test coverage.

🐇🔎

✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 5 minutes.

chet commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full_review, thanks!

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@chet Understood — I’ll perform a complete review of #3739, including correctness, telemetry semantics, error handling, and test coverage.

🐇🔎

✅ 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/scout/src/metrics.rs (1)

116-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded "10s delay" text is decoupled from the actual sleep duration — extract a shared constant.

ScoutStreamReconnect's fixed message literally states "...after 10s delay", while the real delay is a separately-defined Duration::from_secs(10) in the reconnect loop. Nothing keeps these two in sync; if the delay is ever tuned, the log message will misinform operators without any compiler or test signal.

  • crates/scout/src/metrics.rs#L116-L134: derive the "10s" wording from a shared constant (or replace it with a generic message and add a #[context] delay_seconds field per the coding guideline to "record dynamic operational values as structured fields rather than interpolating them into the message").
  • crates/scout/src/stream.rs#L80-L84: define the reconnect delay as a pub(crate) const/shared value and reuse it both for Duration::from_secs(...) and to populate the new context field (or the shared constant consumed by the message text).
♻️ Proposed fix using a structured delay field
-    message = "scout stream reconnecting after 10s delay",
+    message = "scout stream reconnecting after delay",
     describe = "Number of scout stream reconnect cycles after a stream closed or errored."
 )]
 pub struct ScoutStreamReconnect {
     #[context]
     pub api_endpoint: String,
     #[context]
     pub machine_id: MachineId,
+    #[context]
+    pub delay_seconds: u64,
 }
+const RECONNECT_DELAY: Duration = Duration::from_secs(10);
+
             emit(ScoutStreamReconnect {
                 api_endpoint: options.api.clone(),
                 machine_id,
+                delay_seconds: RECONNECT_DELAY.as_secs(),
             });
-            tokio::time::sleep(Duration::from_secs(10)).await;
+            tokio::time::sleep(RECONNECT_DELAY).await;
🤖 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/scout/src/metrics.rs` around lines 116 - 134, Replace the hardcoded
reconnect delay text in ScoutStreamReconnect with a generic message and add a
structured delay_seconds context field populated from a shared reconnect-delay
constant. In crates/scout/src/stream.rs lines 80-84, define that constant as
pub(crate), reuse it for Duration::from_secs(...) and when constructing
ScoutStreamReconnect; update crates/scout/src/metrics.rs lines 116-134
accordingly.
🤖 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/scout/src/metrics.rs`:
- Around line 116-134: Replace the hardcoded reconnect delay text in
ScoutStreamReconnect with a generic message and add a structured delay_seconds
context field populated from a shared reconnect-delay constant. In
crates/scout/src/stream.rs lines 80-84, define that constant as pub(crate),
reuse it for Duration::from_secs(...) and when constructing
ScoutStreamReconnect; update crates/scout/src/metrics.rs lines 116-134
accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2c5ba94c-4871-47ba-a13e-0a4db73b72fa

📥 Commits

Reviewing files that changed from the base of the PR and between 4ad44c6 and 86f3d13.

📒 Files selected for processing (3)
  • crates/scout/src/main.rs
  • crates/scout/src/metrics.rs
  • crates/scout/src/stream.rs

@chet
chet merged commit ea44310 into NVIDIA:main Jul 21, 2026
62 checks passed
@chet
chet deleted the gh-issue-3730 branch July 21, 2026 15:54
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.

Unify Scout action and reconnect logs with their metrics

2 participants