@@ -5,11 +5,11 @@ use std::{
55 sync:: { Arc , Mutex } ,
66 time:: SystemTime ,
77} ;
8-
8+ use std :: borrow :: Cow ;
99use crate :: metrics:: { data:: Aggregation , Temporality } ;
1010use opentelemetry:: time:: now;
1111use opentelemetry:: KeyValue ;
12-
12+ use crate :: metrics :: measurement_processor :: MeasurementProcessor ;
1313use super :: {
1414 exponential_histogram:: ExpoHistogram , histogram:: Histogram , last_value:: LastValue ,
1515 precomputed_sum:: PrecomputedSum , sum:: Sum , Number ,
@@ -106,21 +106,41 @@ type Filter = Arc<dyn Fn(&KeyValue) -> bool + Send + Sync>;
106106#[ derive( Clone ) ]
107107pub ( crate ) struct AttributeSetFilter {
108108 filter : Option < Filter > ,
109+ processor : Option < AggregateProcessor >
109110}
110111
111112impl AttributeSetFilter {
112- pub ( crate ) fn new ( filter : Option < Filter > ) -> Self {
113- Self { filter }
113+ pub ( crate ) fn new ( filter : Option < Filter > , processors : Vec < Arc < dyn MeasurementProcessor > > ) -> Self {
114+ Self { filter, processor : AggregateProcessor :: try_create ( processors ) }
114115 }
115116
116117 pub ( crate ) fn apply ( & self , attrs : & [ KeyValue ] , run : impl FnOnce ( & [ KeyValue ] ) ) {
117- if let Some ( filter) = & self . filter {
118- let filtered_attrs: Vec < KeyValue > =
119- attrs. iter ( ) . filter ( |kv| filter ( kv) ) . cloned ( ) . collect ( ) ;
120- run ( & filtered_attrs) ;
121- } else {
122- run ( attrs) ;
123- } ;
118+ match ( & self . filter , & self . processor ) {
119+ ( None , None ) => {
120+ run ( attrs) ;
121+ } ,
122+ ( Some ( filter) , None ) => {
123+ let filtered_attrs: Vec < KeyValue > =
124+ attrs. iter ( ) . filter ( |kv| filter ( kv) ) . cloned ( ) . collect ( ) ;
125+
126+ run ( & filtered_attrs) ;
127+ } ,
128+ ( None , Some ( processor) ) => {
129+ let attributes = Cow :: Borrowed ( attrs) ;
130+ let attributes = processor. process ( attributes) ;
131+
132+ run ( attributes. as_ref ( ) ) ;
133+ } ,
134+ ( Some ( filter) , Some ( processor) ) => {
135+ let filtered_attrs: Vec < KeyValue > =
136+ attrs. iter ( ) . filter ( |kv| filter ( kv) ) . cloned ( ) . collect ( ) ;
137+
138+ let attributes = Cow :: Owned ( filtered_attrs) ;
139+ let attributes = processor. process ( attributes) ;
140+
141+ run ( attributes. as_ref ( ) ) ;
142+ }
143+ }
124144 }
125145}
126146
@@ -137,10 +157,10 @@ pub(crate) struct AggregateBuilder<T> {
137157}
138158
139159impl < T : Number > AggregateBuilder < T > {
140- pub ( crate ) fn new ( temporality : Temporality , filter : Option < Filter > ) -> Self {
160+ pub ( crate ) fn new ( temporality : Temporality , filter : Option < Filter > , processors : Vec < Arc < dyn MeasurementProcessor > > ) -> Self {
141161 AggregateBuilder {
142162 temporality,
143- filter : AttributeSetFilter :: new ( filter) ,
163+ filter : AttributeSetFilter :: new ( filter, processors ) ,
144164 _marker : marker:: PhantomData ,
145165 }
146166 }
@@ -201,6 +221,31 @@ impl<T: Number> AggregateBuilder<T> {
201221 }
202222}
203223
224+
225+ #[ derive( Clone ) ]
226+ struct AggregateProcessor ( Arc < Vec < Arc < dyn MeasurementProcessor > > > ) ;
227+
228+ impl AggregateProcessor {
229+ pub fn try_create (
230+ processors : Vec < Arc < dyn MeasurementProcessor > > ,
231+ ) -> Option < Self > {
232+ if processors. is_empty ( ) {
233+ return None ;
234+ }
235+ Some ( Self ( Arc :: new ( processors) ) )
236+ }
237+ }
238+
239+ impl MeasurementProcessor for AggregateProcessor {
240+ fn process < ' a > ( & self , mut attributes : Cow < ' a , [ KeyValue ] > ) -> Cow < ' a , [ KeyValue ] > {
241+ for processor in self . 0 . iter ( ) {
242+ attributes = processor. process ( attributes) ;
243+ }
244+
245+ attributes
246+ }
247+ }
248+
204249#[ cfg( test) ]
205250mod tests {
206251 use crate :: metrics:: data:: {
@@ -214,7 +259,7 @@ mod tests {
214259 #[ test]
215260 fn last_value_aggregation ( ) {
216261 let AggregateFns { measure, collect } =
217- AggregateBuilder :: < u64 > :: new ( Temporality :: Cumulative , None ) . last_value ( None ) ;
262+ AggregateBuilder :: < u64 > :: new ( Temporality :: Cumulative , None , vec ! [ ] ) . last_value ( None ) ;
218263 let mut a = Gauge {
219264 data_points : vec ! [ GaugeDataPoint {
220265 attributes: vec![ KeyValue :: new( "a" , 1 ) ] ,
@@ -240,7 +285,7 @@ mod tests {
240285 fn precomputed_sum_aggregation ( ) {
241286 for temporality in [ Temporality :: Delta , Temporality :: Cumulative ] {
242287 let AggregateFns { measure, collect } =
243- AggregateBuilder :: < u64 > :: new ( temporality, None ) . precomputed_sum ( true ) ;
288+ AggregateBuilder :: < u64 > :: new ( temporality, None , vec ! [ ] ) . precomputed_sum ( true ) ;
244289 let mut a = Sum {
245290 data_points : vec ! [
246291 SumDataPoint {
@@ -282,7 +327,7 @@ mod tests {
282327 fn sum_aggregation ( ) {
283328 for temporality in [ Temporality :: Delta , Temporality :: Cumulative ] {
284329 let AggregateFns { measure, collect } =
285- AggregateBuilder :: < u64 > :: new ( temporality, None ) . sum ( true ) ;
330+ AggregateBuilder :: < u64 > :: new ( temporality, None , vec ! [ ] ) . sum ( true ) ;
286331 let mut a = Sum {
287332 data_points : vec ! [
288333 SumDataPoint {
@@ -323,7 +368,7 @@ mod tests {
323368 #[ test]
324369 fn explicit_bucket_histogram_aggregation ( ) {
325370 for temporality in [ Temporality :: Delta , Temporality :: Cumulative ] {
326- let AggregateFns { measure, collect } = AggregateBuilder :: < u64 > :: new ( temporality, None )
371+ let AggregateFns { measure, collect } = AggregateBuilder :: < u64 > :: new ( temporality, None , vec ! [ ] )
327372 . explicit_bucket_histogram ( vec ! [ 1.0 ] , true , true ) ;
328373 let mut a = Histogram {
329374 data_points : vec ! [ HistogramDataPoint {
@@ -366,7 +411,7 @@ mod tests {
366411 #[ test]
367412 fn exponential_histogram_aggregation ( ) {
368413 for temporality in [ Temporality :: Delta , Temporality :: Cumulative ] {
369- let AggregateFns { measure, collect } = AggregateBuilder :: < u64 > :: new ( temporality, None )
414+ let AggregateFns { measure, collect } = AggregateBuilder :: < u64 > :: new ( temporality, None , vec ! [ ] )
370415 . exponential_bucket_histogram ( 4 , 20 , true , true ) ;
371416 let mut a = ExponentialHistogram {
372417 data_points : vec ! [ ExponentialHistogramDataPoint {
0 commit comments