1010//! - [`ObservabilityDetectionInterceptor`]: Detects observability features during
1111//! request processing and tracks them for business metrics in the User-Agent header.
1212
13+ #[ cfg( all( not( target_arch = "powerpc" ) , not( target_family = "wasm" ) ) ) ]
14+ use crate :: sdk_feature:: AwsSdkFeature ;
15+ #[ cfg( all( not( target_arch = "powerpc" ) , not( target_family = "wasm" ) ) ) ]
1316use aws_smithy_observability_otel:: meter:: OtelMeterProvider ;
17+ #[ cfg( all( not( target_arch = "powerpc" ) , not( target_family = "wasm" ) ) ) ]
1418use aws_smithy_runtime:: client:: sdk_feature:: SmithySdkFeature ;
1519use aws_smithy_runtime_api:: box_error:: BoxError ;
1620use aws_smithy_runtime_api:: client:: interceptors:: context:: BeforeTransmitInterceptorContextRef ;
@@ -40,22 +44,37 @@ impl Intercept for ObservabilityDetectionInterceptor {
4044 & self ,
4145 _context : & BeforeTransmitInterceptorContextRef < ' _ > ,
4246 _runtime_components : & RuntimeComponents ,
43- cfg : & mut ConfigBag ,
47+ _cfg : & mut ConfigBag ,
4448 ) -> Result < ( ) , BoxError > {
45- // Try to get the global telemetry provider
46- if let Ok ( provider) = aws_smithy_observability:: global:: get_telemetry_provider ( ) {
47- // Use type-safe downcasting to detect OpenTelemetry meter provider
48- // This works with any ProvideMeter implementation and doesn't require
49- // implementation-specific boolean flags
50- if provider
51- . meter_provider ( )
52- . as_any ( )
53- . downcast_ref :: < OtelMeterProvider > ( )
54- . is_some ( )
55- {
56- // Track that observability metrics are enabled
57- cfg. interceptor_state ( )
58- . store_append ( SmithySdkFeature :: ObservabilityMetrics ) ;
49+ #[ cfg( all( not( target_arch = "powerpc" ) , not( target_family = "wasm" ) ) ) ]
50+ {
51+ // Try to get the global telemetry provider
52+ if let Ok ( provider) = aws_smithy_observability:: global:: get_telemetry_provider ( ) {
53+ let meter_provider = provider. meter_provider ( ) ;
54+
55+ // Check if this is an OpenTelemetry meter provider
56+ let is_otel = meter_provider
57+ . as_any ( )
58+ . downcast_ref :: < OtelMeterProvider > ( )
59+ . is_some ( ) ;
60+
61+ // Check if this is a noop provider (we don't want to track noop)
62+ let is_noop = meter_provider
63+ . as_any ( )
64+ . downcast_ref :: < aws_smithy_observability:: noop:: NoopMeterProvider > ( )
65+ . is_some ( ) ;
66+
67+ if !is_noop {
68+ // Track generic observability metrics (for any non-noop provider)
69+ _cfg. interceptor_state ( )
70+ . store_append ( SmithySdkFeature :: ObservabilityMetrics ) ;
71+
72+ // If it's specifically OpenTelemetry, track that too
73+ if is_otel {
74+ _cfg. interceptor_state ( )
75+ . store_append ( AwsSdkFeature :: ObservabilityOtelMetrics ) ;
76+ }
77+ }
5978 }
6079 }
6180
@@ -73,7 +92,9 @@ mod tests {
7392 use aws_smithy_runtime_api:: client:: runtime_components:: RuntimeComponentsBuilder ;
7493 use aws_smithy_types:: config_bag:: ConfigBag ;
7594
95+ #[ cfg( all( not( target_arch = "powerpc" ) , not( target_family = "wasm" ) ) ) ]
7696 #[ test]
97+ #[ serial_test:: serial]
7798 fn test_detects_noop_provider ( ) {
7899 let mut context = InterceptorContext :: new ( Input :: doesnt_matter ( ) ) ;
79100 context. enter_serialization_phase ( ) ;
@@ -93,15 +114,33 @@ mod tests {
93114 . read_before_signing ( & ctx, & rc, & mut cfg)
94115 . unwrap ( ) ;
95116
96- // Should not track any features for noop provider since it doesn't downcast to OtelMeterProvider
97- let smithy_features: Vec < _ > = cfg. load :: < SmithySdkFeature > ( ) . collect ( ) ;
98- assert_eq ! ( smithy_features. len( ) , 0 ) ;
117+ // Should not track any features for noop provider
118+ let smithy_features: Vec < _ > = cfg
119+ . interceptor_state ( )
120+ . load :: < SmithySdkFeature > ( )
121+ . cloned ( )
122+ . collect ( ) ;
123+ assert_eq ! (
124+ smithy_features. len( ) ,
125+ 0 ,
126+ "Should not track Smithy features for noop provider"
127+ ) ;
99128
100- let aws_features: Vec < _ > = cfg. load :: < AwsSdkFeature > ( ) . collect ( ) ;
101- assert_eq ! ( aws_features. len( ) , 0 ) ;
129+ let aws_features: Vec < _ > = cfg
130+ . interceptor_state ( )
131+ . load :: < AwsSdkFeature > ( )
132+ . cloned ( )
133+ . collect ( ) ;
134+ assert_eq ! (
135+ aws_features. len( ) ,
136+ 0 ,
137+ "Should not track AWS features for noop provider"
138+ ) ;
102139 }
103140
141+ #[ cfg( all( not( target_arch = "powerpc" ) , not( target_family = "wasm" ) ) ) ]
104142 #[ test]
143+ #[ serial_test:: serial]
105144 fn test_custom_provider_not_detected_as_otel ( ) {
106145 use aws_smithy_observability:: meter:: { Meter , ProvideMeter } ;
107146 use aws_smithy_observability:: noop:: NoopMeterProvider ;
@@ -150,24 +189,27 @@ mod tests {
150189 . read_before_signing ( & ctx, & rc, & mut cfg)
151190 . unwrap ( ) ;
152191
153- // Should NOT track any features for custom provider since it doesn't downcast to OtelMeterProvider
154- // The new implementation only emits metrics when OTel is detected
192+ // Should track generic observability metrics for custom provider
155193 let smithy_features: Vec < _ > = cfg
156194 . interceptor_state ( )
157195 . load :: < SmithySdkFeature > ( )
158196 . cloned ( )
159197 . collect ( ) ;
160198 assert ! (
161- ! smithy_features. iter ( ) . any ( |f| * f == SmithySdkFeature :: ObservabilityMetrics ) ,
162- "Should not detect custom provider as having observability metrics (only OTel is tracked) "
199+ smithy_features. contains ( & SmithySdkFeature :: ObservabilityMetrics ) ,
200+ "Should detect custom provider as having observability metrics"
163201 ) ;
164202
165- // Verify no AWS-specific features are tracked for custom provider
203+ // Should NOT track AWS-specific observability metrics for custom provider
166204 let aws_features: Vec < _ > = cfg
167205 . interceptor_state ( )
168206 . load :: < AwsSdkFeature > ( )
169207 . cloned ( )
170208 . collect ( ) ;
209+ assert ! (
210+ !aws_features. contains( & AwsSdkFeature :: ObservabilityOtelMetrics ) ,
211+ "Should NOT track OTel-specific metrics for custom provider"
212+ ) ;
171213 assert_eq ! (
172214 aws_features. len( ) ,
173215 0 ,
0 commit comments