metry 0.1.1

All-in-one telemetry framework, based on tracing crate.
Documentation
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_sdk::logs::{Config, LoggerProvider};
use opentelemetry_stdout::LogExporter;
use tracing_core::Subscriber;
use tracing_subscriber::{registry::LookupSpan, Layer};

use crate::layers::TelemetryLayerBuilder;

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

impl LogOptions {
    pub fn with_log_config(config: Config) -> Self {
        LogOptions {
            config: Some(config),
        }
    }
}

#[derive(Debug)]
pub enum LayerBuilder {
    /// Logs layer emitting to stdout.
    Stdout(LogOptions),
    /// Logs layer emitting to stderr.
    Stderr(LogOptions),
}

impl TelemetryLayerBuilder for LayerBuilder {
    async fn layer<S>(self) -> Result<Box<dyn Layer<S> + Send + Sync + 'static>, String>
    where
        S: Subscriber,
        for<'a> S: LookupSpan<'a>,
    {
        // Configure the writer based on the desired log target:
        let (logger_exporter, config) = match self {
            LayerBuilder::Stdout(LogOptions { config }) => (LogExporter::builder().build(), config),
            LayerBuilder::Stderr(LogOptions { config }) => (
                LogExporter::builder()
                    .with_writer(std::io::stderr())
                    .build(),
                config,
            ),
        };
        let logger_provider = LoggerProvider::builder()
            .with_config(config.unwrap_or_default())
            .with_simple_exporter(logger_exporter)
            .build();
        let logs_layer = OpenTelemetryTracingBridge::new(&logger_provider);
        Ok(Box::new(logs_layer))
    }
}