6666
6767use opentelemetry:: global;
6868use opentelemetry:: sdk:: {
69- export:: metrics:: { CheckpointSet , ExportKind , Histogram , Record , Sum } ,
69+ export:: metrics:: { CheckpointSet , ExportKindSelector , Histogram , LastValue , Record , Sum } ,
7070 metrics:: {
71- aggregators:: { HistogramAggregator , SumAggregator } ,
71+ aggregators:: { HistogramAggregator , LastValueAggregator , SumAggregator } ,
7272 controllers,
7373 selectors:: simple:: Selector ,
7474 PullController ,
@@ -77,9 +77,7 @@ use opentelemetry::sdk::{
7777} ;
7878use opentelemetry:: {
7979 labels,
80- metrics:: {
81- registry:: RegistryMeterProvider , Descriptor , InstrumentKind , MetricsError , NumberKind ,
82- } ,
80+ metrics:: { registry:: RegistryMeterProvider , MetricsError , NumberKind } ,
8381 KeyValue ,
8482} ;
8583use std:: collections:: HashMap ;
@@ -92,7 +90,8 @@ use sanitize::sanitize;
9290
9391/// Cache disabled by default.
9492const DEFAULT_CACHE_PERIOD : Duration = Duration :: from_secs ( 0 ) ;
95- const EXPORT_KIND : ExportKind = ExportKind :: Cumulative ;
93+
94+ const EXPORT_KIND_SELECTOR : ExportKindSelector = ExportKindSelector :: Cumulative ;
9695
9796/// Create a new prometheus exporter builder.
9897pub fn exporter ( ) -> ExporterBuilder {
@@ -181,7 +180,7 @@ impl ExporterBuilder {
181180 . default_histogram_boundaries
182181 . unwrap_or_else ( || vec ! [ 0.5 , 0.9 , 0.99 ] ) ;
183182 let selector = Box :: new ( Selector :: Histogram ( default_histogram_boundaries. clone ( ) ) ) ;
184- let mut controller_builder = controllers:: pull ( selector, Box :: new ( EXPORT_KIND ) )
183+ let mut controller_builder = controllers:: pull ( selector, Box :: new ( EXPORT_KIND_SELECTOR ) )
185184 . with_cache_period ( self . cache_period . unwrap_or ( DEFAULT_CACHE_PERIOD ) )
186185 . with_memory ( true ) ;
187186 if let Some ( resource) = self . resource {
@@ -256,17 +255,6 @@ impl PrometheusExporter {
256255 . map_err ( Into :: into)
257256 . map ( |locked| locked. provider ( ) )
258257 }
259-
260- /// Determine the export kind this exporter should use for a given instrument
261- /// and descriptor.
262- pub fn export_kind_for ( & self , _descriptor : & Descriptor , _kind : & InstrumentKind ) -> ExportKind {
263- // NOTE: Summary values should use Delta aggregation, then be
264- // combined into a sliding window, see the TODO below.
265- // NOTE: Prometheus also supports a "GaugeDelta" exposition format,
266- // which is expressed as a delta histogram. Need to understand if this
267- // should be a default behavior for ValueRecorder/ValueObserver.
268- EXPORT_KIND
269- }
270258}
271259
272260#[ derive( Debug ) ]
@@ -296,9 +284,10 @@ impl prometheus::core::Collector for Collector {
296284 return metrics;
297285 }
298286
299- if let Err ( err) = controller. try_for_each ( & EXPORT_KIND , & mut |record| {
287+ if let Err ( err) = controller. try_for_each ( & EXPORT_KIND_SELECTOR , & mut |record| {
300288 let agg = record. aggregator ( ) . ok_or ( MetricsError :: NoDataCollected ) ?;
301289 let number_kind = record. descriptor ( ) . number_kind ( ) ;
290+ let instrument_kind = record. descriptor ( ) . instrument_kind ( ) ;
302291
303292 let mut label_keys = Vec :: new ( ) ;
304293 let mut label_values = Vec :: new ( ) ;
@@ -309,7 +298,15 @@ impl prometheus::core::Collector for Collector {
309298 if let Some ( hist) = agg. as_any ( ) . downcast_ref :: < HistogramAggregator > ( ) {
310299 metrics. push ( build_histogram ( hist, number_kind, desc, label_values) ?) ;
311300 } else if let Some ( sum) = agg. as_any ( ) . downcast_ref :: < SumAggregator > ( ) {
312- metrics. push ( build_counter ( sum, number_kind, desc, label_values) ?) ;
301+ let counter = if instrument_kind. monotonic ( ) {
302+ build_monotonic_counter ( sum, number_kind, desc, label_values) ?
303+ } else {
304+ build_non_monotonic_counter ( sum, number_kind, desc, label_values) ?
305+ } ;
306+
307+ metrics. push ( counter) ;
308+ } else if let Some ( last) = agg. as_any ( ) . downcast_ref :: < LastValueAggregator > ( ) {
309+ metrics. push ( build_last_value ( last, number_kind, desc, label_values) ?) ;
313310 }
314311
315312 Ok ( ( ) )
@@ -324,7 +321,59 @@ impl prometheus::core::Collector for Collector {
324321 }
325322}
326323
327- fn build_counter (
324+ fn build_last_value (
325+ lv : & LastValueAggregator ,
326+ kind : & NumberKind ,
327+ desc : prometheus:: core:: Desc ,
328+ labels : Vec < KeyValue > ,
329+ ) -> Result < prometheus:: proto:: MetricFamily , MetricsError > {
330+ let ( last_value, _) = lv. last_value ( ) ?;
331+
332+ let mut g = prometheus:: proto:: Gauge :: default ( ) ;
333+ g. set_value ( last_value. to_f64 ( kind) ) ;
334+
335+ let mut m = prometheus:: proto:: Metric :: default ( ) ;
336+ m. set_label ( protobuf:: RepeatedField :: from_vec (
337+ labels. into_iter ( ) . map ( build_label_pair) . collect ( ) ,
338+ ) ) ;
339+ m. set_gauge ( g) ;
340+
341+ let mut mf = prometheus:: proto:: MetricFamily :: default ( ) ;
342+ mf. set_name ( desc. fq_name ) ;
343+ mf. set_help ( desc. help ) ;
344+ mf. set_field_type ( prometheus:: proto:: MetricType :: GAUGE ) ;
345+ mf. set_metric ( protobuf:: RepeatedField :: from_vec ( vec ! [ m] ) ) ;
346+
347+ Ok ( mf)
348+ }
349+
350+ fn build_non_monotonic_counter (
351+ sum : & SumAggregator ,
352+ kind : & NumberKind ,
353+ desc : prometheus:: core:: Desc ,
354+ labels : Vec < KeyValue > ,
355+ ) -> Result < prometheus:: proto:: MetricFamily , MetricsError > {
356+ let sum = sum. sum ( ) ?;
357+
358+ let mut g = prometheus:: proto:: Gauge :: default ( ) ;
359+ g. set_value ( sum. to_f64 ( kind) ) ;
360+
361+ let mut m = prometheus:: proto:: Metric :: default ( ) ;
362+ m. set_label ( protobuf:: RepeatedField :: from_vec (
363+ labels. into_iter ( ) . map ( build_label_pair) . collect ( ) ,
364+ ) ) ;
365+ m. set_gauge ( g) ;
366+
367+ let mut mf = prometheus:: proto:: MetricFamily :: default ( ) ;
368+ mf. set_name ( desc. fq_name ) ;
369+ mf. set_help ( desc. help ) ;
370+ mf. set_field_type ( prometheus:: proto:: MetricType :: GAUGE ) ;
371+ mf. set_metric ( protobuf:: RepeatedField :: from_vec ( vec ! [ m] ) ) ;
372+
373+ Ok ( mf)
374+ }
375+
376+ fn build_monotonic_counter (
328377 sum : & SumAggregator ,
329378 kind : & NumberKind ,
330379 desc : prometheus:: core:: Desc ,
0 commit comments