-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add summary module for aggregating runtime information and internal metrics #365
base: main
Are you sure you want to change the base?
Conversation
…rnal metrics Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files
|
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
…nd update export logic Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
pub enum DisplayOptionKind { | ||
#[default] | ||
Issues, | ||
Timing, | ||
Metrics, | ||
All, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could be bitflags or enumflags, but I'm unsure if that wouldn't be overengineering?
…ic method Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
…ethods to use EcoString Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
What's still missing is functionality to store different categories of issues, e.g. warnings or soft errors. And then to log them to the terminal. TODO:
|
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
…ove logging Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
… Summary Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
…tional fields in Summary Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
|
||
use ecow::EcoString; | ||
|
||
pub type Issues = BTreeMap<IssueCategory, BTreeMap<IssueScope, CondensedIssue>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is IssueScope
needed, or do we want to deduplicated on some other stuff? We can also not use a BTreeMap
here, but just a Vec
tor.
pub type Issues = BTreeMap<IssueCategory, Vec<CondensedIssue>>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could IssueScope
be a member of CondensedIssue
?
So you use a Vec
and still have a notion of IssueScope
…king logic Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
// ! TODO: Refactor this method to merge the context of each summary | ||
// ! | ||
// ? How do we merge the context of each summary? | ||
// ? We can't merge the context, as it's a unique identifier for each summary. | ||
// ? We could add a new field to each CondensedIssue to store the context of the | ||
// ? merged summaries. | ||
// ? | ||
// ? How do we merge the other fields? E.g. Timing, Metrics, etc. | ||
pub fn merge(&mut self, other: Self) { | ||
self.issues.extend(other.issues); | ||
self.metrics.extend(other.metrics); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use conflate
and implement Merge
, make sure we fulfil above requirements and make it as ergonomic as possible. Make sure deduplication works well also for edge cases. We want to be sure, that we can assess if a command soft errored (warnings are lower priority).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, conflate is actually behind the merge
feature flag and doesn't make sense then to be used here.
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com>
|
||
use ecow::EcoString; | ||
|
||
pub type Issues = BTreeMap<IssueCategory, BTreeMap<IssueScope, CondensedIssue>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could IssueScope
be a member of CondensedIssue
?
So you use a Vec
and still have a notion of IssueScope
metrics: Metrics, | ||
|
||
/// Display this data | ||
display: HashSet<DisplayOptionKind>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I'm beginning to read through the code, I am not (yet) fully undertanding what DisplayOptionKind
is about.
Could you detail it a bit more in the code-doc? (for instance in the enum's doc)
pub fn enable_log(&mut self) -> Self { | ||
self.log_enabled = true; | ||
self.clone() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what is the reason to use clone there?
The builder pattern usually is something like:
pub fn enable_log(mut self) -> Self {
self.log_enabled = true;
self
}
_ = self | ||
.issues | ||
.entry(category) | ||
.or_default() | ||
.entry(scope) | ||
.and_modify(|val| { | ||
val.count += 1; | ||
if val.root_cause.is_none() { | ||
val.root_cause.clone_from(&root_cause); | ||
} | ||
}) | ||
.or_insert(CondensedIssue { | ||
category, | ||
message, | ||
count: 1, | ||
root_cause, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I see it, when we get in the and_modify
case, we loose the message
.
Is that voluntary?
Same we might have != root_cause
but we'll keep only one.
Wouldn't this lead to "wrong" reporting of some error A that happened N times, but in reality, A happened N1 times and B, C, D, E had the same scope and happened but their "message" and "root_cause" are lost.
I understand we want to aggregate and get a high level overview
. But as I understand this, we could become misleading
there.
_ = self | ||
.metrics | ||
.entry(key.into()) | ||
.and_modify(|val| *val = value.clone()) | ||
.or_insert_with(|| value); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I see that metrics
are erase on save.
I feel like this should be documented in the add
method.
Maybe also this method should be renamed set_metric
?
|
||
pub fn export_all(&mut self) -> bool { | ||
self.display.insert(DisplayOptionKind::All) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you let me know of use cases where we want only some DisplayOptionKind
and not some others?
Also I feel it's a bit weird that ALL
is an enum value.
An informative summary system for aggregating and condensing data collected
from runtime checks, including warnings, issues, and operational metrics.
This system should provide end-users with a clear, concise summary of command
execution results without conflicting with existing error-handling standards.
In scenarios where execution cannot proceed due to a critical error, a
RusticError
will be raised instead, and no summary will be provided.Separation of Concerns
Critical runtime errors that prevent further execution are handled through the
existing
RusticError
system. TheSummary
will only collect information fornon-fatal events.
Compatibility with Existing Error Handling
Summaries must coexist with error propagation rules. They will not replace
the core behavior of error propagation but act as a complementary mechanism
for presenting non-fatal feedback.
User-Friendly Reporting
Summaries should aggregate detailed runtime information—such as warnings,
issues, and metrics — in a clear and condensed format for the end-user.
Aggregation & Condensation
Similar or repeated errors should be aggregated to avoid redundant information,
presenting users with a high-level overview.