feat: add monitoring system and alerting
- Implemented a basic monitoring system with alerting capabilities. - Introduced `MonitoringAlertingScore` and related traits (`MonitoringSystem`, `ScrapeTarget`, `AlertRule`). - Added `MonitoringAlertingInterpret` to handle the execution of monitoring configurations. - Defined interfaces for Prometheus integration (PrometheusReceiver, PrometheusRule, PrometheusScrapeTarget). - Introduced `CloneBox` trait to enable cloning boxed trait objects. - Refactored Prometheus related traits to require `Debug` implementation. - Implemented basic placeholder logic for Prometheus configuration and alerting. - Updated existing traits to include `Send` and `Sync` where appropriate.
This commit is contained in:
parent
f6c146b14b
commit
9412c0529a
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -2387,6 +2387,15 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "monitoring"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"harmony",
|
||||
"harmony_cli",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.14"
|
||||
|
@ -2,7 +2,7 @@ use harmony::{
|
||||
data::Version,
|
||||
inventory::Inventory,
|
||||
maestro::Maestro,
|
||||
modules::lamp::{LAMPConfig, LAMPScore},
|
||||
modules::{lamp::{LAMPConfig, LAMPScore}, monitoring::monitoring_alerting::MonitoringAlertingScore},
|
||||
topology::{K8sAnywhereTopology, Url},
|
||||
};
|
||||
|
||||
@ -29,6 +29,8 @@ async fn main() {
|
||||
},
|
||||
};
|
||||
|
||||
let monitoring = MonitoringAlertingScore { alert_channel_configs: todo!() };
|
||||
|
||||
// You can choose the type of Topology you want, we suggest starting with the
|
||||
// K8sAnywhereTopology as it is the most automatic one that enables you to easily deploy
|
||||
// locally, to development environment from a CI, to staging, and to production with settings
|
||||
|
@ -1,31 +1,33 @@
|
||||
//#[derive(Debug, Clone)]
|
||||
//pub struct DiscordWebhookAlertChannel {
|
||||
// pub webhook_url: Url,
|
||||
// pub name: String,
|
||||
// pub send_resolved_notifications: bool,
|
||||
//}
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{interpret::Interpret, modules::monitoring::{alert_receiver::{AlertReceiver, AlertReceiverInterpret}, alert_rule::AlertRule, prometheus::{Prometheus, PrometheusReceiver, PrometheusRule, PrometheusScrapeTarget}, scrape_target::ScrapeTarget}, score::Score, topology::Topology};
|
||||
use crate::{
|
||||
interpret::Interpret,
|
||||
modules::monitoring::{
|
||||
alert_receiver::{AlertReceiver, AlertReceiverInterpret},
|
||||
prometheus::{Prometheus, PrometheusReceiver},
|
||||
},
|
||||
score::Score,
|
||||
topology::Topology,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
struct DiscordWebhook;
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_receiver(&self) -> PrometheusReceiver {
|
||||
PrometheusReceiver {}
|
||||
}
|
||||
}
|
||||
|
||||
impl AlertReceiver for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) -> Result<(), String> {
|
||||
sender.configure_receiver(self.as_prometheus_receiver())
|
||||
sender.configure_receiver(Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl PrometheusReceiver for DiscordWebhook {
|
||||
fn get_prometheus_config(
|
||||
&self,
|
||||
) -> crate::modules::monitoring::prometheus::PrometheusReceiverConfig {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct DiscordWebhookScore {
|
||||
@ -36,41 +38,10 @@ impl<T: Topology> Score<T> for DiscordWebhookScore {
|
||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||
Box::new(AlertReceiverInterpret {
|
||||
receiver: Box::new(self.config.clone()),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl ScrapeTarget for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) {
|
||||
sender.configure_scrape_target(self.as_prometheus_scrape_target())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_scrape_target(&self) -> PrometheusScrapeTarget {
|
||||
PrometheusScrapeTarget { definition: todo!() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl AlertRule for DiscordWebhook {
|
||||
type Sender = Prometheus;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) {
|
||||
sender.configure_rule(self.as_prometheus_rule())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl DiscordWebhook {
|
||||
fn as_prometheus_rule(&self) -> PrometheusRule {
|
||||
PrometheusRule { definition: todo!() }
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ use crate::{
|
||||
topology::Topology,
|
||||
};
|
||||
|
||||
use super::prometheus::AlertSender;
|
||||
use super::{monitoring_alerting::CloneBox, prometheus::AlertSender};
|
||||
|
||||
pub trait AlertReceiver: Debug + Send + Sync {
|
||||
pub trait AlertReceiver: Debug + Send + Sync + CloneBox {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self, sender: &Self::Sender) -> Result<(), String>;
|
||||
@ -23,16 +23,16 @@ struct AlertReceiverConfig<S: AlertSender> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AlertReceiverInterpret {
|
||||
pub receiver: Box<dyn AlertReceiver<Sender = dyn AlertSender>>,
|
||||
pub struct AlertReceiverInterpret<S: AlertSender> {
|
||||
pub receiver: Box<dyn AlertReceiver<Sender = S>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T: Topology> Interpret<T> for AlertReceiverInterpret {
|
||||
impl<T: Topology, S: AlertSender> Interpret<T> for AlertReceiverInterpret<S> {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
_inventory: &Inventory,
|
||||
_topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
todo!()
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::fmt::Debug;
|
||||
|
||||
use super::prometheus::AlertSender;
|
||||
|
||||
pub trait AlertRule: Debug {
|
||||
pub trait AlertRule: Debug + Send + Sync {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self, sender: &Self::Sender);
|
||||
|
@ -1,35 +1,41 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use serde::Serialize;
|
||||
use serde_value::Value;
|
||||
|
||||
use crate::topology::oberservability::monitoring::{AlertChannelConfig, Monitor};
|
||||
use crate::{
|
||||
data::{Id, Version},
|
||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
||||
inventory::Inventory,
|
||||
score::Score,
|
||||
topology::{HelmCommand, Topology},
|
||||
topology::Topology,
|
||||
};
|
||||
|
||||
use super::alert_receiver::AlertReceiver;
|
||||
use super::alert_rule::AlertRule;
|
||||
use super::scrape_target::ScrapeTarget;
|
||||
|
||||
pub trait MonitoringSystem: std::fmt::Debug + Clone + Serialize + 'static {}
|
||||
|
||||
pub trait MonitoringSystem {}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MonitoringAlertingScore<M: MonitoringSystem> {
|
||||
alert_receivers: Vec<Box<dyn AlertReceiver<Sender = M>>>,
|
||||
alert_rules: Vec<Box<dyn AlertRule<Sender = M>>>,
|
||||
scrape_targets: Vec<Box<dyn ScrapeTarget<Sender = M>>>,
|
||||
alert_receivers: Arc<Vec<Box<dyn AlertReceiver<Sender = M>>>>,
|
||||
alert_rules: Arc<Vec<Box<dyn AlertRule<Sender = M>>>>,
|
||||
scrape_targets: Arc<Vec<Box<dyn ScrapeTarget<Sender = M>>>>,
|
||||
}
|
||||
|
||||
impl<T: Topology, M: MonitoringSystem> Score<T> for MonitoringAlertingScore<M> {
|
||||
impl <M: MonitoringSystem> Serialize for MonitoringAlertingScore<M> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Topology, M: MonitoringSystem + Serialize> Score<T> for MonitoringAlertingScore<M> {
|
||||
fn create_interpret(&self) -> Box<dyn Interpret<T>> {
|
||||
Box::new(MonitoringAlertingInterpret {
|
||||
score: self.clone(),
|
||||
score: Arc::new(self.clone()),
|
||||
})
|
||||
}
|
||||
|
||||
@ -39,24 +45,18 @@ impl<T: Topology, M: MonitoringSystem> Score<T> for MonitoringAlertingScore<M> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MonitoringAlertingInterpret {
|
||||
score: MonitoringAlertingScore,
|
||||
struct MonitoringAlertingInterpret<M: MonitoringSystem> {
|
||||
score: Arc<MonitoringAlertingScore<M>>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T: Topology> Interpret<T> for MonitoringAlertingInterpret {
|
||||
impl<M: MonitoringSystem, T: Topology> Interpret<T> for MonitoringAlertingInterpret<M> {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
topology
|
||||
.provision_monitor(
|
||||
inventory,
|
||||
topology,
|
||||
self.score.alert_channel_configs.clone(),
|
||||
)
|
||||
.await
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_name(&self) -> InterpretName {
|
||||
@ -75,3 +75,16 @@ impl<T: Topology> Interpret<T> for MonitoringAlertingInterpret {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CloneBox {
|
||||
fn clone_box(&self) -> Box<dyn CloneBox>;
|
||||
}
|
||||
|
||||
impl<C> CloneBox for C
|
||||
where
|
||||
C: Clone + 'static,
|
||||
{
|
||||
fn clone_box(&self) -> Box<dyn CloneBox> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
@ -6,24 +6,23 @@ use crate::{
|
||||
data::{Id, Version},
|
||||
interpret::{Interpret, InterpretError, InterpretName, InterpretStatus, Outcome},
|
||||
inventory::Inventory,
|
||||
score::Score,
|
||||
topology::Topology,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait AlertSender {}
|
||||
pub trait AlertSender: std::fmt::Debug {}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Prometheus {}
|
||||
|
||||
impl Prometheus {
|
||||
pub fn configure_receiver(&self, receiver: PrometheusReceiver) -> Result<(), String> {
|
||||
pub fn configure_receiver(&self, _receiver: Box<&dyn PrometheusReceiver>) -> Result<(), String> {
|
||||
todo!()
|
||||
}
|
||||
pub fn configure_rule(&self, rule: PrometheusRule) {
|
||||
pub fn configure_rule(&self, _rule: Box<&dyn PrometheusRule>) {
|
||||
todo!()
|
||||
}
|
||||
pub fn configure_scrape_target(&self, target: PrometheusScrapeTarget) {
|
||||
pub fn configure_scrape_target(&self, _target: Box<&dyn PrometheusScrapeTarget>) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -36,7 +35,7 @@ pub trait PrometheusCapability {
|
||||
|
||||
impl AlertSender for Prometheus {}
|
||||
|
||||
pub trait PrometheusReceiver{
|
||||
pub trait PrometheusReceiver {
|
||||
fn get_prometheus_config(&self) -> PrometheusReceiverConfig;
|
||||
}
|
||||
|
||||
@ -45,7 +44,7 @@ pub struct PrometheusReceiverConfig {
|
||||
// config
|
||||
}
|
||||
|
||||
pub trait PrometheusRule{
|
||||
pub trait PrometheusRule {
|
||||
fn get_prometheus_config(&self) -> PrometheusRuleConfig;
|
||||
}
|
||||
|
||||
@ -74,8 +73,8 @@ pub struct PrometheusMonitoringInterpret {}
|
||||
impl<T: Topology + PrometheusCapability> Interpret<T> for PrometheusMonitoringInterpret {
|
||||
async fn execute(
|
||||
&self,
|
||||
inventory: &Inventory,
|
||||
topology: &T,
|
||||
_inventory: &Inventory,
|
||||
_topology: &T,
|
||||
) -> Result<Outcome, InterpretError> {
|
||||
todo!()
|
||||
}
|
||||
@ -96,4 +95,3 @@ impl<T: Topology + PrometheusCapability> Interpret<T> for PrometheusMonitoringIn
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use std::fmt::Debug;
|
||||
|
||||
use super::prometheus::AlertSender;
|
||||
|
||||
pub trait ScrapeTarget: Debug {
|
||||
pub trait ScrapeTarget: Debug + Send + Sync {
|
||||
type Sender: AlertSender;
|
||||
|
||||
fn install(&self, sender: &Self::Sender);
|
||||
|
Loading…
Reference in New Issue
Block a user