#[cfg(feature = "telemetry")]
use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
#[cfg(feature = "telemetry")]
pub struct OpTracer {
call_counts: dashmap::DashMap<String, AtomicU64>,
}
#[cfg(feature = "telemetry")]
impl OpTracer {
pub fn new() -> Self {
Self {
call_counts: dashmap::DashMap::new(),
}
}
pub fn trace(&self, op: &str, file: &str, line: u32) {
let key = format!("{}:{}:{}", file, line, op);
let count = self
.call_counts
.entry(key.clone())
.or_insert(AtomicU64::new(0));
let new_count = count.fetch_add(1, Ordering::SeqCst) + 1;
if new_count > 100 {
tracing::warn!(
"Operation {} called {} times - possible loop",
key,
new_count
);
}
}
}
#[cfg(feature = "telemetry")]
impl Default for OpTracer {
fn default() -> Self {
Self::new()
}
}
#[cfg(not(feature = "telemetry"))]
impl Default for OpTracer {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "telemetry")]
pub struct LoopGuard {
name: &'static str,
max_iterations: usize,
counter: AtomicUsize,
}
#[cfg(feature = "telemetry")]
impl LoopGuard {
pub fn new(name: &'static str, max_iterations: usize) -> Self {
Self {
name,
max_iterations,
counter: AtomicUsize::new(0),
}
}
pub fn check(&self) -> Result<(), String> {
let count = self.counter.fetch_add(1, Ordering::SeqCst);
if count >= self.max_iterations {
return Err(format!(
"LoopGuard '{}' exceeded max iterations: {}",
self.name, self.max_iterations
));
}
Ok(())
}
}
#[cfg(feature = "telemetry")]
impl Drop for LoopGuard {
fn drop(&mut self) {
let count = self.counter.load(Ordering::SeqCst);
if count > self.max_iterations / 2 {
tracing::info!("LoopGuard '{}' iterations: {}", self.name, count);
}
}
}
#[cfg(not(feature = "telemetry"))]
pub struct OpTracer;
#[cfg(not(feature = "telemetry"))]
impl OpTracer {
pub fn new() -> Self {
Self
}
pub fn trace(&self, _op: &str, _file: &str, _line: u32) {}
}
#[cfg(not(feature = "telemetry"))]
pub struct LoopGuard;
#[cfg(not(feature = "telemetry"))]
impl LoopGuard {
pub fn new(_name: &'static str, _max_iterations: usize) -> Self {
Self
}
pub fn check(&self) -> Result<(), String> {
Ok(())
}
}