Skip to content

Commit a8e2053

Browse files
committed
updates:
- separated `NotificationConfig` from target config
1 parent 759e039 commit a8e2053

File tree

5 files changed

+79
-42
lines changed

5 files changed

+79
-42
lines changed

src/alerts/alert_enums.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/*
2+
* Parseable Server (C) 2022 - 2024 Parseable, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*
17+
*/
18+
119
use std::fmt::{self, Display};
220

321
use derive_more::derive::FromStr;

src/alerts/alert_structs.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/*
2+
* Parseable Server (C) 2022 - 2024 Parseable, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*
17+
*/
18+
119
use std::collections::HashMap;
220

321
use chrono::{DateTime, Utc};
@@ -13,7 +31,7 @@ use crate::{
1331
LogicalOperator, NotificationState, Severity, WhereConfigOperator,
1432
},
1533
alert_traits::AlertTrait,
16-
target::TARGETS,
34+
target::{NotificationConfig, TARGETS},
1735
},
1836
query::resolve_stream_names,
1937
};
@@ -36,14 +54,21 @@ pub struct Context {
3654
pub alert_info: AlertInfo,
3755
pub deployment_info: DeploymentInfo,
3856
pub message: String,
57+
pub notification_config: NotificationConfig,
3958
}
4059

4160
impl Context {
42-
pub fn new(alert_info: AlertInfo, deployment_info: DeploymentInfo, message: String) -> Self {
61+
pub fn new(
62+
alert_info: AlertInfo,
63+
deployment_info: DeploymentInfo,
64+
notification_config: NotificationConfig,
65+
message: String,
66+
) -> Self {
4367
Self {
4468
alert_info,
4569
deployment_info,
4670
message,
71+
notification_config,
4772
}
4873
}
4974

@@ -226,6 +251,7 @@ pub struct AlertRequest {
226251
pub query: String,
227252
pub alert_type: AlertType,
228253
pub threshold_config: ThresholdConfig,
254+
pub notification_config: NotificationConfig,
229255
pub eval_config: EvalConfig,
230256
pub targets: Vec<Ulid>,
231257
pub tags: Option<Vec<String>>,
@@ -251,6 +277,7 @@ impl AlertRequest {
251277
targets: self.targets,
252278
state: AlertState::default(),
253279
notification_state: NotificationState::Notify,
280+
notification_config: self.notification_config,
254281
created: Utc::now(),
255282
tags: self.tags,
256283
};
@@ -276,6 +303,7 @@ pub struct AlertConfig {
276303
#[serde(default)]
277304
pub state: AlertState,
278305
pub notification_state: NotificationState,
306+
pub notification_config: NotificationConfig,
279307
pub created: DateTime<Utc>,
280308
pub tags: Option<Vec<String>>,
281309
}

src/alerts/alert_types.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
alert_traits::{AlertTrait, MessageCreation},
3232
alerts_utils::{evaluate_condition, execute_alert_query, extract_time_range},
3333
is_query_aggregate,
34-
target::{self, TARGETS},
34+
target::{self, NotificationConfig},
3535
},
3636
handlers::http::query::create_streams_for_distributed,
3737
option::Mode,
@@ -58,6 +58,7 @@ pub struct ThresholdAlert {
5858
#[serde(default)]
5959
pub state: AlertState,
6060
pub notification_state: NotificationState,
61+
pub notification_config: NotificationConfig,
6162
pub created: DateTime<Utc>,
6263
pub tags: Option<Vec<String>>,
6364
pub datasets: Vec<String>,
@@ -105,19 +106,15 @@ impl AlertTrait for ThresholdAlert {
105106
};
106107

107108
// validate that target repeat notifs !> eval_frequency
108-
for target_id in &self.targets {
109-
let target = TARGETS.get_target_by_id(target_id).await?;
110-
match &target.notification_config.times {
111-
target::Retry::Infinite => {}
112-
target::Retry::Finite(repeat) => {
113-
let notif_duration =
114-
Duration::from_secs(60 * target.notification_config.interval)
115-
* *repeat as u32;
116-
if (notif_duration.as_secs_f64()).gt(&((eval_frequency * 60) as f64)) {
117-
return Err(AlertError::Metadata(
118-
"evalFrequency should be greater than target repetition interval",
119-
));
120-
}
109+
match &self.notification_config.times {
110+
target::Retry::Infinite => {}
111+
target::Retry::Finite(repeat) => {
112+
let notif_duration =
113+
Duration::from_secs(60 * self.notification_config.interval) * *repeat as u32;
114+
if (notif_duration.as_secs_f64()).gt(&((eval_frequency * 60) as f64)) {
115+
return Err(AlertError::Metadata(
116+
"evalFrequency should be greater than target repetition interval",
117+
));
121118
}
122119
}
123120
}
@@ -329,6 +326,7 @@ impl From<AlertConfig> for ThresholdAlert {
329326
targets: value.targets,
330327
state: value.state,
331328
notification_state: value.notification_state,
329+
notification_config: value.notification_config,
332330
created: value.created,
333331
tags: value.tags,
334332
datasets: value.datasets,
@@ -350,6 +348,7 @@ impl From<ThresholdAlert> for AlertConfig {
350348
targets: val.targets,
351349
state: val.state,
352350
notification_state: val.notification_state,
351+
notification_config: val.notification_config,
353352
created: val.created,
354353
tags: val.tags,
355354
datasets: val.datasets,

src/alerts/mod.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub use crate::alerts::alert_structs::{
5353
};
5454
use crate::alerts::alert_traits::{AlertManagerTrait, AlertTrait};
5555
use crate::alerts::alert_types::ThresholdAlert;
56-
use crate::alerts::target::TARGETS;
56+
use crate::alerts::target::{NotificationConfig, TARGETS};
5757
use crate::handlers::http::fetch_schema;
5858
use crate::handlers::http::query::create_streams_for_distributed;
5959
use crate::option::Mode;
@@ -130,6 +130,7 @@ impl AlertConfig {
130130
targets,
131131
state,
132132
notification_state: NotificationState::Notify,
133+
notification_config: NotificationConfig::default(),
133134
created: Utc::now(),
134135
tags: None,
135136
};
@@ -603,19 +604,15 @@ impl AlertConfig {
603604
};
604605

605606
// validate that target repeat notifs !> eval_frequency
606-
for target_id in &self.targets {
607-
let target = TARGETS.get_target_by_id(target_id).await?;
608-
match &target.notification_config.times {
609-
target::Retry::Infinite => {}
610-
target::Retry::Finite(repeat) => {
611-
let notif_duration =
612-
Duration::from_secs(60 * target.notification_config.interval)
613-
* *repeat as u32;
614-
if (notif_duration.as_secs_f64()).gt(&((eval_frequency * 60) as f64)) {
615-
return Err(AlertError::Metadata(
616-
"evalFrequency should be greater than target repetition interval",
617-
));
618-
}
607+
match &self.notification_config.times {
608+
target::Retry::Infinite => {}
609+
target::Retry::Finite(repeat) => {
610+
let notif_duration =
611+
Duration::from_secs(60 * self.notification_config.interval) * *repeat as u32;
612+
if (notif_duration.as_secs_f64()).gt(&((eval_frequency * 60) as f64)) {
613+
return Err(AlertError::Metadata(
614+
"evalFrequency should be greater than target repetition interval",
615+
));
619616
}
620617
}
621618
}
@@ -675,6 +672,7 @@ impl AlertConfig {
675672
self.severity.clone().to_string(),
676673
),
677674
DeploymentInfo::new(deployment_instance, deployment_id, deployment_mode),
675+
self.notification_config.clone(),
678676
String::default(),
679677
)
680678
}

src/alerts/target.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ pub struct Target {
151151
pub name: String,
152152
#[serde(flatten)]
153153
pub target: TargetType,
154-
pub notification_config: Timeout,
155154
#[serde(default = "Ulid::new")]
156155
pub id: Ulid,
157156
}
@@ -170,7 +169,6 @@ impl Target {
170169
"name":self.name,
171170
"type":"slack",
172171
"endpoint":masked_endpoint,
173-
"notificationConfig":self.notification_config,
174172
"id":self.id
175173
})
176174
}
@@ -187,7 +185,6 @@ impl Target {
187185
"endpoint":masked_endpoint,
188186
"headers":other_web_hook.headers,
189187
"skipTlsCheck":other_web_hook.skip_tls_check,
190-
"notificationConfig":self.notification_config,
191188
"id":self.id
192189
})
193190
}
@@ -207,7 +204,6 @@ impl Target {
207204
"username":auth.username,
208205
"password":password,
209206
"skipTlsCheck":alert_manager.skip_tls_check,
210-
"notificationConfig":self.notification_config,
211207
"id":self.id
212208
})
213209
} else {
@@ -218,7 +214,6 @@ impl Target {
218214
"username":Value::Null,
219215
"password":Value::Null,
220216
"skipTlsCheck":alert_manager.skip_tls_check,
221-
"notificationConfig":self.notification_config,
222217
"id":self.id
223218
})
224219
}
@@ -228,7 +223,7 @@ impl Target {
228223

229224
pub fn call(&self, context: Context) {
230225
trace!("target.call context- {context:?}");
231-
let timeout = &self.notification_config;
226+
let timeout = context.notification_config.clone();
232227
let resolves = context.alert_info.alert_state;
233228
let mut state = timeout.state.lock().unwrap();
234229
trace!("target.call state- {state:?}");
@@ -245,7 +240,7 @@ impl Target {
245240
state.timed_out = true;
246241
state.awaiting_resolve = true;
247242
drop(state);
248-
self.spawn_timeout_task(timeout, context.clone());
243+
self.spawn_timeout_task(&timeout, context.clone());
249244
}
250245
}
251246
alert_state @ AlertState::NotTriggered => {
@@ -268,7 +263,7 @@ impl Target {
268263
}
269264
}
270265

271-
fn spawn_timeout_task(&self, target_timeout: &Timeout, alert_context: Context) {
266+
fn spawn_timeout_task(&self, target_timeout: &NotificationConfig, alert_context: Context) {
272267
trace!("repeat-\n{target_timeout:?}");
273268
let state = Arc::clone(&target_timeout.state);
274269
let retry = target_timeout.times;
@@ -383,7 +378,7 @@ impl TryFrom<TargetVerifier> for Target {
383378
type Error = String;
384379

385380
fn try_from(value: TargetVerifier) -> Result<Self, Self::Error> {
386-
let mut timeout = Timeout::default();
381+
let mut timeout = NotificationConfig::default();
387382

388383
// Default is Infinite in case of alertmanager
389384
if matches!(value.target, TargetType::AlertManager(_)) {
@@ -405,7 +400,6 @@ impl TryFrom<TargetVerifier> for Target {
405400
Ok(Target {
406401
name: value.name,
407402
target: value.target,
408-
notification_config: timeout,
409403
id: value.id,
410404
})
411405
}
@@ -599,15 +593,15 @@ impl CallableTarget for AlertManager {
599593
}
600594

601595
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
602-
pub struct Timeout {
596+
pub struct NotificationConfig {
603597
pub interval: u64,
604598
#[serde(default = "Retry::default")]
605599
pub times: Retry,
606600
#[serde(skip)]
607601
pub state: Arc<Mutex<TimeoutState>>,
608602
}
609603

610-
impl Default for Timeout {
604+
impl Default for NotificationConfig {
611605
fn default() -> Self {
612606
Self {
613607
interval: 1,

0 commit comments

Comments
 (0)