AWS SDK

AWS SDK

rev. 13a03abd8623d956e96296b8c3fffbcbb753e99e

Files changed:

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

@@ -0,1 +0,24 @@
           1  +
# Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
           2  +
[package]
           3  +
name = "aws-smithy-observability"
           4  +
version = "0.1.0"
           5  +
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
           6  +
description = "Smithy observability implementation."
           7  +
edition = "2021"
           8  +
license = "Apache-2.0"
           9  +
repository = "https://github.com/awslabs/smithy-rs"
          10  +
[package.metadata.docs.rs]
          11  +
all-features = true
          12  +
targets = ["x86_64-unknown-linux-gnu"]
          13  +
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
          14  +
rustdoc-args = ["--cfg", "docsrs"]
          15  +
          16  +
[dependencies]
          17  +
once_cell = "1.19.0"
          18  +
          19  +
[dependencies.aws-smithy-runtime-api]
          20  +
path = "../aws-smithy-runtime-api"
          21  +
version = "1.7.3"
          22  +
          23  +
[dev-dependencies]
          24  +
serial_test = "3.1.1"

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability/LICENSE

@@ -0,1 +0,175 @@
           1  +
           2  +
                                 Apache License
           3  +
                           Version 2.0, January 2004
           4  +
                        http://www.apache.org/licenses/
           5  +
           6  +
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
           7  +
           8  +
   1. Definitions.
           9  +
          10  +
      "License" shall mean the terms and conditions for use, reproduction,
          11  +
      and distribution as defined by Sections 1 through 9 of this document.
          12  +
          13  +
      "Licensor" shall mean the copyright owner or entity authorized by
          14  +
      the copyright owner that is granting the License.
          15  +
          16  +
      "Legal Entity" shall mean the union of the acting entity and all
          17  +
      other entities that control, are controlled by, or are under common
          18  +
      control with that entity. For the purposes of this definition,
          19  +
      "control" means (i) the power, direct or indirect, to cause the
          20  +
      direction or management of such entity, whether by contract or
          21  +
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
          22  +
      outstanding shares, or (iii) beneficial ownership of such entity.
          23  +
          24  +
      "You" (or "Your") shall mean an individual or Legal Entity
          25  +
      exercising permissions granted by this License.
          26  +
          27  +
      "Source" form shall mean the preferred form for making modifications,
          28  +
      including but not limited to software source code, documentation
          29  +
      source, and configuration files.
          30  +
          31  +
      "Object" form shall mean any form resulting from mechanical
          32  +
      transformation or translation of a Source form, including but
          33  +
      not limited to compiled object code, generated documentation,
          34  +
      and conversions to other media types.
          35  +
          36  +
      "Work" shall mean the work of authorship, whether in Source or
          37  +
      Object form, made available under the License, as indicated by a
          38  +
      copyright notice that is included in or attached to the work
          39  +
      (an example is provided in the Appendix below).
          40  +
          41  +
      "Derivative Works" shall mean any work, whether in Source or Object
          42  +
      form, that is based on (or derived from) the Work and for which the
          43  +
      editorial revisions, annotations, elaborations, or other modifications
          44  +
      represent, as a whole, an original work of authorship. For the purposes
          45  +
      of this License, Derivative Works shall not include works that remain
          46  +
      separable from, or merely link (or bind by name) to the interfaces of,
          47  +
      the Work and Derivative Works thereof.
          48  +
          49  +
      "Contribution" shall mean any work of authorship, including
          50  +
      the original version of the Work and any modifications or additions
          51  +
      to that Work or Derivative Works thereof, that is intentionally
          52  +
      submitted to Licensor for inclusion in the Work by the copyright owner
          53  +
      or by an individual or Legal Entity authorized to submit on behalf of
          54  +
      the copyright owner. For the purposes of this definition, "submitted"
          55  +
      means any form of electronic, verbal, or written communication sent
          56  +
      to the Licensor or its representatives, including but not limited to
          57  +
      communication on electronic mailing lists, source code control systems,
          58  +
      and issue tracking systems that are managed by, or on behalf of, the
          59  +
      Licensor for the purpose of discussing and improving the Work, but
          60  +
      excluding communication that is conspicuously marked or otherwise
          61  +
      designated in writing by the copyright owner as "Not a Contribution."
          62  +
          63  +
      "Contributor" shall mean Licensor and any individual or Legal Entity
          64  +
      on behalf of whom a Contribution has been received by Licensor and
          65  +
      subsequently incorporated within the Work.
          66  +
          67  +
   2. Grant of Copyright License. Subject to the terms and conditions of
          68  +
      this License, each Contributor hereby grants to You a perpetual,
          69  +
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
          70  +
      copyright license to reproduce, prepare Derivative Works of,
          71  +
      publicly display, publicly perform, sublicense, and distribute the
          72  +
      Work and such Derivative Works in Source or Object form.
          73  +
          74  +
   3. Grant of Patent License. Subject to the terms and conditions of
          75  +
      this License, each Contributor hereby grants to You a perpetual,
          76  +
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
          77  +
      (except as stated in this section) patent license to make, have made,
          78  +
      use, offer to sell, sell, import, and otherwise transfer the Work,
          79  +
      where such license applies only to those patent claims licensable
          80  +
      by such Contributor that are necessarily infringed by their
          81  +
      Contribution(s) alone or by combination of their Contribution(s)
          82  +
      with the Work to which such Contribution(s) was submitted. If You
          83  +
      institute patent litigation against any entity (including a
          84  +
      cross-claim or counterclaim in a lawsuit) alleging that the Work
          85  +
      or a Contribution incorporated within the Work constitutes direct
          86  +
      or contributory patent infringement, then any patent licenses
          87  +
      granted to You under this License for that Work shall terminate
          88  +
      as of the date such litigation is filed.
          89  +
          90  +
   4. Redistribution. You may reproduce and distribute copies of the
          91  +
      Work or Derivative Works thereof in any medium, with or without
          92  +
      modifications, and in Source or Object form, provided that You
          93  +
      meet the following conditions:
          94  +
          95  +
      (a) You must give any other recipients of the Work or
          96  +
          Derivative Works a copy of this License; and
          97  +
          98  +
      (b) You must cause any modified files to carry prominent notices
          99  +
          stating that You changed the files; and
         100  +
         101  +
      (c) You must retain, in the Source form of any Derivative Works
         102  +
          that You distribute, all copyright, patent, trademark, and
         103  +
          attribution notices from the Source form of the Work,
         104  +
          excluding those notices that do not pertain to any part of
         105  +
          the Derivative Works; and
         106  +
         107  +
      (d) If the Work includes a "NOTICE" text file as part of its
         108  +
          distribution, then any Derivative Works that You distribute must
         109  +
          include a readable copy of the attribution notices contained
         110  +
          within such NOTICE file, excluding those notices that do not
         111  +
          pertain to any part of the Derivative Works, in at least one
         112  +
          of the following places: within a NOTICE text file distributed
         113  +
          as part of the Derivative Works; within the Source form or
         114  +
          documentation, if provided along with the Derivative Works; or,
         115  +
          within a display generated by the Derivative Works, if and
         116  +
          wherever such third-party notices normally appear. The contents
         117  +
          of the NOTICE file are for informational purposes only and
         118  +
          do not modify the License. You may add Your own attribution
         119  +
          notices within Derivative Works that You distribute, alongside
         120  +
          or as an addendum to the NOTICE text from the Work, provided
         121  +
          that such additional attribution notices cannot be construed
         122  +
          as modifying the License.
         123  +
         124  +
      You may add Your own copyright statement to Your modifications and
         125  +
      may provide additional or different license terms and conditions
         126  +
      for use, reproduction, or distribution of Your modifications, or
         127  +
      for any such Derivative Works as a whole, provided Your use,
         128  +
      reproduction, and distribution of the Work otherwise complies with
         129  +
      the conditions stated in this License.
         130  +
         131  +
   5. Submission of Contributions. Unless You explicitly state otherwise,
         132  +
      any Contribution intentionally submitted for inclusion in the Work
         133  +
      by You to the Licensor shall be under the terms and conditions of
         134  +
      this License, without any additional terms or conditions.
         135  +
      Notwithstanding the above, nothing herein shall supersede or modify
         136  +
      the terms of any separate license agreement you may have executed
         137  +
      with Licensor regarding such Contributions.
         138  +
         139  +
   6. Trademarks. This License does not grant permission to use the trade
         140  +
      names, trademarks, service marks, or product names of the Licensor,
         141  +
      except as required for reasonable and customary use in describing the
         142  +
      origin of the Work and reproducing the content of the NOTICE file.
         143  +
         144  +
   7. Disclaimer of Warranty. Unless required by applicable law or
         145  +
      agreed to in writing, Licensor provides the Work (and each
         146  +
      Contributor provides its Contributions) on an "AS IS" BASIS,
         147  +
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
         148  +
      implied, including, without limitation, any warranties or conditions
         149  +
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
         150  +
      PARTICULAR PURPOSE. You are solely responsible for determining the
         151  +
      appropriateness of using or redistributing the Work and assume any
         152  +
      risks associated with Your exercise of permissions under this License.
         153  +
         154  +
   8. Limitation of Liability. In no event and under no legal theory,
         155  +
      whether in tort (including negligence), contract, or otherwise,
         156  +
      unless required by applicable law (such as deliberate and grossly
         157  +
      negligent acts) or agreed to in writing, shall any Contributor be
         158  +
      liable to You for damages, including any direct, indirect, special,
         159  +
      incidental, or consequential damages of any character arising as a
         160  +
      result of this License or out of the use or inability to use the
         161  +
      Work (including but not limited to damages for loss of goodwill,
         162  +
      work stoppage, computer failure or malfunction, or any and all
         163  +
      other commercial damages or losses), even if such Contributor
         164  +
      has been advised of the possibility of such damages.
         165  +
         166  +
   9. Accepting Warranty or Additional Liability. While redistributing
         167  +
      the Work or Derivative Works thereof, You may choose to offer,
         168  +
      and charge a fee for, acceptance of support, warranty, indemnity,
         169  +
      or other liability obligations and/or rights consistent with this
         170  +
      License. However, in accepting such obligations, You may act only
         171  +
      on Your own behalf and on Your sole responsibility, not on behalf
         172  +
      of any other Contributor, and only if You agree to indemnify,
         173  +
      defend, and hold each Contributor harmless for any liability
         174  +
      incurred by, or claims asserted against, such Contributor by reason
         175  +
      of your accepting any such warranty or additional liability.

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability/README.md

@@ -0,1 +0,7 @@
           1  +
# aws-smithy-observability
           2  +
           3  +
This crate contains traits allowing for the implementation of `TelemetryProvider`s for the AWS SDK for Rust. It also contains a `global` module for setting and interacting with the current `GlobalTelemetryProvider`.
           4  +
           5  +
<!-- anchor_start:footer -->
           6  +
This crate is part of the [AWS SDK for Rust](https://awslabs.github.io/aws-sdk-rust/) and the [smithy-rs](https://github.com/smithy-lang/smithy-rs) code generator. In most cases, it should not be used directly.
           7  +
<!-- anchor_end:footer -->

tmp-codegen-diff/aws-sdk/sdk/aws-smithy-observability/external-types.toml

@@ -0,1 +0,3 @@
           1  +
allowed_external_types = [
           2  +
    "aws_smithy_runtime_api::box_error::BoxError",
           3  +
]

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

@@ -0,1 +0,58 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Attributes (also referred to as tags or annotations in other telemetry systems) are structured
           7  +
//! key-value pairs that annotate a span or event. Structured data allows observability backends
           8  +
//! to index and process telemetry data in ways that simple log messages lack.
           9  +
          10  +
use std::collections::HashMap;
          11  +
          12  +
/// The valid types of values accepted by [Attributes].
          13  +
#[non_exhaustive]
          14  +
#[derive(Clone, Debug, PartialEq)]
          15  +
pub enum AttributeValue {
          16  +
    /// Holds an [i64]
          17  +
    I64(i64),
          18  +
    /// Holds an [f64]
          19  +
    F64(f64),
          20  +
    /// Holds a [String]
          21  +
    String(String),
          22  +
    /// Holds a [bool]
          23  +
    Bool(bool),
          24  +
}
          25  +
          26  +
/// Structured telemetry metadata.
          27  +
#[non_exhaustive]
          28  +
#[derive(Clone, Default)]
          29  +
pub struct Attributes {
          30  +
    attrs: HashMap<String, AttributeValue>,
          31  +
}
          32  +
          33  +
impl Attributes {
          34  +
    /// Create a new empty instance of [Attributes].
          35  +
    pub fn new() -> Self {
          36  +
        Self::default()
          37  +
    }
          38  +
          39  +
    /// Set an attribute.
          40  +
    pub fn set(&mut self, key: impl Into<String>, value: impl Into<AttributeValue>) {
          41  +
        self.attrs.insert(key.into(), value.into());
          42  +
    }
          43  +
          44  +
    /// Get an attribute.
          45  +
    pub fn get(&self, key: impl Into<String>) -> Option<&AttributeValue> {
          46  +
        self.attrs.get(&key.into())
          47  +
    }
          48  +
          49  +
    /// Get all of the attribute key value pairs.
          50  +
    pub fn attributes(&self) -> &HashMap<String, AttributeValue> {
          51  +
        &self.attrs
          52  +
    }
          53  +
          54  +
    /// Get an owned [Iterator] of ([String], [AttributeValue]).
          55  +
    pub fn into_attributes(self) -> impl Iterator<Item = (String, AttributeValue)> {
          56  +
        self.attrs.into_iter()
          57  +
    }
          58  +
}

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

@@ -0,1 +0,26 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
/// Delineates a logical scope that has some beginning and end
           7  +
/// (e.g. a function or block of code).
           8  +
pub trait Scope {
           9  +
    /// invoke when the scope has ended.
          10  +
    fn end(&self);
          11  +
}
          12  +
          13  +
/// A cross cutting concern for carrying execution-scoped values across API
          14  +
/// boundaries (both in-process and distributed).
          15  +
pub trait Context {
          16  +
    /// Make this context the currently active context.
          17  +
    /// The returned handle is used to return the previous
          18  +
    /// context (if one existed) as active.
          19  +
    fn make_current(&self) -> &dyn Scope;
          20  +
}
          21  +
          22  +
/// Keeps track of the current [Context].
          23  +
pub trait ContextManager {
          24  +
    ///Get the currently active context.
          25  +
    fn current(&self) -> &dyn Context;
          26  +
}

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

@@ -0,1 +0,80 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Observability Errors
           7  +
           8  +
use std::fmt;
           9  +
          10  +
use aws_smithy_runtime_api::box_error::BoxError;
          11  +
          12  +
/// An error in the SDKs Observability providers
          13  +
#[non_exhaustive]
          14  +
#[derive(Debug)]
          15  +
pub struct ObservabilityError {
          16  +
    kind: ErrorKind,
          17  +
    source: BoxError,
          18  +
}
          19  +
          20  +
/// The types of errors associated with [ObservabilityError]
          21  +
#[non_exhaustive]
          22  +
#[derive(Debug)]
          23  +
pub enum ErrorKind {
          24  +
    /// A custom error that does not fall under any other error kind
          25  +
    Other,
          26  +
}
          27  +
          28  +
impl ObservabilityError {
          29  +
    /// Create a new [`ObservabilityError`] from an [ErrorKind] and a [BoxError]
          30  +
    pub fn new<E>(kind: ErrorKind, err: E) -> Self
          31  +
    where
          32  +
        E: Into<BoxError>,
          33  +
    {
          34  +
        Self {
          35  +
            kind,
          36  +
            source: err.into(),
          37  +
        }
          38  +
    }
          39  +
          40  +
    /// Returns the corresponding [`ErrorKind`] for this error.
          41  +
    pub fn kind(&self) -> &ErrorKind {
          42  +
        &self.kind
          43  +
    }
          44  +
}
          45  +
          46  +
impl fmt::Display for ObservabilityError {
          47  +
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
          48  +
        match &self.kind {
          49  +
            ErrorKind::Other => write!(f, "unclassified error"),
          50  +
        }
          51  +
    }
          52  +
}
          53  +
          54  +
impl std::error::Error for ObservabilityError {
          55  +
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
          56  +
        Some(self.source.as_ref())
          57  +
    }
          58  +
}
          59  +
          60  +
/// An simple error to represent issues with the global [crate::TelemetryProvider].
          61  +
#[non_exhaustive]
          62  +
#[derive(Debug)]
          63  +
pub struct GlobalTelemetryProviderError {
          64  +
    reason: &'static str,
          65  +
}
          66  +
          67  +
impl GlobalTelemetryProviderError {
          68  +
    /// Create a new [GlobalTelemetryProviderError] with a given reason for the error.
          69  +
    pub fn new(reason: &'static str) -> Self {
          70  +
        Self { reason }
          71  +
    }
          72  +
}
          73  +
          74  +
impl std::error::Error for GlobalTelemetryProviderError {}
          75  +
          76  +
impl fmt::Display for GlobalTelemetryProviderError {
          77  +
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
          78  +
        write!(f, "GlobalTelemetryProviderError: {}", self.reason)
          79  +
    }
          80  +
}

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

@@ -0,1 +0,86 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Utilities for interacting with the currently set `GlobalTelemetryProvider`
           7  +
           8  +
use once_cell::sync::Lazy;
           9  +
use std::{
          10  +
    mem,
          11  +
    sync::{Arc, RwLock},
          12  +
};
          13  +
          14  +
use crate::{
          15  +
    error::{ErrorKind, GlobalTelemetryProviderError},
          16  +
    provider::{GlobalTelemetryProvider, TelemetryProvider},
          17  +
    ObservabilityError,
          18  +
};
          19  +
          20  +
// Statically store the global provider
          21  +
static GLOBAL_TELEMETRY_PROVIDER: Lazy<RwLock<GlobalTelemetryProvider>> =
          22  +
    Lazy::new(|| RwLock::new(GlobalTelemetryProvider::new(TelemetryProvider::default())));
          23  +
          24  +
/// Set the current global [TelemetryProvider].
          25  +
///
          26  +
/// This is meant to be run once at the beginning of an application. Will return an [Err] if the
          27  +
/// [RwLock] holding the global [TelemetryProvider] is locked or poisoned.
          28  +
pub fn set_telemetry_provider(new_provider: TelemetryProvider) -> Result<(), ObservabilityError> {
          29  +
    if let Ok(mut old_provider) = GLOBAL_TELEMETRY_PROVIDER.try_write() {
          30  +
        let new_global_provider = GlobalTelemetryProvider::new(new_provider);
          31  +
          32  +
        let _ = mem::replace(&mut *old_provider, new_global_provider);
          33  +
          34  +
        Ok(())
          35  +
    } else {
          36  +
        Err(ObservabilityError::new(
          37  +
            ErrorKind::Other,
          38  +
            GlobalTelemetryProviderError::new("Failed to set global TelemetryProvider."),
          39  +
        ))
          40  +
    }
          41  +
}
          42  +
          43  +
/// Get an [Arc] reference to the current global [TelemetryProvider]. Will return an [Err] if the
          44  +
/// [RwLock] holding the global [TelemetryProvider] is locked or poisoned.
          45  +
pub fn get_telemetry_provider() -> Result<Arc<TelemetryProvider>, ObservabilityError> {
          46  +
    if let Ok(tp) = GLOBAL_TELEMETRY_PROVIDER.try_read() {
          47  +
        Ok(tp.telemetry_provider().clone())
          48  +
    } else {
          49  +
        Err(ObservabilityError::new(
          50  +
            ErrorKind::Other,
          51  +
            GlobalTelemetryProviderError::new("Failed to get global TelemetryProvider"),
          52  +
        ))
          53  +
    }
          54  +
}
          55  +
          56  +
#[cfg(test)]
          57  +
mod tests {
          58  +
    use super::*;
          59  +
    use crate::provider::TelemetryProvider;
          60  +
    use serial_test::serial;
          61  +
          62  +
    // Note: the tests in this module are run serially to prevent them from stepping on each other and poisoning the
          63  +
    // RwLock holding the GlobalTelemetryProvider
          64  +
    #[test]
          65  +
    #[serial]
          66  +
    fn can_set_global_telemetry_provider() {
          67  +
        let my_provider = TelemetryProvider::default();
          68  +
          69  +
        // Set the new counter and get a reference to the old one
          70  +
        set_telemetry_provider(my_provider).unwrap();
          71  +
    }
          72  +
          73  +
    #[test]
          74  +
    #[serial]
          75  +
    fn can_get_global_telemetry_provider() {
          76  +
        let curr_provider = get_telemetry_provider().unwrap();
          77  +
          78  +
        // Use the global provider to create an instrument and record a value with it
          79  +
        let curr_mp = curr_provider.meter_provider();
          80  +
        let curr_meter = curr_mp.get_meter("TestMeter", None);
          81  +
        let instrument = curr_meter
          82  +
            .create_monotonic_counter("TestMonoCounter")
          83  +
            .build();
          84  +
        instrument.add(4, None, None);
          85  +
    }
          86  +
}

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

@@ -0,1 +0,246 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Instruments are used to record values for metrics.
           7  +
           8  +
use std::{borrow::Cow, fmt::Debug, marker::PhantomData, sync::Arc};
           9  +
          10  +
use crate::{meter::Meter, Attributes, Context};
          11  +
          12  +
/// Configuration for building a sync instrument.
          13  +
#[non_exhaustive]
          14  +
pub struct InstrumentBuilder<'a, T> {
          15  +
    instrument_provider: &'a dyn ProvideInstrument,
          16  +
    name: Cow<'static, str>,
          17  +
    description: Option<Cow<'static, str>>,
          18  +
    units: Option<Cow<'static, str>>,
          19  +
    _phantom: PhantomData<T>,
          20  +
}
          21  +
          22  +
impl<'a, T> InstrumentBuilder<'a, T> {
          23  +
    /// Create a new instrument builder
          24  +
    pub(crate) fn new(meter: &'a Meter, name: Cow<'static, str>) -> Self {
          25  +
        InstrumentBuilder {
          26  +
            instrument_provider: meter.instrument_provider.as_ref(),
          27  +
            name,
          28  +
            description: None,
          29  +
            units: None,
          30  +
            _phantom: PhantomData::<T>,
          31  +
        }
          32  +
    }
          33  +
          34  +
    /// Get the name.
          35  +
    pub fn get_name(&self) -> &Cow<'static, str> {
          36  +
        &self.name
          37  +
    }
          38  +
          39  +
    /// Set the description.
          40  +
    pub fn set_description(mut self, description: impl Into<Cow<'static, str>>) -> Self {
          41  +
        self.description = Some(description.into());
          42  +
        self
          43  +
    }
          44  +
          45  +
    /// Get the description.
          46  +
    pub fn get_description(&self) -> &Option<Cow<'static, str>> {
          47  +
        &self.description
          48  +
    }
          49  +
          50  +
    /// Set the units.
          51  +
    pub fn set_units(mut self, units: impl Into<Cow<'static, str>>) -> Self {
          52  +
        self.units = Some(units.into());
          53  +
        self
          54  +
    }
          55  +
          56  +
    /// Get the units.
          57  +
    pub fn get_units(&self) -> &Option<Cow<'static, str>> {
          58  +
        &self.units
          59  +
    }
          60  +
}
          61  +
          62  +
/// Takes in the name of function from [ProvideInstrument] and the type of instrument being created
          63  +
/// (ex: [Histogram]) and adds a `build` function for it.
          64  +
macro_rules! build_instrument {
          65  +
    ($name:ident, $instrument:ty) => {
          66  +
        impl<'a> InstrumentBuilder<'a, $instrument> {
          67  +
            #[doc = concat!("Create a new `",  stringify!($instrument), "`.")]
          68  +
            pub fn build(self) -> $instrument {
          69  +
                self.instrument_provider.$name(self)
          70  +
            }
          71  +
        }
          72  +
    };
          73  +
}
          74  +
          75  +
build_instrument!(create_histogram, Arc<dyn Histogram>);
          76  +
build_instrument!(create_monotonic_counter, Arc<dyn MonotonicCounter>);
          77  +
build_instrument!(create_up_down_counter, Arc<dyn UpDownCounter>);
          78  +
          79  +
/// Configuration for building an async instrument.
          80  +
#[non_exhaustive]
          81  +
pub struct AsyncInstrumentBuilder<'a, T, M> {
          82  +
    instrument_provider: &'a dyn ProvideInstrument,
          83  +
    name: Cow<'static, str>,
          84  +
    // Implementation note: I could not make the lifetimes work out in the impl ProvideInstrument
          85  +
    // in aws-smithy-observability-otel without making this field pub
          86  +
    /// The callback function for this AsyncInstrumentBuilder.
          87  +
    #[allow(clippy::type_complexity)]
          88  +
    pub callback: Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync>,
          89  +
    description: Option<Cow<'static, str>>,
          90  +
    units: Option<Cow<'static, str>>,
          91  +
    _phantom: PhantomData<T>,
          92  +
}
          93  +
          94  +
#[allow(clippy::type_complexity)]
          95  +
impl<'a, T, M> AsyncInstrumentBuilder<'a, T, M> {
          96  +
    /// Create a new async instrument builder
          97  +
    pub(crate) fn new(
          98  +
        meter: &'a Meter,
          99  +
        name: Cow<'static, str>,
         100  +
        callback: Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync>,
         101  +
    ) -> Self {
         102  +
        AsyncInstrumentBuilder {
         103  +
            instrument_provider: meter.instrument_provider.as_ref(),
         104  +
            name,
         105  +
            callback,
         106  +
            description: None,
         107  +
            units: None,
         108  +
            _phantom: PhantomData::<T>,
         109  +
        }
         110  +
    }
         111  +
         112  +
    /// Get the name.
         113  +
    pub fn get_name(&self) -> &Cow<'static, str> {
         114  +
        &self.name
         115  +
    }
         116  +
         117  +
    /// Get the callback function.
         118  +
    pub fn get_callback(&self) -> Arc<dyn Fn(&dyn AsyncMeasure<Value = M>) + Send + Sync> {
         119  +
        self.callback.clone()
         120  +
    }
         121  +
         122  +
    /// Set the description.
         123  +
    pub fn set_description(mut self, description: impl Into<Cow<'static, str>>) -> Self {
         124  +
        self.description = Some(description.into());
         125  +
        self
         126  +
    }
         127  +
         128  +
    /// Get the description.
         129  +
    pub fn get_description(&self) -> &Option<Cow<'static, str>> {
         130  +
        &self.description
         131  +
    }
         132  +
         133  +
    /// Set the units.
         134  +
    pub fn set_units(mut self, units: impl Into<Cow<'static, str>>) -> Self {
         135  +
        self.units = Some(units.into());
         136  +
        self
         137  +
    }
         138  +
         139  +
    /// Get the units.
         140  +
    pub fn get_units(&self) -> &Option<Cow<'static, str>> {
         141  +
        &self.units
         142  +
    }
         143  +
}
         144  +
         145  +
/// Takes in the name of function from [ProvideInstrument] and the type of instrument being created
         146  +
/// (ex: [AsyncMeasure]) and adds a `build` function for it.
         147  +
//TODO(observability): Can I derive the measurement from the Value of the instrument type or vice versa?
         148  +
macro_rules! build_async_instrument {
         149  +
    ($name:ident, $instrument:ty, $measurement:ty) => {
         150  +
        impl<'a> AsyncInstrumentBuilder<'a, $instrument, $measurement> {
         151  +
            #[doc = concat!("Create a new `",  stringify!($instrument), "`.")]
         152  +
            pub fn build(self) -> $instrument {
         153  +
                self.instrument_provider.$name(self)
         154  +
            }
         155  +
        }
         156  +
    };
         157  +
}
         158  +
         159  +
build_async_instrument!(create_gauge, Arc<dyn AsyncMeasure<Value = f64>>, f64);
         160  +
build_async_instrument!(
         161  +
    create_async_up_down_counter,
         162  +
    Arc<dyn AsyncMeasure<Value = i64>>,
         163  +
    i64
         164  +
);
         165  +
build_async_instrument!(
         166  +
    create_async_monotonic_counter,
         167  +
    Arc<dyn AsyncMeasure<Value = u64>>,
         168  +
    u64
         169  +
);
         170  +
         171  +
/// The entry point to creating instruments. A grouping of related metrics.
         172  +
pub trait ProvideInstrument: Send + Sync + Debug {
         173  +
    /// Create a new Gauge.
         174  +
    #[allow(clippy::type_complexity)]
         175  +
    fn create_gauge(
         176  +
        &self,
         177  +
        builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = f64>>, f64>,
         178  +
    ) -> Arc<dyn AsyncMeasure<Value = f64>>;
         179  +
         180  +
    /// Create a new [UpDownCounter].
         181  +
    fn create_up_down_counter(
         182  +
        &self,
         183  +
        builder: InstrumentBuilder<'_, Arc<dyn UpDownCounter>>,
         184  +
    ) -> Arc<dyn UpDownCounter>;
         185  +
         186  +
    /// Create a new AsyncUpDownCounter.
         187  +
    #[allow(clippy::type_complexity)]
         188  +
    fn create_async_up_down_counter(
         189  +
        &self,
         190  +
        builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = i64>>, i64>,
         191  +
    ) -> Arc<dyn AsyncMeasure<Value = i64>>;
         192  +
         193  +
    /// Create a new [MonotonicCounter].
         194  +
    fn create_monotonic_counter(
         195  +
        &self,
         196  +
        builder: InstrumentBuilder<'_, Arc<dyn MonotonicCounter>>,
         197  +
    ) -> Arc<dyn MonotonicCounter>;
         198  +
         199  +
    /// Create a new AsyncMonotonicCounter.
         200  +
    #[allow(clippy::type_complexity)]
         201  +
    fn create_async_monotonic_counter(
         202  +
        &self,
         203  +
        builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = u64>>, u64>,
         204  +
    ) -> Arc<dyn AsyncMeasure<Value = u64>>;
         205  +
         206  +
    /// Create a new [Histogram].
         207  +
    fn create_histogram(
         208  +
        &self,
         209  +
        builder: InstrumentBuilder<'_, Arc<dyn Histogram>>,
         210  +
    ) -> Arc<dyn Histogram>;
         211  +
}
         212  +
         213  +
/// Collects a set of events with an event count and sum for all events.
         214  +
pub trait Histogram: Send + Sync + Debug {
         215  +
    /// Record a value.
         216  +
    fn record(&self, value: f64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
         217  +
}
         218  +
         219  +
/// A counter that monotonically increases.
         220  +
pub trait MonotonicCounter: Send + Sync + Debug {
         221  +
    /// Increment a counter by a fixed amount.
         222  +
    fn add(&self, value: u64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
         223  +
}
         224  +
         225  +
/// A counter that can increase or decrease.
         226  +
pub trait UpDownCounter: Send + Sync + Debug {
         227  +
    /// Increment or decrement a counter by a fixed amount.
         228  +
    fn add(&self, value: i64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
         229  +
}
         230  +
         231  +
/// A measurement that can be taken asynchronously.
         232  +
pub trait AsyncMeasure: Send + Sync + Debug {
         233  +
    /// The type recorded by the measurement.
         234  +
    type Value;
         235  +
         236  +
    /// Record a value
         237  +
    fn record(
         238  +
        &self,
         239  +
        value: Self::Value,
         240  +
        attributes: Option<&Attributes>,
         241  +
        context: Option<&dyn Context>,
         242  +
    );
         243  +
         244  +
    /// Stop recording, unregister callback.
         245  +
    fn stop(&self);
         246  +
}

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

@@ -0,1 +0,31 @@
           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_auto_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  +
          16  +
//! Smithy Observability
          17  +
// TODO(smithyobservability): once we have finalized everything and integrated metrics with our runtime
          18  +
// libraries update this with detailed usage docs and examples
          19  +
          20  +
mod attributes;
          21  +
pub use attributes::{AttributeValue, Attributes};
          22  +
mod context;
          23  +
pub use context::{Context, ContextManager, Scope};
          24  +
mod error;
          25  +
pub use error::{ErrorKind, GlobalTelemetryProviderError, ObservabilityError};
          26  +
pub mod global;
          27  +
pub mod meter;
          28  +
mod noop;
          29  +
mod provider;
          30  +
pub use provider::{TelemetryProvider, TelemetryProviderBuilder};
          31  +
pub mod instruments;

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

@@ -0,1 +0,98 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Metrics are used to gain insight into the operational performance and health of a system in
           7  +
//! real time.
           8  +
           9  +
use crate::instruments::{
          10  +
    AsyncInstrumentBuilder, AsyncMeasure, Histogram, InstrumentBuilder, MonotonicCounter,
          11  +
    UpDownCounter,
          12  +
};
          13  +
use crate::{attributes::Attributes, instruments::ProvideInstrument};
          14  +
use std::{borrow::Cow, fmt::Debug, sync::Arc};
          15  +
          16  +
/// Provides named instances of [Meter].
          17  +
pub trait ProvideMeter: Send + Sync + Debug {
          18  +
    /// Get or create a named [Meter].
          19  +
    fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Meter;
          20  +
}
          21  +
          22  +
/// The entry point to creating instruments. A grouping of related metrics.
          23  +
#[derive(Clone)]
          24  +
pub struct Meter {
          25  +
    pub(crate) instrument_provider: Arc<dyn ProvideInstrument + Send + Sync>,
          26  +
}
          27  +
          28  +
impl Meter {
          29  +
    /// Create a new [Meter] from an [ProvideInstrument]
          30  +
    pub fn new(instrument_provider: Arc<dyn ProvideInstrument + Send + Sync>) -> Self {
          31  +
        Meter {
          32  +
            instrument_provider,
          33  +
        }
          34  +
    }
          35  +
          36  +
    /// Create a new Gauge.
          37  +
    #[allow(clippy::type_complexity)]
          38  +
    pub fn create_gauge<F>(
          39  +
        &self,
          40  +
        name: impl Into<Cow<'static, str>>,
          41  +
        callback: F,
          42  +
    ) -> AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = f64>>, f64>
          43  +
    where
          44  +
        F: Fn(&dyn AsyncMeasure<Value = f64>) + Send + Sync + 'static,
          45  +
    {
          46  +
        AsyncInstrumentBuilder::new(self, name.into(), Arc::new(callback))
          47  +
    }
          48  +
          49  +
    /// Create a new [UpDownCounter].
          50  +
    pub fn create_up_down_counter(
          51  +
        &self,
          52  +
        name: impl Into<Cow<'static, str>>,
          53  +
    ) -> InstrumentBuilder<'_, Arc<dyn UpDownCounter>> {
          54  +
        InstrumentBuilder::new(self, name.into())
          55  +
    }
          56  +
          57  +
    /// Create a new AsyncUpDownCounter.
          58  +
    #[allow(clippy::type_complexity)]
          59  +
    pub fn create_async_up_down_counter<F>(
          60  +
        &self,
          61  +
        name: impl Into<Cow<'static, str>>,
          62  +
        callback: F,
          63  +
    ) -> AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = i64>>, i64>
          64  +
    where
          65  +
        F: Fn(&dyn AsyncMeasure<Value = i64>) + Send + Sync + 'static,
          66  +
    {
          67  +
        AsyncInstrumentBuilder::new(self, name.into(), Arc::new(callback))
          68  +
    }
          69  +
          70  +
    /// Create a new [MonotonicCounter].
          71  +
    pub fn create_monotonic_counter(
          72  +
        &self,
          73  +
        name: impl Into<Cow<'static, str>>,
          74  +
    ) -> InstrumentBuilder<'_, Arc<dyn MonotonicCounter>> {
          75  +
        InstrumentBuilder::new(self, name.into())
          76  +
    }
          77  +
          78  +
    /// Create a new AsyncMonotonicCounter.
          79  +
    #[allow(clippy::type_complexity)]
          80  +
    pub fn create_async_monotonic_counter<F>(
          81  +
        &self,
          82  +
        name: impl Into<Cow<'static, str>>,
          83  +
        callback: F,
          84  +
    ) -> AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = u64>>, u64>
          85  +
    where
          86  +
        F: Fn(&dyn AsyncMeasure<Value = u64>) + Send + Sync + 'static,
          87  +
    {
          88  +
        AsyncInstrumentBuilder::new(self, name.into(), Arc::new(callback))
          89  +
    }
          90  +
          91  +
    /// Create a new [Histogram].
          92  +
    pub fn create_histogram(
          93  +
        &self,
          94  +
        name: impl Into<Cow<'static, str>>,
          95  +
    ) -> InstrumentBuilder<'_, Arc<dyn Histogram>> {
          96  +
        InstrumentBuilder::new(self, name.into())
          97  +
    }
          98  +
}

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

@@ -0,1 +0,107 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! An noop implementation of the Meter traits
           7  +
           8  +
use std::marker::PhantomData;
           9  +
use std::{fmt::Debug, sync::Arc};
          10  +
          11  +
use crate::instruments::{
          12  +
    AsyncInstrumentBuilder, AsyncMeasure, Histogram, InstrumentBuilder, MonotonicCounter,
          13  +
    ProvideInstrument, UpDownCounter,
          14  +
};
          15  +
use crate::{
          16  +
    attributes::Attributes,
          17  +
    context::Context,
          18  +
    meter::{Meter, ProvideMeter},
          19  +
};
          20  +
          21  +
#[derive(Debug)]
          22  +
pub(crate) struct NoopMeterProvider;
          23  +
impl ProvideMeter for NoopMeterProvider {
          24  +
    fn get_meter(&self, _scope: &'static str, _attributes: Option<&Attributes>) -> Meter {
          25  +
        Meter::new(Arc::new(NoopMeter))
          26  +
    }
          27  +
}
          28  +
          29  +
#[derive(Debug)]
          30  +
pub(crate) struct NoopMeter;
          31  +
impl ProvideInstrument for NoopMeter {
          32  +
    fn create_gauge(
          33  +
        &self,
          34  +
        _builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = f64>>, f64>,
          35  +
    ) -> Arc<dyn AsyncMeasure<Value = f64>> {
          36  +
        Arc::new(NoopAsyncMeasurement(PhantomData::<f64>))
          37  +
    }
          38  +
          39  +
    fn create_up_down_counter(
          40  +
        &self,
          41  +
        _builder: InstrumentBuilder<'_, Arc<dyn UpDownCounter>>,
          42  +
    ) -> Arc<dyn UpDownCounter> {
          43  +
        Arc::new(NoopUpDownCounter)
          44  +
    }
          45  +
          46  +
    fn create_async_up_down_counter(
          47  +
        &self,
          48  +
        _builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = i64>>, i64>,
          49  +
    ) -> Arc<dyn AsyncMeasure<Value = i64>> {
          50  +
        Arc::new(NoopAsyncMeasurement(PhantomData::<i64>))
          51  +
    }
          52  +
          53  +
    fn create_monotonic_counter(
          54  +
        &self,
          55  +
        _builder: InstrumentBuilder<'_, Arc<dyn MonotonicCounter>>,
          56  +
    ) -> Arc<dyn MonotonicCounter> {
          57  +
        Arc::new(NoopMonotonicCounter)
          58  +
    }
          59  +
          60  +
    fn create_async_monotonic_counter(
          61  +
        &self,
          62  +
        _builder: AsyncInstrumentBuilder<'_, Arc<dyn AsyncMeasure<Value = u64>>, u64>,
          63  +
    ) -> Arc<dyn AsyncMeasure<Value = u64>> {
          64  +
        Arc::new(NoopAsyncMeasurement(PhantomData::<u64>))
          65  +
    }
          66  +
          67  +
    fn create_histogram(
          68  +
        &self,
          69  +
        _builder: InstrumentBuilder<'_, Arc<dyn Histogram>>,
          70  +
    ) -> Arc<dyn Histogram> {
          71  +
        Arc::new(NoopHistogram)
          72  +
    }
          73  +
}
          74  +
          75  +
#[derive(Debug)]
          76  +
struct NoopAsyncMeasurement<T: Send + Sync + Debug>(PhantomData<T>);
          77  +
impl<T: Send + Sync + Debug> AsyncMeasure for NoopAsyncMeasurement<T> {
          78  +
    type Value = T;
          79  +
          80  +
    fn record(&self, _value: T, _attributes: Option<&Attributes>, _context: Option<&dyn Context>) {}
          81  +
          82  +
    fn stop(&self) {}
          83  +
}
          84  +
          85  +
#[derive(Debug)]
          86  +
struct NoopUpDownCounter;
          87  +
impl UpDownCounter for NoopUpDownCounter {
          88  +
    fn add(&self, _value: i64, _attributes: Option<&Attributes>, _context: Option<&dyn Context>) {}
          89  +
}
          90  +
          91  +
#[derive(Debug)]
          92  +
struct NoopMonotonicCounter;
          93  +
impl MonotonicCounter for NoopMonotonicCounter {
          94  +
    fn add(&self, _value: u64, _attributes: Option<&Attributes>, _context: Option<&dyn Context>) {}
          95  +
}
          96  +
          97  +
#[derive(Debug)]
          98  +
struct NoopHistogram;
          99  +
impl Histogram for NoopHistogram {
         100  +
    fn record(
         101  +
        &self,
         102  +
        _value: f64,
         103  +
        _attributes: Option<&Attributes>,
         104  +
        _context: Option<&dyn Context>,
         105  +
    ) {
         106  +
    }
         107  +
}

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

@@ -0,1 +0,89 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Definitions of high level Telemetry Providers.
           7  +
           8  +
use std::sync::Arc;
           9  +
          10  +
use crate::{meter::ProvideMeter, noop::NoopMeterProvider};
          11  +
          12  +
/// A struct to hold the various types of telemetry providers.
          13  +
#[non_exhaustive]
          14  +
pub struct TelemetryProvider {
          15  +
    meter_provider: Arc<dyn ProvideMeter + Send + Sync>,
          16  +
}
          17  +
          18  +
impl TelemetryProvider {
          19  +
    /// Returns a builder struct for [TelemetryProvider]
          20  +
    pub fn builder() -> TelemetryProviderBuilder {
          21  +
        TelemetryProviderBuilder {
          22  +
            meter_provider: Arc::new(NoopMeterProvider),
          23  +
        }
          24  +
    }
          25  +
          26  +
    /// Returns a noop [TelemetryProvider]
          27  +
    pub fn noop() -> TelemetryProvider {
          28  +
        Self {
          29  +
            meter_provider: Arc::new(NoopMeterProvider),
          30  +
        }
          31  +
    }
          32  +
          33  +
    /// Get the set [ProvideMeter]
          34  +
    pub fn meter_provider(&self) -> &(dyn ProvideMeter + Send + Sync) {
          35  +
        self.meter_provider.as_ref()
          36  +
    }
          37  +
}
          38  +
          39  +
// If we choose to expand our Telemetry provider and make Logging and Tracing
          40  +
// configurable at some point in the future we can do that by adding default
          41  +
// logger_provider and tracer_providers based on `tracing` to maintain backwards
          42  +
// compatibilty with what we have today.
          43  +
impl Default for TelemetryProvider {
          44  +
    fn default() -> Self {
          45  +
        Self {
          46  +
            meter_provider: Arc::new(NoopMeterProvider),
          47  +
        }
          48  +
    }
          49  +
}
          50  +
          51  +
/// A builder for [TelemetryProvider].
          52  +
#[non_exhaustive]
          53  +
pub struct TelemetryProviderBuilder {
          54  +
    meter_provider: Arc<dyn ProvideMeter + Send + Sync>,
          55  +
}
          56  +
          57  +
impl TelemetryProviderBuilder {
          58  +
    /// Set the [ProvideMeter].
          59  +
    pub fn meter_provider(mut self, meter_provider: Arc<impl ProvideMeter + 'static>) -> Self {
          60  +
        self.meter_provider = meter_provider;
          61  +
        self
          62  +
    }
          63  +
          64  +
    /// Build the [TelemetryProvider].
          65  +
    pub fn build(self) -> TelemetryProvider {
          66  +
        TelemetryProvider {
          67  +
            meter_provider: self.meter_provider,
          68  +
        }
          69  +
    }
          70  +
}
          71  +
          72  +
/// Wrapper type to hold a implementer of TelemetryProvider in an Arc so that
          73  +
/// it can be safely used across threads.
          74  +
#[non_exhaustive]
          75  +
pub(crate) struct GlobalTelemetryProvider {
          76  +
    pub(crate) telemetry_provider: Arc<TelemetryProvider>,
          77  +
}
          78  +
          79  +
impl GlobalTelemetryProvider {
          80  +
    pub(crate) fn new(telemetry_provider: TelemetryProvider) -> Self {
          81  +
        Self {
          82  +
            telemetry_provider: Arc::new(telemetry_provider),
          83  +
        }
          84  +
    }
          85  +
          86  +
    pub(crate) fn telemetry_provider(&self) -> &Arc<TelemetryProvider> {
          87  +
        &self.telemetry_provider
          88  +
    }
          89  +
}