11use std:: any:: Any ;
2+ use std:: time:: Duration ;
23use std:: { collections:: HashMap , sync:: Arc } ;
34
45use pyo3:: prelude:: * ;
@@ -32,11 +33,26 @@ pub struct MetricHistogramRef {
3233 histogram : Arc < dyn metrics:: Histogram > ,
3334}
3435
36+ #[ pyclass]
37+ pub struct MetricHistogramFloatRef {
38+ histogram : Arc < dyn metrics:: HistogramF64 > ,
39+ }
40+
41+ #[ pyclass]
42+ pub struct MetricHistogramDurationRef {
43+ histogram : Arc < dyn metrics:: HistogramDuration > ,
44+ }
45+
3546#[ pyclass]
3647pub struct MetricGaugeRef {
3748 gauge : Arc < dyn metrics:: Gauge > ,
3849}
3950
51+ #[ pyclass]
52+ pub struct MetricGaugeFloatRef {
53+ gauge : Arc < dyn metrics:: GaugeF64 > ,
54+ }
55+
4056pub fn new_metric_meter ( runtime_ref : & runtime:: RuntimeRef ) -> Option < MetricMeterRef > {
4157 runtime_ref
4258 . runtime
@@ -84,6 +100,36 @@ impl MetricMeterRef {
84100 }
85101 }
86102
103+ fn new_histogram_float (
104+ & self ,
105+ name : String ,
106+ description : Option < String > ,
107+ unit : Option < String > ,
108+ ) -> MetricHistogramFloatRef {
109+ MetricHistogramFloatRef {
110+ histogram : self . meter . inner . histogram_f64 ( build_metric_parameters (
111+ name,
112+ description,
113+ unit,
114+ ) ) ,
115+ }
116+ }
117+
118+ fn new_histogram_duration (
119+ & self ,
120+ name : String ,
121+ description : Option < String > ,
122+ unit : Option < String > ,
123+ ) -> MetricHistogramDurationRef {
124+ MetricHistogramDurationRef {
125+ histogram : self . meter . inner . histogram_duration ( build_metric_parameters (
126+ name,
127+ description,
128+ unit,
129+ ) ) ,
130+ }
131+ }
132+
87133 fn new_gauge (
88134 & self ,
89135 name : String ,
@@ -97,6 +143,20 @@ impl MetricMeterRef {
97143 . gauge ( build_metric_parameters ( name, description, unit) ) ,
98144 }
99145 }
146+
147+ fn new_gauge_float (
148+ & self ,
149+ name : String ,
150+ description : Option < String > ,
151+ unit : Option < String > ,
152+ ) -> MetricGaugeFloatRef {
153+ MetricGaugeFloatRef {
154+ gauge : self
155+ . meter
156+ . inner
157+ . gauge_f64 ( build_metric_parameters ( name, description, unit) ) ,
158+ }
159+ }
100160}
101161
102162#[ pymethods]
@@ -113,13 +173,35 @@ impl MetricHistogramRef {
113173 }
114174}
115175
176+ #[ pymethods]
177+ impl MetricHistogramFloatRef {
178+ fn record ( & self , value : f64 , attrs_ref : & MetricAttributesRef ) {
179+ self . histogram . record ( value, & attrs_ref. attrs ) ;
180+ }
181+ }
182+
183+ #[ pymethods]
184+ impl MetricHistogramDurationRef {
185+ fn record ( & self , value_ms : u64 , attrs_ref : & MetricAttributesRef ) {
186+ self . histogram
187+ . record ( Duration :: from_millis ( value_ms) , & attrs_ref. attrs ) ;
188+ }
189+ }
190+
116191#[ pymethods]
117192impl MetricGaugeRef {
118193 fn set ( & self , value : u64 , attrs_ref : & MetricAttributesRef ) {
119194 self . gauge . record ( value, & attrs_ref. attrs ) ;
120195 }
121196}
122197
198+ #[ pymethods]
199+ impl MetricGaugeFloatRef {
200+ fn set ( & self , value : f64 , attrs_ref : & MetricAttributesRef ) {
201+ self . gauge . record ( value, & attrs_ref. attrs ) ;
202+ }
203+ }
204+
123205fn build_metric_parameters (
124206 name : String ,
125207 description : Option < String > ,
@@ -192,16 +274,18 @@ pub struct BufferedMetricUpdate {
192274}
193275
194276#[ derive( Clone ) ]
195- pub struct BufferedMetricUpdateValue ( metrics:: MetricUpdateVal ) ;
277+ pub enum BufferedMetricUpdateValue {
278+ U64 ( u64 ) ,
279+ U128 ( u128 ) ,
280+ F64 ( f64 ) ,
281+ }
196282
197283impl IntoPy < PyObject > for BufferedMetricUpdateValue {
198284 fn into_py ( self , py : Python ) -> PyObject {
199- match self . 0 {
200- metrics:: MetricUpdateVal :: Delta ( v) => v. into_py ( py) ,
201- metrics:: MetricUpdateVal :: DeltaF64 ( v) => v. into_py ( py) ,
202- metrics:: MetricUpdateVal :: Value ( v) => v. into_py ( py) ,
203- metrics:: MetricUpdateVal :: ValueF64 ( v) => v. into_py ( py) ,
204- metrics:: MetricUpdateVal :: Duration ( v) => v. as_millis ( ) . into_py ( py) ,
285+ match self {
286+ BufferedMetricUpdateValue :: U64 ( v) => v. into_py ( py) ,
287+ BufferedMetricUpdateValue :: U128 ( v) => v. into_py ( py) ,
288+ BufferedMetricUpdateValue :: F64 ( v) => v. into_py ( py) ,
205289 }
206290 }
207291}
@@ -236,16 +320,18 @@ impl CustomMetricAttributes for BufferedMetricAttributes {
236320pub fn convert_metric_events < ' p > (
237321 py : Python < ' p > ,
238322 events : Vec < MetricEvent < BufferedMetricRef > > ,
323+ durations_as_seconds : bool ,
239324) -> Vec < BufferedMetricUpdate > {
240325 events
241326 . into_iter ( )
242- . filter_map ( |e| convert_metric_event ( py, e) )
327+ . filter_map ( |e| convert_metric_event ( py, e, durations_as_seconds ) )
243328 . collect ( )
244329}
245330
246331fn convert_metric_event < ' p > (
247332 py : Python < ' p > ,
248333 event : MetricEvent < BufferedMetricRef > ,
334+ durations_as_seconds : bool ,
249335) -> Option < BufferedMetricUpdate > {
250336 match event {
251337 // Create the metric and put it on the lazy ref
@@ -262,9 +348,19 @@ fn convert_metric_event<'p>(
262348 description : Some ( params. description )
263349 . filter ( |s| !s. is_empty ( ) )
264350 . map ( |s| s. to_string ( ) ) ,
265- unit : Some ( params. unit )
266- . filter ( |s| !s. is_empty ( ) )
267- . map ( |s| s. to_string ( ) ) ,
351+ unit : if matches ! ( kind, metrics:: MetricKind :: HistogramDuration )
352+ && params. unit == "duration"
353+ {
354+ if durations_as_seconds {
355+ Some ( "s" . to_owned ( ) )
356+ } else {
357+ Some ( "ms" . to_owned ( ) )
358+ }
359+ } else if params. unit . is_empty ( ) {
360+ None
361+ } else {
362+ Some ( params. unit . to_string ( ) )
363+ } ,
268364 kind : match kind {
269365 metrics:: MetricKind :: Counter => 0 ,
270366 metrics:: MetricKind :: Gauge | metrics:: MetricKind :: GaugeF64 => 1 ,
@@ -324,7 +420,18 @@ fn convert_metric_event<'p>(
324420 update,
325421 } => Some ( BufferedMetricUpdate {
326422 metric : instrument. get ( ) . clone ( ) . 0 . clone ( ) ,
327- value : BufferedMetricUpdateValue ( update) ,
423+ value : match update {
424+ metrics:: MetricUpdateVal :: Duration ( v) if durations_as_seconds => {
425+ BufferedMetricUpdateValue :: F64 ( v. as_secs_f64 ( ) )
426+ }
427+ metrics:: MetricUpdateVal :: Duration ( v) => {
428+ BufferedMetricUpdateValue :: U128 ( v. as_millis ( ) )
429+ }
430+ metrics:: MetricUpdateVal :: Delta ( v) => BufferedMetricUpdateValue :: U64 ( v) ,
431+ metrics:: MetricUpdateVal :: DeltaF64 ( v) => BufferedMetricUpdateValue :: F64 ( v) ,
432+ metrics:: MetricUpdateVal :: Value ( v) => BufferedMetricUpdateValue :: U64 ( v) ,
433+ metrics:: MetricUpdateVal :: ValueF64 ( v) => BufferedMetricUpdateValue :: F64 ( v) ,
434+ } ,
328435 attributes : attributes
329436 . get ( )
330437 . clone ( )
0 commit comments