@@ -65,7 +65,10 @@ impl Bosun for BosunClient {
65
65
fn emit_datum ( & self , datum : & Datum ) -> BosunResult {
66
66
let timeout = 5u64 ;
67
67
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 ( ) ?;
69
72
let res = BosunClient :: send_to_bosun_api ( & self . host , "/api/put" , & encoded, timeout, StatusCode :: NO_CONTENT ) ;
70
73
info ! (
71
74
"Sent datum '{:?}' to '{:?}' with result: '{:?}'." ,
@@ -92,10 +95,15 @@ impl Bosun for BosunClient {
92
95
impl BosunClient {
93
96
/// Creates a new BosunClient.
94
97
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 {
95
103
BosunClient {
96
104
host : host. to_string ( ) ,
97
105
timeout,
98
- default_tags : HashMap :: new ( ) ,
106
+ default_tags,
99
107
}
100
108
}
101
109
@@ -254,6 +262,53 @@ pub fn now_in_ms() -> i64 {
254
262
now. timestamp ( ) * 1000 + ( now. nanosecond ( ) / 1_000_000 ) as i64
255
263
}
256
264
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
+
257
312
#[ derive( Debug , Serialize ) ]
258
313
/* cf. https://github.com/bosun-monitor/bosun/blob/master/models/silence.go#L12. 28.11.2018
259
314
Start, End time.Time
@@ -365,3 +420,43 @@ pub mod testing {
365
420
}
366
421
}
367
422
}
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
+
0 commit comments