Skip to content

Commit

Permalink
Most likely finished Error Recognition feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Macronic committed Sep 3, 2024
1 parent 442b3c8 commit 309dc8a
Show file tree
Hide file tree
Showing 7 changed files with 463 additions and 98 deletions.
127 changes: 98 additions & 29 deletions src/errors/conditions.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
use std::ops::ControlFlow;

use predicates::{prelude::predicate, str::RegexPredicate, Predicate};

use super::{Issue, SystemStateSnapshot};
use crate::system_state_manager::LogEntry;

use super::{Issue, SystemStateSnapshot, TriggerMetadata};

pub trait ErrorBaseCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool;
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata>;
}

pub struct FileExistsCondition {
pub file_path: RegexPredicate,
}

impl ErrorBaseCondition for FileExistsCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
for file in system_state.workspace_files.keys() {
if self.file_path.eval(file) {
return true;
return Some(TriggerMetadata::new_file(file.clone()));
}
}
false
None
}
}

Expand All @@ -35,11 +39,12 @@ pub struct ToolRunTimeGreaterThanCondition {
}

impl ErrorBaseCondition for ToolRunTimeGreaterThanCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
system_state
.tool_run_summaries
.iter()
.any(|t| t.tool_name == self.tool_name && t.run_duration > self.run_time)
.find(|t| t.tool_name == self.tool_name && t.run_duration > self.run_time)
.map(|tool_summary| TriggerMetadata::new_tool_run_summaries(tool_summary.clone()))
}
}

Expand All @@ -49,11 +54,12 @@ pub struct ToolCPUUsageGreaterThanCondition {
}

impl ErrorBaseCondition for ToolCPUUsageGreaterThanCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
system_state
.tool_run_summaries
.iter()
.any(|t| t.tool_name == self.tool_name && t.max_cpu_usage > self.threshold)
.find(|t| t.tool_name == self.tool_name && t.max_cpu_usage > self.threshold)
.map(|tool_summary| TriggerMetadata::new_tool_run_summaries(tool_summary.clone()))
}
}

Expand All @@ -63,11 +69,12 @@ pub struct ToolMemoryUsageGreaterThanCondition {
}

impl ErrorBaseCondition for ToolMemoryUsageGreaterThanCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
system_state
.tool_run_summaries
.iter()
.any(|t| t.tool_name == self.tool_name && t.max_memory_utilization > self.threshold)
.find(|t| t.tool_name == self.tool_name && t.max_memory_utilization > self.threshold)
.map(|tool_summary| TriggerMetadata::new_tool_run_summaries(tool_summary.clone()))
}
}

Expand All @@ -82,8 +89,8 @@ impl LogContainsInner {
}
}

pub fn trigger(&self, logs: &[String]) -> bool {
logs.iter().any(|l| self.regex.eval(l))
pub fn trigger<'a>(&self, logs: &'a [LogEntry]) -> Option<&'a LogEntry> {
logs.iter().find(|l| self.regex.eval(&l.message))
}
}

Expand All @@ -94,11 +101,17 @@ pub enum LogContainsCondition {
}

impl ErrorBaseCondition for LogContainsCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
match self {
LogContainsCondition::Stdout(inner) => inner.trigger(system_state.stdout_lines),
LogContainsCondition::Stderr(inner) => inner.trigger(system_state.stderr_lines),
LogContainsCondition::Syslog(inner) => inner.trigger(system_state.syslog_lines),
LogContainsCondition::Stdout(inner) => inner
.trigger(system_state.stdout_lines)
.map(|log| TriggerMetadata::new_stdout(log.clone())),
LogContainsCondition::Stderr(inner) => inner
.trigger(system_state.stderr_lines)
.map(|log| TriggerMetadata::new_stderr(log.clone())),
LogContainsCondition::Syslog(inner) => inner
.trigger(system_state.syslog_lines)
.map(|log| TriggerMetadata::new_syslog(log.clone())),
}
}
}
Expand All @@ -108,8 +121,12 @@ pub struct SystemCPUCondition {
}

impl ErrorBaseCondition for SystemCPUCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
system_state.system_summary.cpu_utilization > self.threshold
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
if system_state.system_summary.cpu_utilization > self.threshold {
Some(TriggerMetadata::default())
} else {
None
}
}
}

Expand All @@ -118,8 +135,12 @@ pub struct SystemMemoryCondition {
}

impl ErrorBaseCondition for SystemMemoryCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
system_state.system_summary.memory_utilization > self.threshold
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
if system_state.system_summary.memory_utilization > self.threshold {
Some(TriggerMetadata::default())
} else {
None
}
}
}

Expand All @@ -128,12 +149,17 @@ pub struct SystemDiskUtilizationCondition {
}

impl ErrorBaseCondition for SystemDiskUtilizationCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
system_state
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
if system_state
.system_summary
.disk_utilizations
.iter()
.any(|d| *d > self.threshold)
{
Some(TriggerMetadata::default())
} else {
None
}
}
}

Expand All @@ -142,8 +168,16 @@ pub struct IssueCondition {
}

impl ErrorBaseCondition for IssueCondition {
fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
system_state.found_issues.iter().any(|i| i == &self.issue)
fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
if system_state
.found_issues
.iter()
.any(|i| i.issue == self.issue)
{
Some(TriggerMetadata::new_issue(self.issue))
} else {
None
}
}
}

Expand All @@ -155,12 +189,47 @@ pub enum ErrorCondition {
}

impl ErrorCondition {
pub fn trigger(&self, system_state: &SystemStateSnapshot) -> bool {
pub fn trigger(&self, system_state: &SystemStateSnapshot) -> Option<TriggerMetadata> {
match self {
ErrorCondition::ExternalTrigger(condition) => condition.trigger(system_state),
ErrorCondition::Or(conditions) => conditions.iter().any(|c| c.trigger(system_state)),
ErrorCondition::And(conditions) => conditions.iter().all(|c| c.trigger(system_state)),
ErrorCondition::Not(condition) => !condition.trigger(system_state),
ErrorCondition::Or(conditions) => conditions.iter().fold(None, |acc, c| {
if acc.is_some() {
acc
} else if let Some(metadata) = c.trigger(system_state) {
Some(metadata)
} else {
acc
}
}),
ErrorCondition::And(conditions) => {
if let ControlFlow::Continue(value) =
conditions
.iter()
.try_fold(None, |acc: Option<TriggerMetadata>, c| {
if let Some(metadata) = c.trigger(system_state) {
if let Some(mut acc_metadata) = acc {
acc_metadata.merge(metadata);
ControlFlow::Continue(Some(acc_metadata))
} else {
ControlFlow::Continue(Some(metadata))
}
} else {
ControlFlow::Break(None::<TriggerMetadata>)
}
})
{
value
} else {
None
}
}
ErrorCondition::Not(condition) => {
if condition.trigger(system_state).is_some() {
None
} else {
Some(TriggerMetadata::default())
}
}
}
}
}
Expand Down
Loading

0 comments on commit 309dc8a

Please sign in to comment.