attuned_core/telemetry/
setup.rs

1//! Telemetry setup and initialization.
2//!
3//! This module provides functions to initialize the observability stack.
4
5use super::{TracingConfig, TracingFormat};
6
7/// Guard that flushes telemetry on drop.
8pub struct TelemetryGuard {
9    _private: (),
10}
11
12impl Drop for TelemetryGuard {
13    fn drop(&mut self) {
14        // Flush any pending traces/metrics
15        tracing::info!("shutting down telemetry");
16    }
17}
18
19/// Initialize tracing with the given configuration.
20///
21/// Returns a guard that should be held for the lifetime of the application.
22/// When dropped, it will flush any pending telemetry data.
23///
24/// # Example
25///
26/// ```rust,ignore
27/// use attuned_core::telemetry::{init_tracing, TracingConfig};
28///
29/// fn main() {
30///     let _guard = init_tracing(TracingConfig::default());
31///     // Application code...
32/// }
33/// ```
34pub fn init_tracing(_config: TracingConfig) -> TelemetryGuard {
35    // Note: Full implementation requires tracing-subscriber
36    // This is a placeholder that works without additional dependencies
37    TelemetryGuard { _private: () }
38}
39
40/// Initialize tracing with environment-based configuration.
41///
42/// Reads configuration from environment variables:
43/// - `ATTUNED_LOG_FORMAT`: "pretty", "json", or "compact"
44/// - `ATTUNED_LOG_LEVEL`: e.g., "info", "debug", "trace"
45/// - `ATTUNED_SERVICE_NAME`: service name for tracing
46pub fn init_tracing_from_env() -> TelemetryGuard {
47    let format = std::env::var("ATTUNED_LOG_FORMAT")
48        .map(|s| match s.to_lowercase().as_str() {
49            "json" => TracingFormat::Json,
50            "compact" => TracingFormat::Compact,
51            _ => TracingFormat::Pretty,
52        })
53        .unwrap_or_default();
54
55    let level = std::env::var("ATTUNED_LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
56
57    let service_name =
58        std::env::var("ATTUNED_SERVICE_NAME").unwrap_or_else(|_| "attuned".to_string());
59
60    let config = TracingConfig {
61        format,
62        level,
63        service_name,
64        ..Default::default()
65    };
66
67    init_tracing(config)
68}
69
70/// Builder for configuring telemetry.
71#[derive(Default)]
72pub struct TelemetryBuilder {
73    tracing: Option<TracingConfig>,
74    #[allow(dead_code)]
75    otel: Option<super::OtelConfig>,
76    #[allow(dead_code)]
77    metrics_enabled: bool,
78}
79
80impl TelemetryBuilder {
81    /// Create a new telemetry builder.
82    pub fn new() -> Self {
83        Self::default()
84    }
85
86    /// Configure tracing.
87    pub fn with_tracing(mut self, config: TracingConfig) -> Self {
88        self.tracing = Some(config);
89        self
90    }
91
92    /// Configure OpenTelemetry export.
93    pub fn with_opentelemetry(mut self, config: super::OtelConfig) -> Self {
94        self.otel = Some(config);
95        self
96    }
97
98    /// Enable metrics collection.
99    pub fn with_metrics(mut self) -> Self {
100        self.metrics_enabled = true;
101        self
102    }
103
104    /// Initialize all configured telemetry.
105    pub fn init(self) -> TelemetryGuard {
106        let config = self.tracing.unwrap_or_default();
107        init_tracing(config)
108    }
109}