Skip to main content

oxideshield_guard/telemetry/
mod.rs

1//! OpenTelemetry Integration for OxideShield
2//!
3//! Provides metrics and tracing for guard operations, enabling production
4//! monitoring and observability.
5//!
6//! ## Features
7//!
8//! - **Metrics**: Counter, histogram, and gauge metrics for guard operations
9//! - **Tracing**: Distributed tracing integration via tracing crate
10//! - **OTLP Export**: Export to OpenTelemetry collectors
11//!
12//! ## Metrics Exposed
13//!
14//! | Metric | Type | Description |
15//! |--------|------|-------------|
16//! | `oxideshield.guard.checks_total` | Counter | Total guard checks |
17//! | `oxideshield.guard.blocks_total` | Counter | Total blocked requests |
18//! | `oxideshield.guard.latency_ms` | Histogram | Guard check latency |
19//! | `oxideshield.guard.active_checks` | Gauge | Currently running checks |
20//!
21//! ## Example
22//!
23//! ```rust,ignore
24//! use oxideshield_guard::telemetry::{TelemetryConfig, init_telemetry};
25//!
26//! // Initialize telemetry
27//! let config = TelemetryConfig::default();
28//! init_telemetry(&config)?;
29//!
30//! // Guards will now emit metrics automatically
31//! let guard = PIIGuard::new("pii").with_telemetry(true);
32//! ```
33
34pub mod metrics;
35#[cfg(feature = "telemetry")]
36mod otel;
37pub mod recorder;
38
39// Re-export OpenTelemetry types when feature is enabled
40#[cfg(feature = "telemetry")]
41pub use otel::{init_telemetry, shutdown_telemetry, OtelGuardMetrics, TelemetryConfig};
42
43// Stub implementations when telemetry feature is disabled
44#[cfg(not(feature = "telemetry"))]
45mod stubs {
46    /// Stub telemetry config
47    #[derive(Debug, Clone)]
48    pub struct TelemetryConfig {
49        pub service_name: String,
50    }
51
52    impl Default for TelemetryConfig {
53        fn default() -> Self {
54            Self {
55                service_name: "oxideshield".to_string(),
56            }
57        }
58    }
59
60    impl TelemetryConfig {
61        pub fn local() -> Self {
62            Self::default()
63        }
64
65        pub fn production(_endpoint: impl Into<String>) -> Self {
66            Self::default()
67        }
68
69        pub fn with_service_name(mut self, name: impl Into<String>) -> Self {
70            self.service_name = name.into();
71            self
72        }
73
74        pub fn with_otlp_endpoint(self, _endpoint: impl Into<String>) -> Self {
75            self
76        }
77    }
78
79    /// Stub metrics
80    #[derive(Debug, Default)]
81    pub struct OtelGuardMetrics;
82
83    impl OtelGuardMetrics {
84        pub fn new() -> Self {
85            Self
86        }
87
88        pub fn record_check(
89            &self,
90            _guard_name: &str,
91            _guard_type: &str,
92            _passed: bool,
93            _latency_ms: f64,
94        ) {
95            // No-op
96        }
97    }
98
99    /// Stub init
100    pub fn init_telemetry(
101        _config: &TelemetryConfig,
102    ) -> Result<OtelGuardMetrics, Box<dyn std::error::Error + Send + Sync>> {
103        Ok(OtelGuardMetrics::new())
104    }
105
106    /// Stub shutdown
107    pub fn shutdown_telemetry() {
108        // No-op
109    }
110}
111
112#[cfg(not(feature = "telemetry"))]
113pub use stubs::{init_telemetry, shutdown_telemetry, OtelGuardMetrics, TelemetryConfig};
114
115// Always export metrics and recorder
116pub use metrics::*;
117pub use recorder::*;