@@ -311,7 +311,7 @@ impl<S: EncodeLabelSet, V: EncodeExemplarValue> TryFrom<&Exemplar<S, V>>
311311
312312 Ok ( openmetrics_data_model:: Exemplar {
313313 value,
314- timestamp : Default :: default ( ) ,
314+ timestamp : exemplar . timestamp . map ( Into :: into ) ,
315315 label : labels,
316316 } )
317317 }
@@ -442,6 +442,8 @@ impl std::fmt::Write for LabelValueEncoder<'_> {
442442
443443#[ cfg( test) ]
444444mod tests {
445+ use prost_types:: Timestamp ;
446+
445447 use super :: * ;
446448 use crate :: metrics:: counter:: Counter ;
447449 use crate :: metrics:: exemplar:: { CounterWithExemplar , HistogramWithExemplars } ;
@@ -454,6 +456,7 @@ mod tests {
454456 use std:: collections:: HashSet ;
455457 use std:: sync:: atomic:: AtomicI64 ;
456458 use std:: sync:: atomic:: AtomicU64 ;
459+ use std:: time:: SystemTime ;
457460
458461 #[ test]
459462 fn encode_counter_int ( ) {
@@ -531,6 +534,9 @@ mod tests {
531534
532535 #[ test]
533536 fn encode_counter_with_exemplar ( ) {
537+ let now = SystemTime :: now ( ) ;
538+ let now_ts: Timestamp = now. into ( ) ;
539+
534540 let mut registry = Registry :: default ( ) ;
535541
536542 let counter_with_exemplar: CounterWithExemplar < Vec < ( String , f64 ) > , f64 > =
@@ -541,7 +547,7 @@ mod tests {
541547 counter_with_exemplar. clone ( ) ,
542548 ) ;
543549
544- counter_with_exemplar. inc_by ( 1.0 , Some ( vec ! [ ( "user_id" . to_string( ) , 42.0 ) ] ) ) ;
550+ counter_with_exemplar. inc_by ( 1.0 , Some ( vec ! [ ( "user_id" . to_string( ) , 42.0 ) ] ) , None ) ;
545551
546552 let metric_set = encode ( & registry) . unwrap ( ) ;
547553
@@ -563,6 +569,8 @@ mod tests {
563569 let exemplar = value. exemplar . as_ref ( ) . unwrap ( ) ;
564570 assert_eq ! ( 1.0 , exemplar. value) ;
565571
572+ assert ! ( exemplar. timestamp. is_none( ) ) ;
573+
566574 let expected_label = {
567575 openmetrics_data_model:: Label {
568576 name : "user_id" . to_string ( ) ,
@@ -573,6 +581,30 @@ mod tests {
573581 }
574582 _ => panic ! ( "wrong value type" ) ,
575583 }
584+
585+ counter_with_exemplar. inc_by ( 1.0 , Some ( vec ! [ ( "user_id" . to_string( ) , 99.0 ) ] ) , Some ( now) ) ;
586+
587+ match extract_metric_point_value ( & encode ( & registry) . unwrap ( ) ) {
588+ openmetrics_data_model:: metric_point:: Value :: CounterValue ( value) => {
589+ // The counter should be encoded as `DoubleValue`
590+ let expected = openmetrics_data_model:: counter_value:: Total :: DoubleValue ( 2.0 ) ;
591+ assert_eq ! ( Some ( expected) , value. total) ;
592+
593+ let exemplar = value. exemplar . as_ref ( ) . unwrap ( ) ;
594+ assert_eq ! ( 1.0 , exemplar. value) ;
595+
596+ assert_eq ! ( & now_ts, exemplar. timestamp. as_ref( ) . unwrap( ) ) ;
597+
598+ let expected_label = {
599+ openmetrics_data_model:: Label {
600+ name : "user_id" . to_string ( ) ,
601+ value : "99.0" . to_string ( ) ,
602+ }
603+ } ;
604+ assert_eq ! ( vec![ expected_label] , exemplar. label) ;
605+ }
606+ _ => panic ! ( "wrong value type" ) ,
607+ }
576608 }
577609
578610 #[ test]
@@ -784,10 +816,14 @@ mod tests {
784816
785817 #[ test]
786818 fn encode_histogram_with_exemplars ( ) {
819+ let now = SystemTime :: now ( ) ;
820+ let now_ts: Timestamp = now. into ( ) ;
821+
787822 let mut registry = Registry :: default ( ) ;
788823 let histogram = HistogramWithExemplars :: new ( exponential_buckets ( 1.0 , 2.0 , 10 ) ) ;
789824 registry. register ( "my_histogram" , "My histogram" , histogram. clone ( ) ) ;
790- histogram. observe ( 1.0 , Some ( vec ! [ ( "user_id" . to_string( ) , 42u64 ) ] ) ) ;
825+
826+ histogram. observe ( 1.0 , Some ( vec ! [ ( "user_id" . to_string( ) , 42u64 ) ] ) , None ) ;
791827
792828 let metric_set = encode ( & registry) . unwrap ( ) ;
793829
@@ -805,6 +841,8 @@ mod tests {
805841 let exemplar = value. buckets . first ( ) . unwrap ( ) . exemplar . as_ref ( ) . unwrap ( ) ;
806842 assert_eq ! ( 1.0 , exemplar. value) ;
807843
844+ assert ! ( exemplar. timestamp. is_none( ) ) ;
845+
808846 let expected_label = {
809847 openmetrics_data_model:: Label {
810848 name : "user_id" . to_string ( ) ,
@@ -815,6 +853,26 @@ mod tests {
815853 }
816854 _ => panic ! ( "wrong value type" ) ,
817855 }
856+
857+ histogram. observe ( 2.0 , Some ( vec ! [ ( "user_id" . to_string( ) , 99u64 ) ] ) , Some ( now) ) ;
858+
859+ match extract_metric_point_value ( & encode ( & registry) . unwrap ( ) ) {
860+ openmetrics_data_model:: metric_point:: Value :: HistogramValue ( value) => {
861+ let exemplar = value. buckets . get ( 1 ) . unwrap ( ) . exemplar . as_ref ( ) . unwrap ( ) ;
862+ assert_eq ! ( 2.0 , exemplar. value) ;
863+
864+ assert_eq ! ( & now_ts, exemplar. timestamp. as_ref( ) . unwrap( ) ) ;
865+
866+ let expected_label = {
867+ openmetrics_data_model:: Label {
868+ name : "user_id" . to_string ( ) ,
869+ value : "99" . to_string ( ) ,
870+ }
871+ } ;
872+ assert_eq ! ( vec![ expected_label] , exemplar. label) ;
873+ }
874+ _ => panic ! ( "wrong value type" ) ,
875+ }
818876 }
819877
820878 #[ test]
0 commit comments