aws_smithy_observability_otel/
lib.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6/* Automatically managed default lints */
7#![cfg_attr(docsrs, feature(doc_cfg))]
8/* End of automatically managed default lints */
9#![warn(
10    missing_docs,
11    rustdoc::missing_crate_level_docs,
12    unreachable_pub,
13    rust_2018_idioms
14)]
15// The `opentelemetry_sdk` crate uses std::sync::atomic::{AtomicI64, AtomicU64} which are not available on 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")))]
18
19//! Smithy Observability OpenTelemetry
20//TODO(smithyobservability): once we have finalized everything and integrated metrics with our runtime
21// libraries update this with detailed usage docs and examples
22
23pub mod attributes;
24pub mod meter;
25
26#[cfg(test)]
27mod tests {
28
29    use std::sync::Arc;
30
31    use crate::meter::OtelMeterProvider;
32    use aws_smithy_observability::{
33        global::{get_telemetry_provider, set_telemetry_provider},
34        TelemetryProvider,
35    };
36    use opentelemetry_sdk::metrics::{data::Sum, PeriodicReader, SdkMeterProvider};
37    use opentelemetry_sdk::runtime::Tokio;
38    use opentelemetry_sdk::testing::metrics::InMemoryMetricExporter;
39
40    // Without these tokio settings this test just stalls forever on flushing the metrics pipeline
41    #[tokio::test(flavor = "multi_thread", worker_threads = 1)]
42    async fn can_construct_set_and_use_otel_as_global_telemetry_provider() {
43        // Create the OTel metrics objects
44        let exporter = InMemoryMetricExporter::default();
45        let reader = PeriodicReader::builder(exporter.clone(), Tokio).build();
46        let otel_mp = SdkMeterProvider::builder().with_reader(reader).build();
47
48        // Create the SDK metrics types from the OTel objects
49        let sdk_mp = Arc::new(OtelMeterProvider::new(otel_mp));
50        let sdk_ref = sdk_mp.clone();
51        let sdk_tp = TelemetryProvider::builder().meter_provider(sdk_mp).build();
52
53        // Set the global TelemetryProvider and then get it back out
54        let _ = set_telemetry_provider(sdk_tp);
55        let global_tp = get_telemetry_provider().unwrap();
56
57        // Create an instrument and record a value
58        let global_meter = global_tp
59            .meter_provider()
60            .get_meter("TestGlobalMeter", None);
61
62        let mono_counter = global_meter
63            .create_monotonic_counter("TestMonoCounter")
64            .build();
65        mono_counter.add(4, None, None);
66
67        sdk_ref.flush().unwrap();
68        let finished_metrics = exporter.get_finished_metrics().unwrap();
69
70        let extracted_mono_counter_data = &finished_metrics[0].scope_metrics[0].metrics[0]
71            .data
72            .as_any()
73            .downcast_ref::<Sum<u64>>()
74            .unwrap()
75            .data_points[0]
76            .value;
77        assert_eq!(extracted_mono_counter_data, &4);
78    }
79}