1
1
use core:: fmt;
2
2
use std:: {
3
3
borrow:: Cow ,
4
+ collections:: HashMap ,
4
5
sync:: {
5
6
atomic:: { AtomicBool , Ordering } ,
6
- Arc ,
7
+ Arc , Mutex ,
7
8
} ,
8
9
} ;
9
10
10
11
use opentelemetry:: {
11
- metrics:: { noop:: NoopMeterCore , InstrumentProvider , Meter as ApiMeter , MetricsError , Result } ,
12
+ metrics:: { noop:: NoopMeterCore , Meter as ApiMeter , MetricsError , Result } ,
12
13
KeyValue ,
13
14
} ;
14
15
@@ -26,6 +27,7 @@ use super::{meter::Meter as SdkMeter, pipeline::Pipelines, reader::MetricReader,
26
27
#[ derive( Clone , Debug ) ]
27
28
pub struct MeterProvider {
28
29
pipes : Arc < Pipelines > ,
30
+ meters : Arc < Mutex < HashMap < Scope , Arc < SdkMeter > > > > ,
29
31
is_shutdown : Arc < AtomicBool > ,
30
32
}
31
33
@@ -121,15 +123,23 @@ impl opentelemetry::metrics::MeterProvider for MeterProvider {
121
123
schema_url : Option < impl Into < Cow < ' static , str > > > ,
122
124
attributes : Option < Vec < KeyValue > > ,
123
125
) -> ApiMeter {
124
- let inst_provider: Arc < dyn InstrumentProvider + Send + Sync > =
125
- if !self . is_shutdown . load ( Ordering :: Relaxed ) {
126
- let scope = Scope :: new ( name, version, schema_url, attributes) ;
127
- Arc :: new ( SdkMeter :: new ( scope, self . pipes . clone ( ) ) )
128
- } else {
129
- Arc :: new ( NoopMeterCore :: new ( ) )
130
- } ;
126
+ if self . is_shutdown . load ( Ordering :: Relaxed ) {
127
+ return ApiMeter :: new ( Arc :: new ( NoopMeterCore :: new ( ) ) ) ;
128
+ }
129
+
130
+ let scope = Scope :: new ( name, version, schema_url, attributes) ;
131
131
132
- ApiMeter :: new ( inst_provider)
132
+ if let Ok ( mut meters) = self . meters . lock ( ) {
133
+ let meter = meters
134
+ . entry ( scope)
135
+ . or_insert_with_key ( |scope| {
136
+ Arc :: new ( SdkMeter :: new ( scope. clone ( ) , self . pipes . clone ( ) ) )
137
+ } )
138
+ . clone ( ) ;
139
+ ApiMeter :: new ( meter)
140
+ } else {
141
+ ApiMeter :: new ( Arc :: new ( NoopMeterCore :: new ( ) ) )
142
+ }
133
143
}
134
144
}
135
145
@@ -184,6 +194,7 @@ impl MeterProviderBuilder {
184
194
self . readers ,
185
195
self . views ,
186
196
) ) ,
197
+ meters : Default :: default ( ) ,
187
198
is_shutdown : Arc :: new ( AtomicBool :: new ( false ) ) ,
188
199
}
189
200
}
0 commit comments