@@ -299,6 +299,10 @@ impl Metric {
299
299
MetricBuilder { metric }
300
300
}
301
301
302
+ pub fn parse_statsd ( string : & str ) -> Result < Self , ParseMetricError > {
303
+ parse_metric_opt ( string) . ok_or ( ParseMetricError ( ( ) ) )
304
+ }
305
+
302
306
pub fn incr ( name : impl Into < MetricStr > ) -> MetricBuilder {
303
307
Self :: build ( name, MetricValue :: Counter ( 1.0 ) )
304
308
}
@@ -353,6 +357,52 @@ impl MetricBuilder {
353
357
}
354
358
}
355
359
360
+ #[ derive( Debug ) ]
361
+ pub struct ParseMetricError ( ( ) ) ;
362
+
363
+ impl std:: error:: Error for ParseMetricError { }
364
+
365
+ impl fmt:: Display for ParseMetricError {
366
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
367
+ f. write_str ( "invalid metric string" )
368
+ }
369
+ }
370
+
371
+ fn parse_metric_opt ( string : & str ) -> Option < Metric > {
372
+ let mut components = string. split ( '|' ) ;
373
+
374
+ let ( mri_str, value_str) = components. next ( ) ?. split_once ( ':' ) ?;
375
+ let ( name, unit) = match mri_str. split_once ( '@' ) {
376
+ Some ( ( name, unit_str) ) => ( name, unit_str. parse ( ) . ok ( ) ?) ,
377
+ None => ( mri_str, MetricUnit :: None ) ,
378
+ } ;
379
+
380
+ let ty = components. next ( ) . and_then ( |s| s. parse ( ) . ok ( ) ) ?;
381
+ let value = match ty {
382
+ MetricType :: Counter => MetricValue :: Counter ( value_str. parse ( ) . ok ( ) ?) ,
383
+ MetricType :: Distribution => MetricValue :: Distribution ( value_str. parse ( ) . ok ( ) ?) ,
384
+ MetricType :: Set => MetricValue :: Set ( value_str. parse ( ) . ok ( ) ?) ,
385
+ MetricType :: Gauge => MetricValue :: Gauge ( value_str. parse ( ) . ok ( ) ?) ,
386
+ } ;
387
+
388
+ let mut builder = Metric :: build ( name. to_owned ( ) , value) . with_unit ( unit) ;
389
+
390
+ for component in components {
391
+ if let Some ( '#' ) = component. chars ( ) . next ( ) {
392
+ for pair in component. get ( 1 ..) ?. split ( ',' ) {
393
+ let mut key_value = pair. splitn ( 2 , ':' ) ;
394
+
395
+ let key = key_value. next ( ) ?. to_owned ( ) ;
396
+ let value = key_value. next ( ) . unwrap_or_default ( ) . to_owned ( ) ;
397
+
398
+ builder = builder. with_tag ( key, value) ;
399
+ }
400
+ }
401
+ }
402
+
403
+ Some ( builder. finish ( ) )
404
+ }
405
+
356
406
pub struct MetricAggregator {
357
407
inner : Arc < Mutex < AggregatorInner > > ,
358
408
handle : Option < JoinHandle < ( ) > > ,
0 commit comments