AWS SDK

AWS SDK

rev. ad61026a50d52029b7d26fd97aa5ad9030d8287b

Files changed:

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. I 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,83 @@
           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)]
          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 {
          37  +
            attrs: HashMap::new(),
          38  +
        }
          39  +
    }
          40  +
          41  +
    /// Set an attribute.
          42  +
    pub fn set(&mut self, key: String, value: AttributeValue) {
          43  +
        self.attrs.insert(key, value);
          44  +
    }
          45  +
          46  +
    /// Get an attribute.
          47  +
    pub fn get(&self, key: String) -> Option<&AttributeValue> {
          48  +
        self.attrs.get(&key)
          49  +
    }
          50  +
          51  +
    /// Get all of the attribute key value pairs.
          52  +
    pub fn attributes(&self) -> &HashMap<String, AttributeValue> {
          53  +
        &self.attrs
          54  +
    }
          55  +
}
          56  +
          57  +
impl Default for Attributes {
          58  +
    fn default() -> Self {
          59  +
        Self::new()
          60  +
    }
          61  +
}
          62  +
          63  +
/// Delineates a logical scope that has some beginning and end
          64  +
/// (e.g. a function or block of code).
          65  +
pub trait Scope {
          66  +
    /// invoke when the scope has ended.
          67  +
    fn end(&self);
          68  +
}
          69  +
          70  +
/// A cross cutting concern for carrying execution-scoped values across API
          71  +
/// boundaries (both in-process and distributed).
          72  +
pub trait Context {
          73  +
    /// Make this context the currently active context.
          74  +
    /// The returned handle is used to return the previous
          75  +
    /// context (if one existed) as active.
          76  +
    fn make_current(&self) -> &dyn Scope;
          77  +
}
          78  +
          79  +
/// Keeps track of the current [Context].
          80  +
pub trait ContextManager {
          81  +
    ///Get the currently active context.
          82  +
    fn current(&self) -> &dyn Context;
          83  +
}

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

@@ -0,1 +0,69 @@
           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  +
    /// An error setting the `GlobalTelemetryProvider``
          25  +
    SettingGlobalProvider,
          26  +
    /// Error flushing metrics pipeline
          27  +
    MetricsFlush,
          28  +
    /// Error gracefully shutting down Metrics Provider
          29  +
    MetricsShutdown,
          30  +
    /// A custom error that does not fall under any other error kind
          31  +
    Other,
          32  +
}
          33  +
          34  +
impl ObservabilityError {
          35  +
    /// Create a new [`ObservabilityError`] from an [ErrorKind] and a [BoxError]
          36  +
    pub fn new<E>(kind: ErrorKind, err: E) -> Self
          37  +
    where
          38  +
        E: Into<BoxError>,
          39  +
    {
          40  +
        Self {
          41  +
            kind,
          42  +
            source: err.into(),
          43  +
        }
          44  +
    }
          45  +
          46  +
    /// Returns the corresponding [`ErrorKind`] for this error.
          47  +
    pub fn kind(&self) -> &ErrorKind {
          48  +
        &self.kind
          49  +
    }
          50  +
}
          51  +
          52  +
impl fmt::Display for ObservabilityError {
          53  +
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
          54  +
        match &self.kind {
          55  +
            ErrorKind::Other => write!(f, "unclassified error"),
          56  +
            ErrorKind::SettingGlobalProvider => {
          57  +
                write!(f, "failed to set global telemetry provider")
          58  +
            }
          59  +
            ErrorKind::MetricsFlush => write!(f, "failed to flush metrics pipeline"),
          60  +
            ErrorKind::MetricsShutdown => write!(f, "failed to shutdown metrics provider"),
          61  +
        }
          62  +
    }
          63  +
}
          64  +
          65  +
impl std::error::Error for ObservabilityError {
          66  +
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
          67  +
        Some(self.source.as_ref())
          68  +
    }
          69  +
}

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

@@ -0,1 +0,82 @@
           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::provider::{GlobalTelemetryProvider, TelemetryProvider};
          15  +
          16  +
// Statically store the global provider
          17  +
static GLOBAL_TELEMETRY_PROVIDER: Lazy<RwLock<GlobalTelemetryProvider>> =
          18  +
    Lazy::new(|| RwLock::new(GlobalTelemetryProvider::new(TelemetryProvider::default())));
          19  +
          20  +
/// Set the current global [TelemetryProvider]. If [None] is supplied then a noop provider is set.
          21  +
/// The previous [TelemetryProvider] is returned in an [Arc] so appropriate cleanup can be done if necessary.
          22  +
pub fn set_global_telemetry_provider(
          23  +
    new_provider: Option<TelemetryProvider>,
          24  +
) -> Arc<TelemetryProvider> {
          25  +
    // TODO(smithyObservability): would probably be nicer to return a Result here, but the Guard held by the error from
          26  +
    // .try_write is not Send so I struggled to build an ObservabilityError from it
          27  +
    let mut old_provider = GLOBAL_TELEMETRY_PROVIDER
          28  +
        .try_write()
          29  +
        .expect("GLOBAL_TELEMETRY_PROVIDER RwLock Poisoned");
          30  +
          31  +
    let new_global_provider = if let Some(tp) = new_provider {
          32  +
        GlobalTelemetryProvider::new(tp)
          33  +
    } else {
          34  +
        GlobalTelemetryProvider::new(TelemetryProvider::default())
          35  +
    };
          36  +
          37  +
    mem::replace(&mut *old_provider, new_global_provider).telemetry_provider
          38  +
}
          39  +
          40  +
/// Get an [Arc] reference to the current global [TelemetryProvider].
          41  +
pub fn get_global_telemetry_provider() -> Arc<TelemetryProvider> {
          42  +
    // TODO(smithyObservability): would probably be nicer to return a Result here, but the Guard held by the error from
          43  +
    // .try_read is not Send so I struggled to build an ObservabilityError from it
          44  +
    GLOBAL_TELEMETRY_PROVIDER
          45  +
        .try_read()
          46  +
        .expect("GLOBAL_TELEMETRY_PROVIDER RwLock Poisoned")
          47  +
        .telemetry_provider()
          48  +
        .clone()
          49  +
}
          50  +
          51  +
#[cfg(test)]
          52  +
mod tests {
          53  +
    use super::*;
          54  +
    use crate::provider::TelemetryProvider;
          55  +
    use serial_test::serial;
          56  +
          57  +
    // Note: the tests in this module are run serially to prevent them from stepping on each other and poisoning the
          58  +
    // RwLock holding the GlobalTelemetryProvider
          59  +
    #[test]
          60  +
    #[serial]
          61  +
    fn can_set_global_telemetry_provider() {
          62  +
        let my_provider = TelemetryProvider::default();
          63  +
          64  +
        // Set the new counter and get a reference to the old one
          65  +
        let old_provider = set_global_telemetry_provider(Some(my_provider));
          66  +
          67  +
        // Call shutdown on the old meter provider
          68  +
        let _old_meter = old_provider.meter_provider().shutdown().unwrap();
          69  +
    }
          70  +
          71  +
    #[test]
          72  +
    #[serial]
          73  +
    fn can_get_global_telemetry_provider() {
          74  +
        let curr_provider = get_global_telemetry_provider();
          75  +
          76  +
        // Use the global provider to create an instrument and record a value with it
          77  +
        let curr_mp = curr_provider.meter_provider();
          78  +
        let curr_meter = curr_mp.get_meter("TestMeter", None);
          79  +
        let instrument = curr_meter.create_monotonic_counter("TestMonoCounter".into(), None, None);
          80  +
        instrument.add(4, None, None);
          81  +
    }
          82  +
}

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

@@ -0,1 +0,25 @@
           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  +
pub mod attributes;
          21  +
pub mod error;
          22  +
pub mod global;
          23  +
pub mod meter;
          24  +
mod noop;
          25  +
pub mod provider;

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

@@ -0,1 +0,118 @@
           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::attributes::{Attributes, Context};
          10  +
use crate::error::ObservabilityError;
          11  +
          12  +
/// Provides named instances of [Meter].
          13  +
pub trait MeterProvider {
          14  +
    /// Get or create a named [Meter].
          15  +
    fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Box<dyn Meter>;
          16  +
          17  +
    /// Optional method to flush the metrics pipeline, default is noop
          18  +
    fn flush(&self) -> Result<(), ObservabilityError> {
          19  +
        Ok(())
          20  +
    }
          21  +
          22  +
    /// Optional method to shutdown the metrics provider, default is noop
          23  +
    fn shutdown(&self) -> Result<(), ObservabilityError> {
          24  +
        Ok(())
          25  +
    }
          26  +
}
          27  +
          28  +
/// The entry point to creating instruments. A grouping of related metrics.
          29  +
pub trait Meter {
          30  +
    /// Create a new Gauge.
          31  +
    #[allow(clippy::type_complexity)]
          32  +
    fn create_gauge(
          33  +
        &self,
          34  +
        name: String,
          35  +
        callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = f64>) + Send + Sync>,
          36  +
        units: Option<String>,
          37  +
        description: Option<String>,
          38  +
    ) -> Box<dyn AsyncMeasurement<Value = f64>>;
          39  +
          40  +
    /// Create a new [UpDownCounter].
          41  +
    fn create_up_down_counter(
          42  +
        &self,
          43  +
        name: String,
          44  +
        units: Option<String>,
          45  +
        description: Option<String>,
          46  +
    ) -> Box<dyn UpDownCounter>;
          47  +
          48  +
    /// Create a new AsyncUpDownCounter.
          49  +
    #[allow(clippy::type_complexity)]
          50  +
    fn create_async_up_down_counter(
          51  +
        &self,
          52  +
        name: String,
          53  +
        callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = i64>) + Send + Sync>,
          54  +
        units: Option<String>,
          55  +
        description: Option<String>,
          56  +
    ) -> Box<dyn AsyncMeasurement<Value = i64>>;
          57  +
          58  +
    /// Create a new [MonotonicCounter].
          59  +
    fn create_monotonic_counter(
          60  +
        &self,
          61  +
        name: String,
          62  +
        units: Option<String>,
          63  +
        description: Option<String>,
          64  +
    ) -> Box<dyn MonotonicCounter>;
          65  +
          66  +
    /// Create a new AsyncMonotonicCounter.
          67  +
    #[allow(clippy::type_complexity)]
          68  +
    fn create_async_monotonic_counter(
          69  +
        &self,
          70  +
        name: String,
          71  +
        callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = u64>) + Send + Sync>,
          72  +
        units: Option<String>,
          73  +
        description: Option<String>,
          74  +
    ) -> Box<dyn AsyncMeasurement<Value = u64>>;
          75  +
          76  +
    /// Create a new [Histogram].
          77  +
    fn create_histogram(
          78  +
        &self,
          79  +
        name: String,
          80  +
        units: Option<String>,
          81  +
        description: Option<String>,
          82  +
    ) -> Box<dyn Histogram>;
          83  +
}
          84  +
          85  +
/// Collects a set of events with an event count and sum for all events.
          86  +
pub trait Histogram {
          87  +
    /// Record a value.
          88  +
    fn record(&self, value: f64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
          89  +
}
          90  +
          91  +
/// A counter that monotonically increases.
          92  +
pub trait MonotonicCounter {
          93  +
    /// Increment a counter by a fixed amount.
          94  +
    fn add(&self, value: u64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
          95  +
}
          96  +
          97  +
/// A counter that can increase or decrease.
          98  +
pub trait UpDownCounter {
          99  +
    /// Increment or decrement a counter by a fixed amount.
         100  +
    fn add(&self, value: i64, attributes: Option<&Attributes>, context: Option<&dyn Context>);
         101  +
}
         102  +
         103  +
/// A measurement that can be taken asynchronously.
         104  +
pub trait AsyncMeasurement {
         105  +
    /// The type recorded by the measurement.
         106  +
    type Value;
         107  +
         108  +
    /// Record a value
         109  +
    fn record(
         110  +
        &self,
         111  +
        value: Self::Value,
         112  +
        attributes: Option<&Attributes>,
         113  +
        context: Option<&dyn Context>,
         114  +
    );
         115  +
         116  +
    /// Stop recording , unregister callback.
         117  +
    fn stop(&self);
         118  +
}

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

@@ -0,1 +0,110 @@
           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  +
          10  +
use crate::{
          11  +
    attributes::{Attributes, Context},
          12  +
    meter::{AsyncMeasurement, Histogram, Meter, MeterProvider, MonotonicCounter, UpDownCounter},
          13  +
};
          14  +
          15  +
pub(crate) struct NoopMeterProvider;
          16  +
impl MeterProvider for NoopMeterProvider {
          17  +
    fn get_meter(&self, _scope: &'static str, _attributes: Option<&Attributes>) -> Box<dyn Meter> {
          18  +
        Box::new(NoopMeter)
          19  +
    }
          20  +
}
          21  +
          22  +
pub(crate) struct NoopMeter;
          23  +
impl Meter for NoopMeter {
          24  +
    fn create_gauge(
          25  +
        &self,
          26  +
        _name: String,
          27  +
        _callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = f64>) + Send + Sync>,
          28  +
        _units: Option<String>,
          29  +
        _description: Option<String>,
          30  +
    ) -> Box<dyn AsyncMeasurement<Value = f64>> {
          31  +
        Box::new(NoopAsyncMeasurement(PhantomData::<f64>))
          32  +
    }
          33  +
          34  +
    fn create_up_down_counter(
          35  +
        &self,
          36  +
        _name: String,
          37  +
        _units: Option<String>,
          38  +
        _description: Option<String>,
          39  +
    ) -> Box<dyn UpDownCounter> {
          40  +
        Box::new(NoopUpDownCounter)
          41  +
    }
          42  +
          43  +
    fn create_async_up_down_counter(
          44  +
        &self,
          45  +
        _name: String,
          46  +
        _callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = i64>) + Send + Sync>,
          47  +
        _units: Option<String>,
          48  +
        _description: Option<String>,
          49  +
    ) -> Box<dyn AsyncMeasurement<Value = i64>> {
          50  +
        Box::new(NoopAsyncMeasurement(PhantomData::<i64>))
          51  +
    }
          52  +
          53  +
    fn create_monotonic_counter(
          54  +
        &self,
          55  +
        _name: String,
          56  +
        _units: Option<String>,
          57  +
        _description: Option<String>,
          58  +
    ) -> Box<dyn MonotonicCounter> {
          59  +
        Box::new(NoopMonotonicCounter)
          60  +
    }
          61  +
          62  +
    fn create_async_monotonic_counter(
          63  +
        &self,
          64  +
        _name: String,
          65  +
        _callback: Box<dyn Fn(&dyn AsyncMeasurement<Value = u64>) + Send + Sync>,
          66  +
        _units: Option<String>,
          67  +
        _description: Option<String>,
          68  +
    ) -> Box<dyn AsyncMeasurement<Value = u64>> {
          69  +
        Box::new(NoopAsyncMeasurement(PhantomData::<u64>))
          70  +
    }
          71  +
          72  +
    fn create_histogram(
          73  +
        &self,
          74  +
        _name: String,
          75  +
        _units: Option<String>,
          76  +
        _description: Option<String>,
          77  +
    ) -> Box<dyn Histogram> {
          78  +
        Box::new(NoopHistogram)
          79  +
    }
          80  +
}
          81  +
          82  +
struct NoopAsyncMeasurement<T>(PhantomData<T>);
          83  +
impl<T> AsyncMeasurement for NoopAsyncMeasurement<T> {
          84  +
    type Value = T;
          85  +
          86  +
    fn record(&self, _value: T, _attributes: Option<&Attributes>, _context: Option<&dyn Context>) {}
          87  +
          88  +
    fn stop(&self) {}
          89  +
}
          90  +
          91  +
struct NoopUpDownCounter;
          92  +
impl UpDownCounter for NoopUpDownCounter {
          93  +
    fn add(&self, _value: i64, _attributes: Option<&Attributes>, _context: Option<&dyn Context>) {}
          94  +
}
          95  +
          96  +
struct NoopMonotonicCounter;
          97  +
impl MonotonicCounter for NoopMonotonicCounter {
          98  +
    fn add(&self, _value: u64, _attributes: Option<&Attributes>, _context: Option<&dyn Context>) {}
          99  +
}
         100  +
         101  +
struct NoopHistogram;
         102  +
impl Histogram for NoopHistogram {
         103  +
    fn record(
         104  +
        &self,
         105  +
        _value: f64,
         106  +
        _attributes: Option<&Attributes>,
         107  +
        _context: Option<&dyn Context>,
         108  +
    ) {
         109  +
    }
         110  +
}

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

@@ -0,1 +0,82 @@
           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::MeterProvider, noop::NoopMeterProvider};
          11  +
          12  +
/// A struct to hold the various types of telemetry providers.
          13  +
#[non_exhaustive]
          14  +
pub struct TelemetryProvider {
          15  +
    meter_provider: Box<dyn MeterProvider + Send + Sync>,
          16  +
}
          17  +
          18  +
impl TelemetryProvider {
          19  +
    /// Returns a builder struct for [TelemetryProvider]
          20  +
    pub fn builder() -> TelemetryProviderBuilder {
          21  +
        TelemetryProviderBuilder {
          22  +
            meter_provider: Box::new(NoopMeterProvider),
          23  +
        }
          24  +
    }
          25  +
          26  +
    /// Get the set [MeterProvider]
          27  +
    pub fn meter_provider(&self) -> &(dyn MeterProvider + Send + Sync) {
          28  +
        self.meter_provider.as_ref()
          29  +
    }
          30  +
}
          31  +
          32  +
impl Default for TelemetryProvider {
          33  +
    fn default() -> Self {
          34  +
        Self {
          35  +
            meter_provider: Box::new(NoopMeterProvider),
          36  +
        }
          37  +
    }
          38  +
}
          39  +
          40  +
// If we choose to expand our Telemetry provider and make Logging and Tracing
          41  +
// configurable at some point in the future we can do that by adding default
          42  +
// logger_provider and tracer_providers based on `tracing` to maintain backwards
          43  +
// compatibilty with what we have today.
          44  +
/// A builder for [TelemetryProvider].
          45  +
#[non_exhaustive]
          46  +
pub struct TelemetryProviderBuilder {
          47  +
    meter_provider: Box<dyn MeterProvider + Send + Sync>,
          48  +
}
          49  +
          50  +
impl TelemetryProviderBuilder {
          51  +
    /// Set the [MeterProvider].
          52  +
    pub fn meter_provider(mut self, meter_provider: Box<dyn MeterProvider + Send + Sync>) -> Self {
          53  +
        self.meter_provider = meter_provider;
          54  +
        self
          55  +
    }
          56  +
          57  +
    /// Build the [TelemetryProvider].
          58  +
    pub fn build(self) -> TelemetryProvider {
          59  +
        TelemetryProvider {
          60  +
            meter_provider: self.meter_provider,
          61  +
        }
          62  +
    }
          63  +
}
          64  +
          65  +
/// Wrapper type to hold a implementer of TelemetryProvider in an Arc so that
          66  +
/// it can be safely used across threads.
          67  +
#[non_exhaustive]
          68  +
pub(crate) struct GlobalTelemetryProvider {
          69  +
    pub(crate) telemetry_provider: Arc<TelemetryProvider>,
          70  +
}
          71  +
          72  +
impl GlobalTelemetryProvider {
          73  +
    pub(crate) fn new(telemetry_provider: TelemetryProvider) -> Self {
          74  +
        Self {
          75  +
            telemetry_provider: Arc::new(telemetry_provider),
          76  +
        }
          77  +
    }
          78  +
          79  +
    pub(crate) fn telemetry_provider(&self) -> &Arc<TelemetryProvider> {
          80  +
        &self.telemetry_provider
          81  +
    }
          82  +
}