Hastic standalone https://hastic.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

138 lines
4.1 KiB

use fastrand::bool;
use serde::{Deserialize, Serialize};
use async_trait::async_trait;
use crate::services::{metric_service::MetricService, segments_service::SegmentsService};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct PatternConfig {
pub correlation_score: f32,
pub anti_correlation_score: f32,
pub model_score: f32,
pub threshold_score: f32,
}
impl Default for PatternConfig {
fn default() -> Self {
PatternConfig {
correlation_score: 0.7,
anti_correlation_score: 0.1,
model_score: 0.5,
threshold_score: 1.0,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AnomalyConfig {
pub sesonality: bool,
}
impl Default for AnomalyConfig {
fn default() -> Self {
AnomalyConfig { sesonality: false }
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ThresholdConfig {
pub threashold: f64,
}
impl Default for ThresholdConfig {
fn default() -> Self {
ThresholdConfig { threashold: 0.5 }
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum AnalyticUnitConfig {
Pattern(PatternConfig),
Threshold(ThresholdConfig),
Anomaly(AnomalyConfig),
}
impl AnalyticUnitConfig {
// return tru if patch is different type
pub fn patch(&self, patch: PatchConfig) -> (AnalyticUnitConfig, bool) {
match patch {
PatchConfig::Pattern(tcfg) => match self.clone() {
AnalyticUnitConfig::Pattern(_) => {
if tcfg.is_some() {
return (AnalyticUnitConfig::Pattern(tcfg.unwrap()), false);
} else {
return (AnalyticUnitConfig::Pattern(Default::default()), false);
}
}
_ => {
if tcfg.is_some() {
return (AnalyticUnitConfig::Pattern(tcfg.unwrap()), true);
} else {
return (AnalyticUnitConfig::Pattern(Default::default()), true);
}
}
},
PatchConfig::Anomaly(tcfg) => match self.clone() {
AnalyticUnitConfig::Anomaly(_) => {
if tcfg.is_some() {
return (AnalyticUnitConfig::Anomaly(tcfg.unwrap()), false);
} else {
return (AnalyticUnitConfig::Anomaly(Default::default()), false);
}
}
_ => {
if tcfg.is_some() {
return (AnalyticUnitConfig::Anomaly(tcfg.unwrap()), true);
} else {
return (AnalyticUnitConfig::Anomaly(Default::default()), true);
}
}
},
PatchConfig::Threshold(tcfg) => match self.clone() {
AnalyticUnitConfig::Threshold(_) => {
if tcfg.is_some() {
return (AnalyticUnitConfig::Threshold(tcfg.unwrap()), false);
} else {
return (AnalyticUnitConfig::Threshold(Default::default()), false);
}
}
_ => {
if tcfg.is_some() {
return (AnalyticUnitConfig::Threshold(tcfg.unwrap()), true);
} else {
return (AnalyticUnitConfig::Threshold(Default::default()), true);
}
}
},
}
}
}
pub enum LearningResult {
Finished,
FinishedEmpty,
DatasourceError,
}
#[async_trait]
pub trait AnalyticUnit {
async fn learn(&mut self, ms: MetricService, ss: SegmentsService) -> LearningResult;
async fn detect(
&self,
ms: MetricService,
from: u64,
to: u64,
) -> anyhow::Result<Vec<(u64, u64)>>;
fn set_config(&mut self, c: AnalyticUnitConfig);
}
#[derive(Deserialize, Serialize, Debug)]
pub enum PatchConfig {
Pattern(Option<PatternConfig>),
Threshold(Option<ThresholdConfig>),
Anomaly(Option<AnomalyConfig>),
}