feat/monitoring_alerting #61

Merged
johnride merged 12 commits from feat/monitoring_alerting into master 2025-06-19 14:37:20 +00:00
7 changed files with 86 additions and 52 deletions
Showing only changes of commit ba536885bd - Show all commits

View File

@ -1,6 +1,6 @@
use harmony::{ use harmony::{
inventory::Inventory, maestro::Maestro, inventory::Inventory, maestro::Maestro,
modules::monitoring::monitoring_alerting::MonitoringAlertingScore, modules::monitoring::monitoring_alerting::{MonitoringAlertingScore, MonitoringSystem},
topology::K8sAnywhereTopology, topology::K8sAnywhereTopology,
}; };
@ -13,10 +13,11 @@ async fn main() {
.await .await
.unwrap(); .unwrap();
let monitoring = MonitoringAlertingScore { //let monitoring = MonitoringAlertingScore {
alert_channel_configs: None, // alert_receivers: vec![],
}; // alert_rules: vec![],
// scrape_targets: vec![],
maestro.register_all(vec![Box::new(monitoring)]); //};
//maestro.register_all(vec![Box::new(monitoring)]);
harmony_cli::init(maestro, None).await.unwrap(); harmony_cli::init(maestro, None).await.unwrap();
} }

View File

@ -1,3 +1,4 @@
use log::debug;
use serde::Serialize; use serde::Serialize;
use crate::{ use crate::{
@ -14,16 +15,16 @@ pub struct DiscordWebhook {
} }
impl AlertReceiver for DiscordWebhook { impl AlertReceiver for DiscordWebhook {
type Sender = Prometheus; type M = Prometheus;
fn install(&self, sender: &Self::Sender) -> Result<(), String> { fn install(&self, sender: &Self::M) -> Result<(), String> {
sender.configure_receiver(Box::new(self)) sender.configure_receiver(Box::new(self))?;
debug!("DiscordWebhook installed for Prometheus");
Ok(())
} }
fn clone(&self) -> Self fn clone_box(&self) -> Box<dyn AlertReceiver<M = Self::M>> {
where Box::new(self.clone())
Self: Sized {
<Self as Clone>::clone(self)
} }
} }

View File

@ -9,27 +9,28 @@ use crate::{
topology::Topology, topology::Topology,
}; };
use super::prometheus::AlertSender; use super::monitoring_alerting::MonitoringSystem;
pub trait AlertReceiver: Debug + Send + Sync { pub trait AlertReceiver: Debug + Send + Sync {
type Sender: AlertSender; type M: MonitoringSystem;
fn install(&self, sender: &Self::Sender) -> Result<(), String>; fn install(&self, sender: &Self::M) -> Result<(), String>;
fn clone_box(&self) -> Box<dyn AlertReceiver<Sender = Self::Sender>>; fn clone_box(&self) -> Box<dyn AlertReceiver<M = Self::M>>;
} }
struct AlertReceiverConfig<S: AlertSender> { struct AlertReceiverConfig<M: MonitoringSystem> {
config: String, // Or whatever config: String, // Or whatever
sender: S, sender: M,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct AlertReceiverInterpret<S: AlertSender> { pub struct AlertReceiverInterpret<M: MonitoringSystem> {
pub receiver: Box<dyn AlertReceiver<Sender = S>>, pub receiver: Box<dyn AlertReceiver<M = M>>,
} }
#[async_trait] #[async_trait]
impl<T: Topology, S: AlertSender> Interpret<T> for AlertReceiverInterpret<S> { impl<T: Topology, M: MonitoringSystem> Interpret<T> for AlertReceiverInterpret<M> {
async fn execute( async fn execute(
&self, &self,
_inventory: &Inventory, _inventory: &Inventory,

View File

@ -2,10 +2,12 @@ use std::fmt::Debug;
use dyn_clone::DynClone; use dyn_clone::DynClone;
use super::prometheus::AlertSender; use super::monitoring_alerting::MonitoringSystem;
pub trait AlertRule: Debug + Send + Sync + DynClone { pub trait AlertRule: Debug + Send + Sync + DynClone {
type Sender: AlertSender; type M: MonitoringSystem;
fn install(&self, sender: &Self::Sender); fn install(&self, sender: &Self::M);
fn clone_box(&self) -> Box<dyn AlertRule<M = Self::M>>;
} }

View File

@ -1,6 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use log::debug;
use serde::Serialize; use serde::Serialize;
use crate::{ use crate::{
@ -11,37 +12,42 @@ use crate::{
topology::Topology, topology::Topology,
}; };
use super::{alert_receiver::AlertReceiver, prometheus::AlertSender}; use super::{alert_receiver::AlertReceiver, prometheus::Installable};
use super::alert_rule::AlertRule; use super::alert_rule::AlertRule;
use super::scrape_target::ScrapeTarget; use super::scrape_target::ScrapeTarget;
pub trait MonitoringSystem: std::fmt::Debug + Clone + Serialize + 'static {} #[async_trait]
pub trait MonitoringSystem: std::fmt::Debug + Clone + Serialize + 'static + Send + Sync {
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MonitoringAlertingScore<M: MonitoringSystem> { pub struct MonitoringAlertingScore<M: MonitoringSystem> {
pub alert_receivers: Vec<Box<dyn AlertReceiver<Sender = M>>>, pub alert_receivers: Vec<Box<dyn AlertReceiver<M = M>>>,
pub alert_rules: Vec<Box<dyn AlertRule<Sender = M>>>, pub alert_rules: Vec<Box<dyn AlertRule<M = M>>>,
pub scrape_targets: Vec<Box<dyn ScrapeTarget<Sender = M>>>, pub scrape_targets: Vec<Box<dyn ScrapeTarget<M = M>>>,
} }
#[derive(Clone)]
struct MonitoringConfig<M: MonitoringSystem> {
receivers: Vec<Box<dyn AlertReceiver<M = M>>>,
}
impl <M: MonitoringSystem + AlertSender> Clone for Box<dyn AlertReceiver<Sender = M>>{ impl<M: MonitoringSystem> Clone for Box<dyn AlertReceiver<M = M>> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
self.clone_box() self.clone_box()
} }
} }
impl <M: MonitoringSystem> Clone for Box<dyn AlertRule<Sender = M>>{ impl<M: MonitoringSystem> Clone for Box<dyn AlertRule<M = M>> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
todo!() self.clone_box()
} }
} }
impl <M: MonitoringSystem> Clone for Box<dyn ScrapeTarget<Sender = M>>{ impl<M: MonitoringSystem> Clone for Box<dyn ScrapeTarget<M = M>> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
todo!() self.clone_box()
} }
} }
impl<M: MonitoringSystem> Serialize for MonitoringAlertingScore<M> { impl<M: MonitoringSystem> Serialize for MonitoringAlertingScore<M> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -51,7 +57,9 @@ impl<M: MonitoringSystem> Serialize for MonitoringAlertingScore<M> {
} }
} }
impl<T: Topology, M: MonitoringSystem + Serialize> Score<T> for MonitoringAlertingScore<M> { impl<T: Topology, M: MonitoringSystem + Serialize + Installable> Score<T>
for MonitoringAlertingScore<M>
{
fn create_interpret(&self) -> Box<dyn Interpret<T>> { fn create_interpret(&self) -> Box<dyn Interpret<T>> {
Box::new(MonitoringAlertingInterpret { Box::new(MonitoringAlertingInterpret {
score: Arc::new(self.clone()), score: Arc::new(self.clone()),
@ -68,14 +76,19 @@ struct MonitoringAlertingInterpret<M: MonitoringSystem> {
score: Arc<MonitoringAlertingScore<M>>, score: Arc<MonitoringAlertingScore<M>>,
} }
#[async_trait] #[async_trait]
impl<M: MonitoringSystem, T: Topology> Interpret<T> for MonitoringAlertingInterpret<M> { impl<M: MonitoringSystem + Installable, T: Topology> Interpret<T>
for MonitoringAlertingInterpret<M>
{
async fn execute( async fn execute(
&self, &self,
inventory: &Inventory, inventory: &Inventory,
topology: &T, topology: &T,
) -> Result<Outcome, InterpretError> { ) -> Result<Outcome, InterpretError> {
todo!() debug!("score {:#?}", self.score);
monitoring_system.install().await
} }
fn get_name(&self) -> InterpretName { fn get_name(&self) -> InterpretName {
@ -94,3 +107,9 @@ impl<M: MonitoringSystem, T: Topology> Interpret<T> for MonitoringAlertingInterp
todo!() todo!()
} }
} }
impl<M: MonitoringSystem> MonitoringAlertingInterpret<M> {
fn build_config(&self) -> MonitoringConfig<M> {
todo!()
}
}

View File

@ -6,22 +6,18 @@ use crate::{
data::{Id, Version}, data::{Id, Version},
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome}, interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
inventory::Inventory, inventory::Inventory,
topology::Topology, topology::{HelmCommand, K8sAnywhereTopology, Topology},
}; };
use std::fmt::Debug; use std::fmt::Debug;
use super::monitoring_alerting::MonitoringSystem; use super::monitoring_alerting::{MonitoringSystem, MonitoringSystemInstaller};
pub trait AlertSender: std::fmt::Debug {}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct Prometheus {} pub struct Prometheus {}
impl Prometheus { impl Prometheus {
pub fn configure_receiver( pub fn configure_receiver(&self, receiver: Box<&dyn PrometheusReceiver>) -> Result<(), String> {
&self, let receiver_config = receiver.get_prometheus_config();
_receiver: Box<&dyn PrometheusReceiver>,
) -> Result<(), String> {
todo!() todo!()
} }
pub fn configure_rule(&self, _rule: Box<&dyn PrometheusRule>) { pub fn configure_rule(&self, _rule: Box<&dyn PrometheusRule>) {
@ -40,8 +36,6 @@ pub trait PrometheusCapability {
fn install_scrape_targets(&self, receivers: Vec<Box<dyn PrometheusScrapeTarget>>); fn install_scrape_targets(&self, receivers: Vec<Box<dyn PrometheusScrapeTarget>>);
} }
impl AlertSender for Prometheus {}
pub trait PrometheusReceiver { pub trait PrometheusReceiver {
fn get_prometheus_config(&self) -> PrometheusReceiverConfig; fn get_prometheus_config(&self) -> PrometheusReceiverConfig;
} }
@ -102,3 +96,17 @@ impl<T: Topology + PrometheusCapability> Interpret<T> for PrometheusMonitoringIn
todo!() todo!()
} }
} }
#[async_trait]
pub trait Installable {
async fn install(&self) -> Result<Outcome, InterpretError>;
type Installer;
}
#[async_trait]
impl Installable for Prometheus {
type Installer = K8sAnywhereTopology;
async fn install(&self) -> Result<Outcome, InterpretError> {
todo!()
}
}

View File

@ -2,11 +2,13 @@ use std::fmt::Debug;
use dyn_clone::DynClone; use dyn_clone::DynClone;
use super::prometheus::AlertSender; use super::monitoring_alerting::MonitoringSystem;
pub trait ScrapeTarget: Debug + Send + Sync + DynClone { pub trait ScrapeTarget: Debug + Send + Sync + DynClone {
type Sender: AlertSender; type M: MonitoringSystem;
fn install(&self, sender: &Self::Sender); fn install(&self, sender: &Self::M);
fn clone_box(&self) -> Box<dyn ScrapeTarget<M = Self::M>>;
} }