Skip to content

Commit b190c35

Browse files
committed
Add default tags to bosun client
1 parent 1e510fd commit b190c35

File tree

2 files changed

+98
-3
lines changed

2 files changed

+98
-3
lines changed

watch-autoscaling/src/bosun.rs

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ impl Bosun for BosunClient {
6565
fn emit_datum(&self, datum: &Datum) -> BosunResult {
6666
let timeout = 5u64;
6767

68-
let encoded = datum.to_json()?;
68+
let mut internal_datum: InternalDatum = datum.into();
69+
internal_datum.add_tags(&self.default_tags);
70+
71+
let encoded = internal_datum.to_json()?;
6972
let res = BosunClient::send_to_bosun_api(&self.host, "/api/put", &encoded, timeout, StatusCode::NO_CONTENT);
7073
info!(
7174
"Sent datum '{:?}' to '{:?}' with result: '{:?}'.",
@@ -92,10 +95,15 @@ impl Bosun for BosunClient {
9295
impl BosunClient {
9396
/// Creates a new BosunClient.
9497
pub fn new(host: &str, timeout: u64) -> BosunClient {
98+
Self::with_tags(host, timeout, Tags::new())
99+
}
100+
101+
/// Creates a new BosunClient with default tags
102+
pub fn with_tags(host: &str, timeout: u64, default_tags: Tags) -> BosunClient {
95103
BosunClient {
96104
host: host.to_string(),
97105
timeout,
98-
default_tags: HashMap::new(),
106+
default_tags,
99107
}
100108
}
101109

@@ -254,6 +262,53 @@ pub fn now_in_ms() -> i64 {
254262
now.timestamp() * 1000 + (now.nanosecond() / 1_000_000) as i64
255263
}
256264

265+
266+
/// Represents a metric datum used solely for internal purpose, i.e., adding default tags and
267+
/// sending the datum.
268+
#[derive(Debug, Serialize)]
269+
struct InternalDatum<'a> {
270+
/// Metric name
271+
pub metric: &'a str,
272+
/// Unix timestamp in either _s_ or _ms_
273+
pub timestamp: i64,
274+
/// Value as string representation
275+
pub value: &'a str,
276+
/// Tags for this metric datum
277+
pub tags: HashMap<&'a str, &'a str>,
278+
}
279+
280+
impl<'a> From<&'a Datum<'a>> for InternalDatum<'a> {
281+
fn from(datum: &'a Datum<'a>) -> InternalDatum<'a> {
282+
let mut tags = HashMap::new();
283+
for (k,v) in datum.tags {
284+
tags.insert(k.as_ref(),v.as_ref());
285+
}
286+
InternalDatum {
287+
metric: datum.metric,
288+
timestamp: datum.timestamp,
289+
value: datum.value,
290+
tags,
291+
}
292+
}
293+
}
294+
295+
impl<'a> InternalDatum<'a> {
296+
fn add_tags(&mut self, tags: &'a Tags) {
297+
for (k,v) in tags {
298+
self.tags.insert(k.as_ref(),v.as_ref());
299+
}
300+
}
301+
302+
pub fn to_json(&self) -> Result<String, BosunError> {
303+
let json = serde_json::to_string(&self)
304+
//TODO: Use context to carry original error on
305+
.map_err(|_| BosunError::JsonParseError)?;
306+
debug!("InternalDatum::to_json '{:?}', '{:?}'.", &self, json);
307+
308+
Ok(json)
309+
}
310+
}
311+
257312
#[derive(Debug, Serialize)]
258313
/* cf. https://github.com/bosun-monitor/bosun/blob/master/models/silence.go#L12. 28.11.2018
259314
Start, End time.Time
@@ -365,3 +420,43 @@ pub mod testing {
365420
}
366421
}
367422
}
423+
424+
#[cfg(test)]
425+
mod tests {
426+
use super::*;
427+
428+
use spectral::prelude::*;
429+
430+
#[test]
431+
fn to_internal_datum() {
432+
let mut default_tags = Tags::new();
433+
default_tags.insert("default_tag1".to_string(), "value1".to_string());
434+
let mut tags = Tags::new();
435+
tags.insert("tag2".to_string(), "value2".to_string());
436+
tags.insert("tag3".to_string(), "value3".to_string());
437+
let datum = Datum::now("a_test_metric", "42", &tags);
438+
439+
let mut internal_datum: InternalDatum = (&datum).into();
440+
internal_datum.add_tags(&default_tags);
441+
442+
assert_that(&internal_datum.tags).has_length(3);
443+
}
444+
445+
#[test]
446+
fn to_json() {
447+
let mut default_tags = Tags::new();
448+
default_tags.insert("default_tag1".to_string(), "value1".to_string());
449+
let tags = Tags::new();
450+
let datum = Datum::new("a_test_metric", 1545918681110, "42", &tags);
451+
let mut internal_datum: InternalDatum = (&datum).into();
452+
internal_datum.add_tags(&default_tags);
453+
454+
let expected =
455+
r#"{"metric":"a_test_metric","timestamp":1545918681110,"value":"42","tags":{"default_tag1":"value1"}}"#.to_string();
456+
457+
let json = internal_datum.to_json();
458+
459+
assert_that(&json).is_ok().is_equal_to(&expected);
460+
}
461+
}
462+

watch-autoscaling/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ fn handler(input: Value, ctx: &Context) -> Result<(), Error> {
136136
debug!("Decrypted encrypted configuration.");
137137
info!("Invocation initialization complete.");
138138

139-
let bosun = BosunClient::new(config.bosun.uri().as_str(), 3);
139+
let bosun = BosunClient::with_tags(config.bosun.uri().as_str(), 3, config.bosun.tags.clone());
140140
debug!("Created Bosun client.");
141141

142142
do_handler(input, ctx, &config, &bosun)

0 commit comments

Comments
 (0)