AWS SDK

AWS SDK

rev. 80d9b4c9aa38f40a6d033a9f956fdf3576cff60f (ignoring whitespace)

Files changed:

tmp-codegen-diff/aws-sdk/sdk/aws-sigv4/src/http_request/canonical_request.rs

@@ -854,854 +927,927 @@
  874    874   
    #[test]
  875    875   
    fn test_double_url_encode_path() {
  876    876   
        let test = SigningSuiteTest::v4("double-encode-path");
  877    877   
        let req = test.request();
  878    878   
        let req = SignableRequest::from(&req);
  879    879   
        let identity = Credentials::for_tests().into();
  880    880   
        let signing_params = signing_params(&identity, SigningSettings::default());
  881    881   
        let creq = CanonicalRequest::from(&req, &signing_params).unwrap();
  882    882   
  883    883   
        let expected = test.canonical_request(SignatureLocation::Headers);
  884         -
        let actual = format!("{}", creq);
         884  +
        let actual = format!("{creq}");
  885    885   
        assert_eq!(actual, expected);
  886    886   
    }
  887    887   
  888    888   
    #[test]
  889    889   
    fn test_double_url_encode() {
  890    890   
        let test = SigningSuiteTest::v4("double-url-encode");
  891    891   
        let req = test.request();
  892    892   
        let req = SignableRequest::from(&req);
  893    893   
        let identity = Credentials::for_tests().into();
  894    894   
        let signing_params = signing_params(&identity, SigningSettings::default());
  895    895   
        let creq = CanonicalRequest::from(&req, &signing_params).unwrap();
  896    896   
        let expected = test.canonical_request(SignatureLocation::Headers);
  897         -
        let actual = format!("{}", creq);
         897  +
        let actual = format!("{creq}");
  898    898   
        assert_eq!(actual, expected);
  899    899   
    }
  900    900   
  901    901   
    #[test]
  902    902   
    fn test_tilde_in_uri() {
  903    903   
        let req = http0::Request::builder()
  904    904   
            .uri("https://s3.us-east-1.amazonaws.com/my-bucket?list-type=2&prefix=~objprefix&single&k=&unreserved=-_.~").body("").unwrap().into();
  905    905   
        let req = SignableRequest::from(&req);
  906    906   
        let identity = Credentials::for_tests().into();
  907    907   
        let signing_params = signing_params(&identity, SigningSettings::default());

tmp-codegen-diff/aws-sdk/sdk/aws-sigv4/src/http_request/test.rs

@@ -84,84 +144,144 @@
  104    104   
    pub(crate) fn context(&self) -> TestContext {
  105    105   
        let context = read(&self.path("context.json"));
  106    106   
        let tc_builder: TestContextBuilder = serde_json::from_str(&context).unwrap();
  107    107   
        tc_builder.build()
  108    108   
    }
  109    109   
}
  110    110   
  111    111   
fn test_parsed_request(path: &str) -> TestRequest {
  112    112   
    match parse_request(read(path).as_bytes()) {
  113    113   
        Ok(parsed) => parsed,
  114         -
        Err(err) => panic!("Failed to parse {}: {}", path, err),
         114  +
        Err(err) => panic!("Failed to parse {path}: {err}"),
  115    115   
    }
  116    116   
}
  117    117   
  118    118   
fn new_v4_signing_params_from_context(
  119    119   
    test_context: &'_ TestContext,
  120    120   
    signature_location: SignatureLocation,
  121    121   
) -> crate::http_request::SigningParams<'_> {
  122    122   
    let mut params = crate::sign::v4::SigningParams::from(test_context);
  123    123   
    params.settings.signature_location = signature_location;
  124    124   
    params.into()
@@ -401,401 +520,520 @@
  421    421   
    #[test]
  422    422   
    fn test_read_query_params() {
  423    423   
        let req = SigningSuiteTest::v4a("get-header-value-trim").request();
  424    424   
        assert_eq!(req.method, "GET");
  425    425   
        assert_eq!(req.uri, "https://example.amazonaws.com/");
  426    426   
        assert!(!req.headers.is_empty());
  427    427   
    }
  428    428   
}
  429    429   
  430    430   
fn read(path: &str) -> String {
  431         -
    println!("Loading `{}` for test case...", path);
         431  +
    println!("Loading `{path}` for test case...");
  432    432   
    let v = {
  433    433   
        match std::fs::read_to_string(path) {
  434    434   
            // This replacement is necessary for tests to pass on Windows, as reading the
  435    435   
            // test snapshots from the file system results in CRLF line endings being inserted.
  436    436   
            Ok(value) => value.replace("\r\n", "\n"),
  437    437   
            Err(err) => {
  438         -
                panic!("failed to load test case `{}`: {}", path, err);
         438  +
                panic!("failed to load test case `{path}`: {err}");
  439    439   
            }
  440    440   
        }
  441    441   
    };
  442    442   
  443    443   
    v.trim().to_string()
  444    444   
}
  445    445   
  446    446   
pub(crate) struct TestRequest {
  447    447   
    pub(crate) uri: String,
  448    448   
    pub(crate) method: String,
  449    449   
    pub(crate) headers: Vec<(String, String)>,
  450    450   
    pub(crate) body: TestSignedBody,
  451    451   
}
  452    452   
  453    453   
pub(crate) enum TestSignedBody {
  454    454   
    Signable(SignableBody<'static>),
  455    455   
    Bytes(Vec<u8>),
  456    456   
}
  457    457   
  458    458   
impl TestSignedBody {
  459    459   
    fn as_signable_body(&self) -> SignableBody<'_> {
  460    460   
        match self {
  461    461   
            TestSignedBody::Signable(data) => data.clone(),
  462    462   
            TestSignedBody::Bytes(data) => SignableBody::Bytes(data.as_slice()),
  463    463   
        }
  464    464   
    }
  465    465   
}
  466    466   
  467    467   
impl TestRequest {
  468    468   
    pub(crate) fn set_body(&mut self, body: SignableBody<'static>) {
  469    469   
        self.body = TestSignedBody::Signable(body);
  470    470   
    }
  471    471   
  472    472   
    pub(crate) fn as_http_request(&self) -> http0::Request<&'static str> {
  473    473   
        let mut builder = http0::Request::builder()
  474    474   
            .uri(&self.uri)
  475    475   
            .method(Method::from_bytes(self.method.as_bytes()).unwrap());
  476    476   
        for (k, v) in &self.headers {
  477    477   
            builder = builder.header(k, v);
  478    478   
        }
  479    479   
        builder.body("body").unwrap()
  480    480   
    }
  481    481   
}
  482    482   
  483    483   
impl<B: AsRef<[u8]>> From<http0::Request<B>> for TestRequest {
  484    484   
    fn from(value: http0::Request<B>) -> Self {
  485    485   
        let invalid = value
  486    486   
            .headers()
  487    487   
            .values()
  488    488   
            .find(|h| std::str::from_utf8(h.as_bytes()).is_err());
  489    489   
        if let Some(invalid) = invalid {
  490         -
            panic!("invalid header: {:?}", invalid);
         490  +
            panic!("invalid header: {invalid:?}");
  491    491   
        }
  492    492   
        Self {
  493    493   
            uri: value.uri().to_string(),
  494    494   
            method: value.method().to_string(),
  495    495   
            headers: value
  496    496   
                .headers()
  497    497   
                .iter()
  498    498   
                .map(|(k, v)| {
  499    499   
                    (
  500    500   
                        k.to_string(),

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-compression/Cargo.toml

@@ -1,1 +34,34 @@
    1      1   
# Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
    2      2   
[package]
    3      3   
name = "aws-smithy-compression"
    4         -
version = "0.0.6"
           4  +
version = "0.0.7"
    5      5   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>", "Zelda Hessler <zhessler@amazon.com>"]
    6      6   
description = "Request compression for smithy clients."
    7      7   
edition = "2021"
    8      8   
license = "Apache-2.0"
    9      9   
repository = "https://github.com/smithy-lang/smithy-rs"
   10     10   
[package.metadata.docs.rs]
   11     11   
all-features = true
   12     12   
targets = ["x86_64-unknown-linux-gnu"]
   13     13   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   14     14   
rustdoc-args = ["--cfg", "docsrs"]

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-compression/src/body.rs

@@ -217,217 +264,264 @@
  237    237   
            let compress_request =
  238    238   
                CompressionAlgorithm::Gzip.into_impl_http_body_1_x(&compression_options);
  239    239   
            let body = SdkBody::from(UNCOMPRESSED_INPUT);
  240    240   
            let mut compressed_body = CompressedBody::new(body, compress_request);
  241    241   
  242    242   
            let mut output = SegmentedBuf::new();
  243    243   
  244    244   
            loop {
  245    245   
                let data = match compressed_body.frame().await {
  246    246   
                    Some(Ok(frame)) => frame.into_data(),
  247         -
                    Some(Err(e)) => panic!("Error: {}", e),
         247  +
                    Some(Err(e)) => panic!("Error: {e}"),
  248    248   
                    // No more frames, break out of loop
  249    249   
                    None => break,
  250    250   
                }
  251    251   
                .expect("frame is OK");
  252    252   
                output.push(data);
  253    253   
            }
  254    254   
  255    255   
            let mut actual_output = Vec::new();
  256    256   
            output
  257    257   
                .reader()

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-http-client/Cargo.toml

@@ -1,1 +56,56 @@
   16     16   
   17     17   
[[example]]
   18     18   
name = "custom-dns"
   19     19   
required-features = ["rustls-ring"]
   20     20   
doc-scrape-examples = true
   21     21   
   22     22   
[package]
   23     23   
name = "aws-smithy-http-client"
   24     24   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
   25     25   
description = "HTTP client abstractions for generated smithy clients"
   26         -
version = "1.1.4"
          26  +
version = "1.1.5"
   27     27   
license = "Apache-2.0"
   28     28   
edition = "2021"
   29     29   
repository = "https://github.com/smithy-lang/smithy-rs"
   30     30   
[package.metadata.smithy-rs-release-tooling]
   31     31   
stable = true
   32     32   
[package.metadata.docs.rs]
   33     33   
all-features = false
   34     34   
features = ["default-client ", "wire-mock", "test-util", "rustls-ring", "rustls-aws-lc"]
   35     35   
targets = ["x86_64-unknown-linux-gnu"]
   36     36   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-http-client/src/test_util/dvr.rs

@@ -320,320 +384,379 @@
  340    340   
    }
  341    341   
}
  342    342   
  343    343   
#[cfg(test)]
  344    344   
mod tests {
  345    345   
    use super::*;
  346    346   
  347    347   
    use std::error::Error;
  348    348   
    use std::fs;
  349    349   
  350         -
    use aws_smithy_runtime_api::client::http::HttpConnector;
  351         -
    use aws_smithy_runtime_api::client::http::SharedHttpConnector;
  352         -
    use aws_smithy_types::body::SdkBody;
  353         -
    use aws_smithy_types::byte_stream::ByteStream;
  354         -
  355    350   
    #[tokio::test]
  356    351   
    async fn correctly_fixes_content_lengths() -> Result<(), Box<dyn Error>> {
  357    352   
        let network_traffic = fs::read_to_string("test-data/example.com.json")?;
  358    353   
        let mut network_traffic: NetworkTraffic = serde_json::from_str(&network_traffic)?;
  359    354   
        network_traffic.correct_content_lengths();
  360    355   
        let Action::Request {
  361    356   
            request: Request { headers, .. },
  362    357   
        } = &network_traffic.events[0].action
  363    358   
        else {
  364    359   
            panic!("unexpected event")

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-http-client/src/test_util/never.rs

@@ -160,160 +226,219 @@
  180    180   
  181    181   
        fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
  182    182   
            unreachable!()
  183    183   
        }
  184    184   
    }
  185    185   
}
  186    186   
  187    187   
#[cfg(test)]
  188    188   
mod test {
  189    189   
  190         -
    use super::*;
  191         -
  192         -
    use aws_smithy_async::rt::sleep::TokioSleep;
  193         -
    use aws_smithy_async::time::SystemTimeSource;
  194         -
    use aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder;
  195         -
    use tokio::time::Duration;
  196         -
  197    190   
    #[cfg(feature = "hyper-014")]
  198    191   
    #[tokio::test]
  199    192   
    async fn never_tcp_connector_plugs_into_hyper_014() {
  200    193   
        use super::NeverTcpConnector;
  201    194   
        use crate::hyper_014::HyperClientBuilder;
  202    195   
  203    196   
        // it should compile
  204    197   
        let client = HyperClientBuilder::new().build(NeverTcpConnector::new());
  205    198   
        let components = RuntimeComponentsBuilder::for_tests()
  206    199   
            .with_sleep_impl(Some(TokioSleep::new()))

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-mocks/Cargo.toml

@@ -1,1 +0,44 @@
   21     21   
version = "1.3.4"
   22     22   
   23     23   
[dependencies.aws-smithy-runtime-api]
   24     24   
path = "../aws-smithy-runtime-api"
   25     25   
features = ["client", "http-1x", "test-util"]
   26     26   
version = "1.9.2"
   27     27   
   28     28   
[dependencies.aws-smithy-http-client]
   29     29   
path = "../aws-smithy-http-client"
   30     30   
features = ["test-util"]
   31         -
version = "1.1.4"
          31  +
version = "1.1.5"
   32     32   
[dev-dependencies.tokio]
   33     33   
version = "1"
   34     34   
features = ["full"]
   35     35   
   36     36   
[dev-dependencies.aws-smithy-async]
   37     37   
path = "../aws-smithy-async"
   38     38   
features = ["rt-tokio"]
   39     39   
version = "1.2.6"
   40     40   
   41     41   
[dev-dependencies.aws-smithy-runtime]
   42     42   
path = "../aws-smithy-runtime"
   43     43   
features = ["client"]
   44         -
version = "1.9.4"
          44  +
version = "1.9.5"

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability-otel/Cargo.toml

@@ -1,1 +48,48 @@
    2      2   
[[bench]]
    3      3   
name = "sync_instruments"
    4      4   
harness = false
    5      5   
    6      6   
[[bench]]
    7      7   
name = "async_instruments"
    8      8   
harness = false
    9      9   
   10     10   
[package]
   11     11   
name = "aws-smithy-observability-otel"
   12         -
version = "0.1.2"
          12  +
version = "0.1.3"
   13     13   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
   14     14   
description = "Smithy OpenTelemetry observability implementation."
   15     15   
edition = "2021"
   16     16   
license = "Apache-2.0"
   17     17   
repository = "https://github.com/awslabs/smithy-rs"
   18     18   
[package.metadata.docs.rs]
   19     19   
all-features = true
   20     20   
targets = ["x86_64-unknown-linux-gnu"]
   21     21   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   22     22   
rustdoc-args = ["--cfg", "docsrs"]
   23     23   
   24     24   
[dependencies]
   25     25   
value-bag = "1.10.0"
   26     26   
async-global-executor = "2.4.1"
   27     27   
async-task = "=4.7.1"
   28     28   
   29     29   
[dependencies.aws-smithy-observability]
   30     30   
path = "../aws-smithy-observability"
   31         -
version = "0.1.4"
          31  +
version = "0.2.0"
   32     32   
   33     33   
[dependencies.opentelemetry]
   34         -
version = "0.26.0"
          34  +
version = "0.27.1"
   35     35   
features = ["metrics"]
   36         -
[target."cfg(not(target_arch = \"powerpc\"))".dependencies.opentelemetry_sdk]
   37         -
version = "0.26.0"
          36  +
[target."cfg(all(not(target_arch = \"powerpc\"), not(target_family = \"wasm\")))".dependencies.opentelemetry_sdk]
          37  +
version = "0.27.1"
   38     38   
features = ["metrics", "testing"]
   39     39   
   40     40   
[dev-dependencies]
   41     41   
stats_alloc = "0.1.10"
   42     42   
   43     43   
[dev-dependencies.tokio]
   44     44   
version = "1.23.1"
   45     45   
   46     46   
[dev-dependencies.criterion]
   47     47   
version = "0.5.1"

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability-otel/benches/async_instruments.rs

@@ -1,1 +43,43 @@
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
    6      6   
use aws_smithy_observability::instruments::AsyncMeasure;
    7      7   
use aws_smithy_observability::meter::Meter;
    8      8   
use aws_smithy_observability::{AttributeValue, Attributes, TelemetryProvider};
    9      9   
use aws_smithy_observability_otel::meter::OtelMeterProvider;
   10     10   
use criterion::{criterion_group, criterion_main, Criterion};
   11     11   
use opentelemetry_sdk::metrics::{PeriodicReader, SdkMeterProvider};
   12     12   
use opentelemetry_sdk::runtime::Tokio;
   13         -
use opentelemetry_sdk::testing::metrics::InMemoryMetricsExporter;
          13  +
use opentelemetry_sdk::testing::metrics::InMemoryMetricExporter;
   14     14   
   15     15   
use stats_alloc::{Region, StatsAlloc, INSTRUMENTED_SYSTEM};
   16     16   
use std::alloc::System;
   17     17   
use std::sync::Arc;
   18     18   
   19     19   
async fn record_async_instruments(dyn_sdk_meter: Meter) {
   20     20   
    //Create all async instruments and record some data
   21     21   
    let gauge = dyn_sdk_meter
   22     22   
        .create_gauge(
   23     23   
            "TestGauge".to_string(),
@@ -47,47 +99,99 @@
   67     67   
   68     68   
fn async_instruments_benchmark(c: &mut Criterion) {
   69     69   
    #[global_allocator]
   70     70   
    static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
   71     71   
    let reg = Region::new(GLOBAL);
   72     72   
   73     73   
    // Setup the Otel MeterProvider (which needs to be done inside an async runtime)
   74     74   
    // The runtime is reused later for running the bench function
   75     75   
    let runtime = tokio::runtime::Runtime::new().unwrap();
   76     76   
    let otel_mp = runtime.block_on(async {
   77         -
        let exporter = InMemoryMetricsExporter::default();
          77  +
        let exporter = InMemoryMetricExporter::default();
   78     78   
        let reader = PeriodicReader::builder(exporter.clone(), Tokio).build();
   79     79   
        SdkMeterProvider::builder().with_reader(reader).build()
   80     80   
    });
   81     81   
    // Create the SDK metrics types from the OTel objects
   82     82   
    let sdk_mp = Arc::new(OtelMeterProvider::new(otel_mp));
   83     83   
    let sdk_tp = TelemetryProvider::builder().meter_provider(sdk_mp).build();
   84     84   
   85     85   
    // Get the dyn versions of the SDK metrics objects
   86     86   
    let dyn_sdk_mp = sdk_tp.meter_provider();
   87     87   
    let dyn_sdk_meter = dyn_sdk_mp.get_meter("TestMeter", None);
   88     88   
   89     89   
    c.bench_function("async_instruments", |b| {
   90     90   
        b.to_async(&runtime)
   91         -
            .iter(|| async { record_async_instruments(dyn_sdk_meter.clone()) });
          91  +
            .iter(|| async { record_async_instruments(dyn_sdk_meter.clone()).await });
   92     92   
    });
   93     93   
   94     94   
    println!("FINISHING");
   95     95   
    println!("Stats at end: {:#?}", reg.change());
   96     96   
}
   97     97   
   98     98   
criterion_group!(benches, async_instruments_benchmark);
   99     99   
criterion_main!(benches);

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability-otel/benches/sync_instruments.rs

@@ -1,1 +65,65 @@
    2      2   
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
    3      3   
 * SPDX-License-Identifier: Apache-2.0
    4      4   
 */
    5      5   
    6      6   
use aws_smithy_observability::meter::Meter;
    7      7   
use aws_smithy_observability::TelemetryProvider;
    8      8   
use aws_smithy_observability_otel::meter::OtelMeterProvider;
    9      9   
use criterion::{criterion_group, criterion_main, Criterion};
   10     10   
use opentelemetry_sdk::metrics::{PeriodicReader, SdkMeterProvider};
   11     11   
use opentelemetry_sdk::runtime::Tokio;
   12         -
use opentelemetry_sdk::testing::metrics::InMemoryMetricsExporter;
          12  +
use opentelemetry_sdk::testing::metrics::InMemoryMetricExporter;
   13     13   
   14     14   
use stats_alloc::{Region, StatsAlloc, INSTRUMENTED_SYSTEM};
   15     15   
use std::alloc::System;
   16     16   
use std::sync::Arc;
   17     17   
   18     18   
async fn record_sync_instruments(dyn_sdk_meter: Meter) {
   19     19   
    //Create all 3 sync instruments and record some data for each
   20     20   
    let mono_counter = dyn_sdk_meter
   21     21   
        .create_monotonic_counter("TestMonoCounter")
   22     22   
        .build();
   23     23   
    mono_counter.add(4, None, None);
   24     24   
    let ud_counter = dyn_sdk_meter
   25     25   
        .create_up_down_counter("TestUpDownCounter")
   26     26   
        .build();
   27     27   
    ud_counter.add(-6, None, None);
   28     28   
    let histogram = dyn_sdk_meter
   29     29   
        .create_histogram("TestHistogram".to_string())
   30     30   
        .build();
   31     31   
    histogram.record(1.234, None, None);
   32     32   
}
   33     33   
   34     34   
fn sync_instruments_benchmark(c: &mut Criterion) {
   35     35   
    #[global_allocator]
   36     36   
    static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
   37     37   
    let reg = Region::new(GLOBAL);
   38     38   
   39     39   
    // Setup the Otel MeterProvider (which needs to be done inside an async runtime)
   40     40   
    // The runtime is reused later for running the bench function
   41     41   
    let runtime = tokio::runtime::Runtime::new().unwrap();
   42     42   
    let otel_mp = runtime.block_on(async {
   43         -
        let exporter = InMemoryMetricsExporter::default();
          43  +
        let exporter = InMemoryMetricExporter::default();
   44     44   
        let reader = PeriodicReader::builder(exporter.clone(), Tokio).build();
   45     45   
        SdkMeterProvider::builder().with_reader(reader).build()
   46     46   
    });
   47     47   
    // Create the SDK metrics types from the OTel objects
   48     48   
    let sdk_mp = Arc::new(OtelMeterProvider::new(otel_mp));
   49     49   
    let sdk_tp = TelemetryProvider::builder().meter_provider(sdk_mp).build();
   50     50   
   51     51   
    // Get the dyn versions of the SDK metrics objects
   52     52   
    let dyn_sdk_mp = sdk_tp.meter_provider();
   53     53   
    let dyn_sdk_meter = dyn_sdk_mp.get_meter("TestMeter", None);
   54     54   
   55     55   
    c.bench_function("sync_instruments", |b| {
   56     56   
        b.to_async(&runtime)
   57         -
            .iter(|| async { record_sync_instruments(dyn_sdk_meter.clone()) });
          57  +
            .iter(|| async { record_sync_instruments(dyn_sdk_meter.clone()).await });
   58     58   
    });
   59     59   
   60     60   
    println!("FINISHING");
   61     61   
    println!("Stats at end: {:#?}", reg.change());
   62     62   
}
   63     63   
   64     64   
criterion_group!(benches, sync_instruments_benchmark);
   65     65   
criterion_main!(benches);

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability-otel/src/attributes.rs

@@ -50,50 +109,113 @@
   70     70   
            attrs.set(
   71     71   
                kv.key.clone(),
   72     72   
                match &kv.value {
   73     73   
                    Value::Bool(val) => AttributeValue::Bool(*val),
   74     74   
                    Value::I64(val) => AttributeValue::I64(*val),
   75     75   
                    Value::F64(val) => AttributeValue::F64(*val),
   76     76   
                    Value::String(val) => AttributeValue::String(val.clone().into()),
   77     77   
                    Value::Array(_) => {
   78     78   
                        AttributeValue::String("UNSUPPORTED ATTRIBUTE VALUE TYPE".into())
   79     79   
                    }
          80  +
                    _ => {
          81  +
                        // Catch-all for any future Value variants added to OpenTelemetry
          82  +
                        AttributeValue::String("UNSUPPORTED ATTRIBUTE VALUE TYPE".into())
          83  +
                    }
   80     84   
                },
   81     85   
            )
   82     86   
        });
   83     87   
   84     88   
        AttributesWrap(attrs)
   85     89   
    }
   86     90   
}
   87     91   
   88     92   
#[cfg(test)]
   89     93   
mod tests {

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability-otel/src/lib.rs

@@ -1,1 +73,74 @@
    6      6   
/* Automatically managed default lints */
    7      7   
#![cfg_attr(docsrs, feature(doc_cfg))]
    8      8   
/* End of automatically managed default lints */
    9      9   
#![warn(
   10     10   
    missing_docs,
   11     11   
    rustdoc::missing_crate_level_docs,
   12     12   
    unreachable_pub,
   13     13   
    rust_2018_idioms
   14     14   
)]
   15     15   
// The `opentelemetry_sdk` crate uses std::sync::atomic::{AtomicI64, AtomicU64} which are not available on powerpc
   16         -
#![cfg(not(target_arch = "powerpc"))]
          16  +
// Additionally, opentelemetry_sdk depends on async-std which is not compatible with WASM targets
          17  +
#![cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
   17     18   
   18     19   
//! Smithy Observability OpenTelemetry
   19     20   
//TODO(smithyobservability): once we have finalized everything and integrated metrics with our runtime
   20     21   
// libraries update this with detailed usage docs and examples
   21     22   
   22     23   
pub mod attributes;
   23     24   
pub mod meter;
   24     25   
   25     26   
#[cfg(test)]
   26     27   
mod tests {
   27     28   
   28     29   
    use std::sync::Arc;
   29     30   
   30     31   
    use crate::meter::OtelMeterProvider;
   31     32   
    use aws_smithy_observability::{
   32     33   
        global::{get_telemetry_provider, set_telemetry_provider},
   33     34   
        TelemetryProvider,
   34     35   
    };
   35     36   
    use opentelemetry_sdk::metrics::{data::Sum, PeriodicReader, SdkMeterProvider};
   36     37   
    use opentelemetry_sdk::runtime::Tokio;
   37         -
    use opentelemetry_sdk::testing::metrics::InMemoryMetricsExporter;
          38  +
    use opentelemetry_sdk::testing::metrics::InMemoryMetricExporter;
   38     39   
   39     40   
    // Without these tokio settings this test just stalls forever on flushing the metrics pipeline
   40     41   
    #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
   41     42   
    async fn can_construct_set_and_use_otel_as_global_telemetry_provider() {
   42     43   
        // Create the OTel metrics objects
   43         -
        let exporter = InMemoryMetricsExporter::default();
          44  +
        let exporter = InMemoryMetricExporter::default();
   44     45   
        let reader = PeriodicReader::builder(exporter.clone(), Tokio).build();
   45     46   
        let otel_mp = SdkMeterProvider::builder().with_reader(reader).build();
   46     47   
   47     48   
        // Create the SDK metrics types from the OTel objects
   48     49   
        let sdk_mp = Arc::new(OtelMeterProvider::new(otel_mp));
   49     50   
        let sdk_ref = sdk_mp.clone();
   50     51   
        let sdk_tp = TelemetryProvider::builder().meter_provider(sdk_mp).build();
   51     52   
   52     53   
        // Set the global TelemetryProvider and then get it back out
   53     54   
        let _ = set_telemetry_provider(sdk_tp);

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability-otel/src/meter.rs

@@ -29,29 +131,137 @@
   49     49   
    }
   50     50   
}
   51     51   
   52     52   
#[derive(Debug)]
   53     53   
struct GaugeWrap(OtelObservableGauge<f64>);
   54     54   
impl AsyncMeasure for GaugeWrap {
   55     55   
    type Value = f64;
   56     56   
   57     57   
    fn record(
   58     58   
        &self,
   59         -
        value: Self::Value,
   60         -
        attributes: Option<&Attributes>,
          59  +
        _value: Self::Value,
          60  +
        _attributes: Option<&Attributes>,
   61     61   
        _context: Option<&dyn Context>,
   62     62   
    ) {
   63         -
        self.0.observe(value, &kv_from_option_attr(attributes));
          63  +
        // In OpenTelemetry 0.27+, observable instruments don't have an observe() method.
          64  +
        // Recording is done through callbacks registered during instrument creation.
          65  +
        // This method is a no-op as the callback handles all observations.
   64     66   
    }
   65     67   
   66     68   
    // OTel rust does not currently support unregistering callbacks
   67     69   
    // https://github.com/open-telemetry/opentelemetry-rust/issues/2245
   68     70   
    fn stop(&self) {}
   69     71   
}
   70     72   
   71     73   
#[derive(Debug)]
   72     74   
struct AsyncUpDownCounterWrap(OtelObservableUpDownCounter<i64>);
   73     75   
impl AsyncMeasure for AsyncUpDownCounterWrap {
   74     76   
    type Value = i64;
   75     77   
   76     78   
    fn record(
   77     79   
        &self,
   78         -
        value: Self::Value,
   79         -
        attributes: Option<&Attributes>,
          80  +
        _value: Self::Value,
          81  +
        _attributes: Option<&Attributes>,
   80     82   
        _context: Option<&dyn Context>,
   81     83   
    ) {
   82         -
        self.0.observe(value, &kv_from_option_attr(attributes));
          84  +
        // In OpenTelemetry 0.27+, observable instruments don't have an observe() method.
          85  +
        // Recording is done through callbacks registered during instrument creation.
          86  +
        // This method is a no-op as the callback handles all observations.
   83     87   
    }
   84     88   
   85     89   
    // OTel rust does not currently support unregistering callbacks
   86     90   
    // https://github.com/open-telemetry/opentelemetry-rust/issues/2245
   87     91   
    fn stop(&self) {}
   88     92   
}
   89     93   
   90     94   
#[derive(Debug)]
   91     95   
struct AsyncMonotonicCounterWrap(OtelObservableCounter<u64>);
   92     96   
impl AsyncMeasure for AsyncMonotonicCounterWrap {
   93     97   
    type Value = u64;
   94     98   
   95     99   
    fn record(
   96    100   
        &self,
   97         -
        value: Self::Value,
   98         -
        attributes: Option<&Attributes>,
         101  +
        _value: Self::Value,
         102  +
        _attributes: Option<&Attributes>,
   99    103   
        _context: Option<&dyn Context>,
  100    104   
    ) {
  101         -
        self.0.observe(value, &kv_from_option_attr(attributes));
         105  +
        // In OpenTelemetry 0.27+, observable instruments don't have an observe() method.
         106  +
        // Recording is done through callbacks registered during instrument creation.
         107  +
        // This method is a no-op as the callback handles all observations.
  102    108   
    }
  103    109   
  104    110   
    // OTel rust does not currently support unregistering callbacks
  105    111   
    // https://github.com/open-telemetry/opentelemetry-rust/issues/2245
  106    112   
    fn stop(&self) {}
  107    113   
}
  108    114   
  109    115   
struct AsyncInstrumentWrap<'a, T>(&'a (dyn OtelAsyncInstrument<T> + Send + Sync));
  110    116   
impl<T> AsyncMeasure for AsyncInstrumentWrap<'_, T> {
  111    117   
    type Value = T;
@@ -135,141 +495,474 @@
  155    161   
  156    162   
        if let Some(u) = builder.get_units() {
  157    163   
            otel_builder = otel_builder.with_unit(u.clone());
  158    164   
        }
  159    165   
  160    166   
        otel_builder = otel_builder.with_callback(move |input: &dyn OtelAsyncInstrument<f64>| {
  161    167   
            let f = builder.callback.clone();
  162    168   
            f(&AsyncInstrumentWrap(input));
  163    169   
        });
  164    170   
  165         -
        Arc::new(GaugeWrap(otel_builder.init()))
         171  +
        Arc::new(GaugeWrap(otel_builder.build()))
  166    172   
    }
  167    173   
  168    174   
    fn create_up_down_counter(
  169    175   
        &self,
  170    176   
        builder: InstrumentBuilder<'_, Arc<dyn UpDownCounter>>,
  171    177   
    ) -> Arc<dyn UpDownCounter> {
  172    178   
        let mut otel_builder = self.i64_up_down_counter(builder.get_name().clone());
  173    179   
        if let Some(desc) = builder.get_description() {
  174    180   
            otel_builder = otel_builder.with_description(desc.clone());
  175    181   
        }
  176    182   
  177    183   
        if let Some(u) = builder.get_units() {
  178    184   
            otel_builder = otel_builder.with_unit(u.clone());
  179    185   
        }
  180    186   
  181         -
        Arc::new(UpDownCounterWrap(otel_builder.init()))
         187  +
        Arc::new(UpDownCounterWrap(otel_builder.build()))
  182    188   
    }
  183    189   
  184    190   
    fn create_async_up_down_counter(
  185    191   
        &self,
  186    192   
        builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = i64>>, i64>,
  187    193   
    ) -> Arc<dyn AsyncMeasure<Value = i64>> {
  188    194   
        let mut otel_builder = self.i64_observable_up_down_counter(builder.get_name().clone());
  189    195   
  190    196   
        if let Some(desc) = builder.get_description() {
  191    197   
            otel_builder = otel_builder.with_description(desc.clone());
  192    198   
        }
  193    199   
  194    200   
        if let Some(u) = builder.get_units() {
  195    201   
            otel_builder = otel_builder.with_unit(u.clone());
  196    202   
        }
  197    203   
  198    204   
        otel_builder = otel_builder.with_callback(move |input: &dyn OtelAsyncInstrument<i64>| {
  199    205   
            let f = builder.callback.clone();
  200    206   
            f(&AsyncInstrumentWrap(input));
  201    207   
        });
  202    208   
  203         -
        Arc::new(AsyncUpDownCounterWrap(otel_builder.init()))
         209  +
        Arc::new(AsyncUpDownCounterWrap(otel_builder.build()))
  204    210   
    }
  205    211   
  206    212   
    fn create_monotonic_counter(
  207    213   
        &self,
  208    214   
        builder: InstrumentBuilder<'_, Arc<dyn MonotonicCounter>>,
  209    215   
    ) -> Arc<dyn MonotonicCounter> {
  210    216   
        let mut otel_builder = self.u64_counter(builder.get_name().clone());
  211    217   
        if let Some(desc) = builder.get_description() {
  212    218   
            otel_builder = otel_builder.with_description(desc.clone());
  213    219   
        }
  214    220   
  215    221   
        if let Some(u) = builder.get_units() {
  216    222   
            otel_builder = otel_builder.with_unit(u.clone());
  217    223   
        }
  218    224   
  219         -
        Arc::new(MonotonicCounterWrap(otel_builder.init()))
         225  +
        Arc::new(MonotonicCounterWrap(otel_builder.build()))
  220    226   
    }
  221    227   
  222    228   
    fn create_async_monotonic_counter(
  223    229   
        &self,
  224    230   
        builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = u64>>, u64>,
  225    231   
    ) -> Arc<dyn AsyncMeasure<Value = u64>> {
  226    232   
        let mut otel_builder = self.u64_observable_counter(builder.get_name().clone());
  227    233   
  228    234   
        if let Some(desc) = builder.get_description() {
  229    235   
            otel_builder = otel_builder.with_description(desc.clone());
  230    236   
        }
  231    237   
  232    238   
        if let Some(u) = builder.get_units() {
  233    239   
            otel_builder = otel_builder.with_unit(u.clone());
  234    240   
        }
  235    241   
  236    242   
        otel_builder = otel_builder.with_callback(move |input: &dyn OtelAsyncInstrument<u64>| {
  237    243   
            let f = builder.callback.clone();
  238    244   
            f(&AsyncInstrumentWrap(input));
  239    245   
        });
  240    246   
  241         -
        Arc::new(AsyncMonotonicCounterWrap(otel_builder.init()))
         247  +
        Arc::new(AsyncMonotonicCounterWrap(otel_builder.build()))
  242    248   
    }
  243    249   
  244    250   
    fn create_histogram(
  245    251   
        &self,
  246    252   
        builder: InstrumentBuilder<'_, Arc<dyn Histogram>>,
  247    253   
    ) -> Arc<dyn Histogram> {
  248    254   
        let mut otel_builder = self.f64_histogram(builder.get_name().clone());
  249    255   
        if let Some(desc) = builder.get_description() {
  250    256   
            otel_builder = otel_builder.with_description(desc.clone());
  251    257   
        }
  252    258   
  253    259   
        if let Some(u) = builder.get_units() {
  254    260   
            otel_builder = otel_builder.with_unit(u.clone());
  255    261   
        }
  256    262   
  257         -
        Arc::new(HistogramWrap(otel_builder.init()))
         263  +
        Arc::new(HistogramWrap(otel_builder.build()))
  258    264   
    }
  259    265   
}
  260    266   
  261    267   
/// An OpenTelemetry based implementation of the AWS SDK's [ProvideMeter] trait
  262    268   
#[non_exhaustive]
  263    269   
#[derive(Debug)]
  264    270   
pub struct OtelMeterProvider {
  265    271   
    meter_provider: OtelSdkMeterProvider,
  266    272   
}
  267    273   
  268    274   
impl OtelMeterProvider {
  269    275   
    /// Create a new [OtelMeterProvider] from an [OtelSdkMeterProvider].
  270    276   
    pub fn new(otel_meter_provider: OtelSdkMeterProvider) -> Self {
  271    277   
        Self {
  272    278   
            meter_provider: otel_meter_provider,
  273    279   
        }
  274    280   
    }
  275    281   
  276    282   
    /// Flush the metric pipeline.
  277    283   
    pub fn flush(&self) -> Result<(), ObservabilityError> {
  278    284   
        match self.meter_provider.force_flush() {
  279    285   
            Ok(_) => Ok(()),
  280    286   
            Err(err) => Err(ObservabilityError::new(ErrorKind::Other, err)),
  281    287   
        }
  282    288   
    }
  283    289   
}
  284    290   
  285    291   
impl ProvideMeter for OtelMeterProvider {
  286    292   
    fn get_meter(&self, scope: &'static str, _attributes: Option<&Attributes>) -> Meter {
  287    293   
        Meter::new(Arc::new(MeterWrap(self.meter_provider.meter(scope))))
  288    294   
    }
         295  +
         296  +
    fn as_any(&self) -> &dyn std::any::Any {
         297  +
        self
         298  +
    }
  289    299   
}
  290    300   
  291    301   
#[cfg(test)]
  292    302   
mod tests {
  293    303   
  294    304   
    use std::sync::Arc;
  295    305   
  296    306   
    use aws_smithy_observability::instruments::AsyncMeasure;
  297    307   
    use aws_smithy_observability::{AttributeValue, Attributes, TelemetryProvider};
  298    308   
    use opentelemetry_sdk::metrics::{
  299    309   
        data::{Gauge, Histogram, Sum},
  300    310   
        PeriodicReader, SdkMeterProvider,
  301    311   
    };
  302    312   
    use opentelemetry_sdk::runtime::Tokio;
  303         -
    use opentelemetry_sdk::testing::metrics::InMemoryMetricsExporter;
         313  +
    use opentelemetry_sdk::testing::metrics::InMemoryMetricExporter;
  304    314   
  305    315   
    use super::OtelMeterProvider;
  306    316   
  307    317   
    // Without these tokio settings this test just stalls forever on flushing the metrics pipeline
  308    318   
    #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
  309    319   
    async fn sync_instruments_work() {
  310    320   
        // Create the OTel metrics objects
  311         -
        let exporter = InMemoryMetricsExporter::default();
         321  +
        let exporter = InMemoryMetricExporter::default();
  312    322   
        let reader = PeriodicReader::builder(exporter.clone(), Tokio).build();
  313    323   
        let otel_mp = SdkMeterProvider::builder().with_reader(reader).build();
  314    324   
  315    325   
        // Create the SDK metrics types from the OTel objects
  316    326   
        let sdk_mp = Arc::new(OtelMeterProvider::new(otel_mp));
  317    327   
        let sdk_ref = sdk_mp.clone();
  318    328   
        let sdk_tp = TelemetryProvider::builder().meter_provider(sdk_mp).build();
  319    329   
  320    330   
        // Get the dyn versions of the SDK metrics objects
  321    331   
        let dyn_sdk_mp = sdk_tp.meter_provider();
  322    332   
        let dyn_sdk_meter = dyn_sdk_mp.get_meter("TestMeter", None);
  323    333   
  324    334   
        //Create all 3 sync instruments and record some data for each
  325    335   
        let mono_counter = dyn_sdk_meter
  326    336   
            .create_monotonic_counter("TestMonoCounter")
  327    337   
            .build();
  328    338   
        mono_counter.add(4, None, None);
  329    339   
        let ud_counter = dyn_sdk_meter
  330    340   
            .create_up_down_counter("TestUpDownCounter")
  331    341   
            .build();
  332    342   
        ud_counter.add(-6, None, None);
  333    343   
        let histogram = dyn_sdk_meter.create_histogram("TestHistogram").build();
  334    344   
        histogram.record(1.234, None, None);
  335    345   
  336    346   
        // Gracefully shutdown the metrics provider so all metrics are flushed through the pipeline
  337    347   
        sdk_ref.flush().unwrap();
  338    348   
  339    349   
        // Extract the metrics from the exporter and assert that they are what we expect
  340    350   
        let finished_metrics = exporter.get_finished_metrics().unwrap();
  341    351   
        let extracted_mono_counter_data = &finished_metrics[0].scope_metrics[0].metrics[0]
  342    352   
            .data
  343    353   
            .as_any()
  344    354   
            .downcast_ref::<Sum<u64>>()
  345    355   
            .unwrap()
  346    356   
            .data_points[0]
  347    357   
            .value;
  348    358   
        assert_eq!(extracted_mono_counter_data, &4);
  349    359   
  350    360   
        let extracted_ud_counter_data = &finished_metrics[0].scope_metrics[0].metrics[1]
  351    361   
            .data
  352    362   
            .as_any()
  353    363   
            .downcast_ref::<Sum<i64>>()
  354    364   
            .unwrap()
  355    365   
            .data_points[0]
  356    366   
            .value;
  357    367   
        assert_eq!(extracted_ud_counter_data, &-6);
  358    368   
  359    369   
        let extracted_histogram_data = &finished_metrics[0].scope_metrics[0].metrics[2]
  360    370   
            .data
  361    371   
            .as_any()
  362    372   
            .downcast_ref::<Histogram<f64>>()
  363    373   
            .unwrap()
  364    374   
            .data_points[0]
  365    375   
            .sum;
  366    376   
        assert_eq!(extracted_histogram_data, &1.234);
  367    377   
    }
  368    378   
  369    379   
    #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
  370    380   
    async fn async_instrument_work() {
  371    381   
        // Create the OTel metrics objects
  372         -
        let exporter = InMemoryMetricsExporter::default();
         382  +
        let exporter = InMemoryMetricExporter::default();
  373    383   
        let reader = PeriodicReader::builder(exporter.clone(), Tokio).build();
  374    384   
        let otel_mp = SdkMeterProvider::builder().with_reader(reader).build();
  375    385   
  376    386   
        // Create the SDK metrics types from the OTel objects
  377    387   
        let sdk_mp = Arc::new(OtelMeterProvider::new(otel_mp));
  378    388   
        let sdk_ref = sdk_mp.clone();
  379    389   
        let sdk_tp = TelemetryProvider::builder().meter_provider(sdk_mp).build();
  380    390   
  381    391   
        // Get the dyn versions of the SDK metrics objects
  382    392   
        let dyn_sdk_mp = sdk_tp.meter_provider();
  383    393   
        let dyn_sdk_meter = dyn_sdk_mp.get_meter("TestMeter", None);
  384    394   
  385         -
        //Create all async instruments and record some data
  386         -
        let gauge = dyn_sdk_meter
         395  +
        //Create all async instruments - in OpenTelemetry 0.27+, async instruments only work through callbacks
         396  +
        let _gauge = dyn_sdk_meter
  387    397   
            .create_gauge(
  388    398   
                "TestGauge".to_string(),
  389         -
                // Callback function records another value with different attributes so it is deduped
         399  +
                // Callback function records the value
  390    400   
                |measurement: &dyn AsyncMeasure<Value = f64>| {
  391    401   
                    let mut attrs = Attributes::new();
  392    402   
                    attrs.set(
  393    403   
                        "TestGaugeAttr",
  394    404   
                        AttributeValue::String("TestGaugeAttr".into()),
  395    405   
                    );
  396    406   
                    measurement.record(6.789, Some(&attrs), None);
  397    407   
                },
  398    408   
            )
  399    409   
            .build();
  400         -
        gauge.record(1.234, None, None);
  401    410   
  402         -
        let async_ud_counter = dyn_sdk_meter
         411  +
        let _async_ud_counter = dyn_sdk_meter
  403    412   
            .create_async_up_down_counter(
  404    413   
                "TestAsyncUpDownCounter".to_string(),
  405    414   
                |measurement: &dyn AsyncMeasure<Value = i64>| {
  406    415   
                    let mut attrs = Attributes::new();
  407    416   
                    attrs.set(
  408    417   
                        "TestAsyncUpDownCounterAttr",
  409    418   
                        AttributeValue::String("TestAsyncUpDownCounterAttr".into()),
  410    419   
                    );
  411    420   
                    measurement.record(12, Some(&attrs), None);
  412    421   
                },
  413    422   
            )
  414    423   
            .build();
  415         -
        async_ud_counter.record(-6, None, None);
  416    424   
  417         -
        let async_mono_counter = dyn_sdk_meter
         425  +
        let _async_mono_counter = dyn_sdk_meter
  418    426   
            .create_async_monotonic_counter(
  419    427   
                "TestAsyncMonoCounter".to_string(),
  420    428   
                |measurement: &dyn AsyncMeasure<Value = u64>| {
  421    429   
                    let mut attrs = Attributes::new();
  422    430   
                    attrs.set(
  423    431   
                        "TestAsyncMonoCounterAttr",
  424    432   
                        AttributeValue::String("TestAsyncMonoCounterAttr".into()),
  425    433   
                    );
  426    434   
                    measurement.record(123, Some(&attrs), None);
  427    435   
                },
  428    436   
            )
  429    437   
            .build();
  430         -
        async_mono_counter.record(4, None, None);
  431    438   
  432    439   
        // Gracefully shutdown the metrics provider so all metrics are flushed through the pipeline
  433    440   
        sdk_ref.flush().unwrap();
  434    441   
  435    442   
        // Extract the metrics from the exporter
  436    443   
        let finished_metrics = exporter.get_finished_metrics().unwrap();
  437    444   
  438         -
        // Assert that the reported metrics are what we expect
         445  +
        // Assert that the async callbacks ran and recorded the expected values
         446  +
        // In OpenTelemetry 0.27+, async instruments only work through callbacks
  439    447   
        let extracted_gauge_data = &finished_metrics[0].scope_metrics[0].metrics[0]
  440    448   
            .data
  441    449   
            .as_any()
  442    450   
            .downcast_ref::<Gauge<f64>>()
  443    451   
            .unwrap()
  444    452   
            .data_points[0]
  445    453   
            .value;
  446         -
        assert_eq!(extracted_gauge_data, &1.234);
  447         -
  448         -
        let extracted_async_ud_counter_data = &finished_metrics[0].scope_metrics[0].metrics[1]
  449         -
            .data
  450         -
            .as_any()
  451         -
            .downcast_ref::<Sum<i64>>()
  452         -
            .unwrap()
  453         -
            .data_points[0]
  454         -
            .value;
  455         -
        assert_eq!(extracted_async_ud_counter_data, &-6);
  456         -
  457         -
        let extracted_async_mono_data = &finished_metrics[0].scope_metrics[0].metrics[2]
  458         -
            .data
  459         -
            .as_any()
  460         -
            .downcast_ref::<Sum<u64>>()
  461         -
            .unwrap()
  462         -
            .data_points[0]
  463         -
            .value;
  464         -
        assert_eq!(extracted_async_mono_data, &4);
  465         -
  466         -
        // Assert that the async callbacks ran
  467         -
        let finished_metrics = exporter.get_finished_metrics().unwrap();
  468         -
        let extracted_gauge_data = &finished_metrics[0].scope_metrics[0].metrics[0]
  469         -
            .data
  470         -
            .as_any()
  471         -
            .downcast_ref::<Gauge<f64>>()
  472         -
            .unwrap()
  473         -
            .data_points[1]
  474         -
            .value;
  475    454   
        assert_eq!(extracted_gauge_data, &6.789);
  476    455   
  477    456   
        let extracted_async_ud_counter_data = &finished_metrics[0].scope_metrics[0].metrics[1]
  478    457   
            .data
  479    458   
            .as_any()
  480    459   
            .downcast_ref::<Sum<i64>>()
  481    460   
            .unwrap()
  482         -
            .data_points[1]
         461  +
            .data_points[0]
  483    462   
            .value;
  484    463   
        assert_eq!(extracted_async_ud_counter_data, &12);
  485    464   
  486    465   
        let extracted_async_mono_data = &finished_metrics[0].scope_metrics[0].metrics[2]
  487    466   
            .data
  488    467   
            .as_any()
  489    468   
            .downcast_ref::<Sum<u64>>()
  490    469   
            .unwrap()
  491         -
            .data_points[1]
         470  +
            .data_points[0]
  492    471   
            .value;
  493    472   
        assert_eq!(extracted_async_mono_data, &123);
  494    473   
    }
  495    474   
}

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability/Cargo.toml

@@ -1,1 +20,20 @@
    1      1   
# Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
    2      2   
[package]
    3      3   
name = "aws-smithy-observability"
    4         -
version = "0.1.4"
           4  +
version = "0.2.0"
    5      5   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
    6      6   
description = "Smithy observability implementation."
    7      7   
edition = "2021"
    8      8   
license = "Apache-2.0"
    9      9   
repository = "https://github.com/awslabs/smithy-rs"
   10     10   
[package.metadata.docs.rs]
   11     11   
all-features = true
   12     12   
targets = ["x86_64-unknown-linux-gnu"]
   13     13   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   14     14   
rustdoc-args = ["--cfg", "docsrs"]

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability/src/lib.rs

@@ -1,1 +31,32 @@
   18     18   
// libraries update this with detailed usage docs and examples
   19     19   
   20     20   
mod attributes;
   21     21   
pub use attributes::{AttributeValue, Attributes};
   22     22   
mod context;
   23     23   
pub use context::{Context, ContextManager, Scope};
   24     24   
mod error;
   25     25   
pub use error::{ErrorKind, GlobalTelemetryProviderError, ObservabilityError};
   26     26   
pub mod global;
   27     27   
pub mod meter;
   28         -
mod noop;
          28  +
#[doc(hidden)]
          29  +
pub mod noop;
   29     30   
mod provider;
   30     31   
pub use provider::{TelemetryProvider, TelemetryProviderBuilder};
   31     32   
pub mod instruments;