feat(instrument): per-instance log messages via message = dynamic#3705
Conversation
WalkthroughThe event derive macro now supports static, dynamic, and absent messages. A public ChangesDynamic event messages
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant EventDeclaration as Event declaration
participant EventDerive as Event derive macro
participant GeneratedEvent as Generated Event
participant DynamicMessage as DynamicMessage implementation
EventDeclaration->>EventDerive: declare message = dynamic
EventDerive->>GeneratedEvent: generate Event::message()
GeneratedEvent->>DynamicMessage: call message()
DynamicMessage-->>GeneratedEvent: return per-instance message
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full_review |
|
🌿 Preview your docs: https://nvidia-preview-pull-request-3705.docs.buildwithfern.com/infra-controller |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
crates/instrument/src/lib.rs (1)
574-596: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse one table for outcome-to-message and outcome-to-level expectations.
The test maps the same input enum to two outputs; table-driven cases keep variant coverage and expectations together.
🤖 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 574 - 596, Refactor dynamic_message_selects_wording_per_variant to use one table-driven set of cases containing each Outcome variant, its expected message, and its expected LogAt value. Iterate over the table and perform both Event::message and Event::log_at assertions per case, keeping coverage and expectations together.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.
Inline comments:
In `@crates/xtask/src/metric_docs.rs`:
- Around line 255-264: Update the message attribute parsing branch in the metric
documentation gate to accept string literals or only the identifier dynamic;
reject any other identifier with a parse error, matching the validation in the
instrument macro implementation. Add a negative parser test covering message =
bogus.
---
Nitpick comments:
In `@crates/instrument/src/lib.rs`:
- Around line 574-596: Refactor dynamic_message_selects_wording_per_variant to
use one table-driven set of cases containing each Outcome variant, its expected
message, and its expected LogAt value. Iterate over the table and perform both
Event::message and Event::log_at assertions per case, keeping coverage and
expectations together.
🪄 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: 095f6cf0-a1ef-4b0a-87b3-171228140314
📒 Files selected for processing (4)
crates/instrument-macros/src/lib.rscrates/instrument/src/lib.rscrates/xtask/src/metric_docs.rsdocs/observability/instrumentation.md
An `Event`'s log `message` has been a single static string, even when the event's outcome is a `#[label]` enum whose variants deserve distinct wording. The new `message = dynamic` knob lifts that: declare it in place of a literal `message`, implement the new `DynamicMessage` trait, and the derive routes `Event::message()` through it so each instance picks its own `&'static str` -- typically by matching on a label enum. Level and message are independent axes: an event can pair a dynamic level with a static message, a static level with dynamic wording, or both. This closes a gap for events that keep a separate `tracing::` line per outcome purely to preserve per-variant wording. With `message = dynamic` that line folds into the `emit()`, keeping the metric and its message a single declaration. - Adds the `DynamicMessage` trait and the `message = dynamic` value; the derive routes `Event::message()` to the impl, and otherwise emits the static string (or an empty default). A `message` that is neither a string literal nor `dynamic` is a compile error. - Teaches the `check-metric-docs` gate the ident form, so a metric-backed event can declare `message = dynamic` without tripping the catalogue parser. Tests: `DynamicMessage` routing selects per-variant wording independently of the level; the derive rejects a non-string, non-`dynamic` `message`; the docs gate collects a `message = dynamic` counter. Signed-off-by: Chet Nichols III <chetn@nvidia.com>
f9b53d5 to
aaa692c
Compare
…n guide Add a `message = dynamic` entry to the instrumentation guide, next to the existing `log = dynamic` section: declare it, implement `DynamicMessage`, and the derive routes `Event::message()` through it. Includes the guidance to prefer a static `message` plus a label where the label already names the case, and to use `message = dynamic` only where the wording says something the label does not. Documents the framework capability added in NVIDIA#3705; kept as its own PR so the code and docs can land on independent timelines. Signed-off-by: Chet Nichols III <chetn@nvidia.com>
Event's logmessagehas been a single static string.message = dynamiclets an event pick its message per instance: declare it instead of a literalmessage, implement the newDynamicMessagetrait, and the derive routesEvent::message()through it, typically a match on a#[label]enum. Level and message stay independent axes.That lets an event that today keeps a separate
tracing::line per outcome (purely to preserve per-variant wording) fold that line into theemit(), so the metric and its message are one declaration.DynamicMessagetrait plus themessage = dynamicvalue; amessagethat is neither a string literal nordynamicis a compile error.check-metric-docsgate learns the ident form, so a metric-backed event can usemessage = dynamicwithout tripping the catalogue parser.Guide docs are in a separate PR (#3707).
Part of the instrumentation-coherency initiative (#3169). Enables the folded metric+log form for outcome-enum events like the
/metricsscrape-failure meta-metric (#3546, contributor PR #3686).