metry 0.1.1

All-in-one telemetry framework, based on tracing crate.
Documentation
use opentelemetry::{global, trace::TracerProvider as _};
use opentelemetry_sdk::trace::Config;
use opentelemetry_sdk::{runtime, trace::TracerProvider};
use tracing_core::Subscriber;
use tracing_subscriber::{registry::LookupSpan, Layer};

use super::exporters::XrayExporterBuilder;

use crate::layers::TelemetryLayerBuilder;

/// Configuration options for a trace [LayerBuilder].
#[derive(Debug, Default)]
pub struct TraceOptions {
    config: Option<Config>,
}

impl TraceOptions {
    pub fn with_trace_config(config: Config) -> Self {
        TraceOptions {
            config: Some(config),
        }
    }
}

#[derive(Debug)]
pub enum LayerBuilder {
    /// Trace layer emitting to stdout.
    Stdout(TraceOptions),
    /// Trace layer emitting to AWS XRay.
    Xray(TraceOptions),
}

impl TelemetryLayerBuilder for LayerBuilder {
    async fn layer<S>(self) -> Result<Box<dyn Layer<S> + Send + Sync + 'static>, String>
    where
        S: Subscriber + Send + Sync,
        for<'a> S: LookupSpan<'a>,
    {
        let provider = match self {
            LayerBuilder::Stdout(TraceOptions { config }) => {
                let exporter = opentelemetry_stdout::SpanExporter::default();
                let provider = TracerProvider::builder()
                    .with_config(config.unwrap_or_default())
                    .with_batch_exporter(exporter, runtime::Tokio)
                    .build();
                Ok(provider)
            }
            LayerBuilder::Xray(TraceOptions { config }) => {
                XrayExporterBuilder::with_default_config()
                    .await
                    .build_span_exporter()
                    .map(|exporter| {
                        TracerProvider::builder()
                            .with_config(config.unwrap_or_default())
                            .with_batch_exporter(exporter, runtime::Tokio)
                            .build()
                    })
                    .map_err(|error| error.to_string())
            }
        }?;

        let tracer = provider.tracer("metry-tracer");
        let _ = global::set_tracer_provider(provider);
        let trace_layer = tracing_opentelemetry::layer().with_tracer(tracer);
        Ok(Box::new(trace_layer))
    }
}