Skip to content

Commit cb0b179

Browse files
committed
Fix observability detection to use type-safe downcasting and remove unused business_metrics test
1 parent b54fd60 commit cb0b179

File tree

8 files changed

+79
-30
lines changed

8 files changed

+79
-30
lines changed

aws/rust-runtime/aws-runtime/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ aws-smithy-async = { path = "../../../rust-runtime/aws-smithy-async" }
2222
aws-smithy-eventstream = { path = "../../../rust-runtime/aws-smithy-eventstream", optional = true }
2323
aws-smithy-http = { path = "../../../rust-runtime/aws-smithy-http" }
2424
aws-smithy-observability = { path = "../../../rust-runtime/aws-smithy-observability" }
25-
aws-smithy-observability-otel = { path = "../../../rust-runtime/aws-smithy-observability-otel" }
2625
aws-smithy-runtime = { path = "../../../rust-runtime/aws-smithy-runtime", features = ["client"] }
2726
aws-smithy-runtime-api = { path = "../../../rust-runtime/aws-smithy-runtime-api", features = ["client"] }
2827
aws-smithy-types = { path = "../../../rust-runtime/aws-smithy-types" }

aws/rust-runtime/aws-runtime/src/endpoint_override.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ mod tests {
153153
.load::<AwsSdkFeature>()
154154
.cloned()
155155
.collect();
156-
assert_eq!(features.len(), 1, "Expected 1 feature, got: {:?}", features);
156+
assert_eq!(features.len(), 1, "Expected 1 feature, got: {features:?}");
157157
assert_eq!(features[0], AwsSdkFeature::EndpointOverride);
158158
}
159159
}

aws/rust-runtime/aws-runtime/src/observability_detection.rs

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
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")))]
1316
use aws_smithy_observability_otel::meter::OtelMeterProvider;
17+
#[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
1418
use aws_smithy_runtime::client::sdk_feature::SmithySdkFeature;
1519
use aws_smithy_runtime_api::box_error::BoxError;
1620
use 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,

aws/rust-runtime/aws-runtime/src/sdk_feature.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ pub enum AwsSdkFeature {
2626
SsoLoginAuth,
2727
/// An operation called using a user provided endpoint URL
2828
EndpointOverride,
29+
/// An operation called with OpenTelemetry tracing integration enabled
30+
ObservabilityOtelTracing,
31+
/// An operation called with OpenTelemetry metrics integration enabled
32+
ObservabilityOtelMetrics,
2933
}
3034

3135
impl Storable for AwsSdkFeature {

aws/rust-runtime/aws-runtime/src/user_agent/metrics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ impl ProvideBusinessMetric for SmithySdkFeature {
202202
FlexibleChecksumsResWhenRequired => {
203203
Some(BusinessMetric::FlexibleChecksumsResWhenRequired)
204204
}
205+
ObservabilityTracing => Some(BusinessMetric::ObservabilityTracing),
205206
ObservabilityMetrics => Some(BusinessMetric::ObservabilityMetrics),
206207
otherwise => {
207208
// This may occur if a customer upgrades only the `aws-smithy-runtime-api` crate
@@ -228,6 +229,8 @@ impl ProvideBusinessMetric for AwsSdkFeature {
228229
SsoLoginDevice => Some(BusinessMetric::SsoLoginDevice),
229230
SsoLoginAuth => Some(BusinessMetric::SsoLoginAuth),
230231
EndpointOverride => Some(BusinessMetric::EndpointOverride),
232+
ObservabilityOtelTracing => Some(BusinessMetric::ObservabilityOtelTracing),
233+
ObservabilityOtelMetrics => Some(BusinessMetric::ObservabilityOtelMetrics),
231234
}
232235
}
233236
}

rust-runtime/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust-runtime/aws-smithy-runtime/src/client/sdk_feature.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub enum SmithySdkFeature {
2323
FlexibleChecksumsReqWhenRequired,
2424
FlexibleChecksumsResWhenSupported,
2525
FlexibleChecksumsResWhenRequired,
26+
ObservabilityTracing,
2627
ObservabilityMetrics,
2728
}
2829

tools/ci-build/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
ARG base_image=public.ecr.aws/amazonlinux/amazonlinux:2023
99
ARG rust_stable_version=1.88.0
10-
ARG rust_nightly_version=nightly-2025-08-06
10+
ARG rust_nightly_version=nightly-2024-11-28
1111

1212
FROM ${base_image} AS bare_base_image
1313
RUN yum -y updateinfo && yum clean all && rm -rf /var/cache/yum

0 commit comments

Comments
 (0)