ai_agent/analytics/
mod.rs1use std::sync::Arc;
2use std::sync::atomic::{AtomicU64, Ordering};
3
4#[derive(Debug, Clone)]
5pub enum AnalyticsEvent {
6 PageView {
7 path: String,
8 },
9 Action {
10 name: String,
11 metadata: Vec<(String, String)>,
12 },
13 Error {
14 message: String,
15 stack: Option<String>,
16 },
17 Performance {
18 metric: String,
19 value: f64,
20 },
21}
22
23#[derive(Debug, Default)]
24pub struct GleanTracker {
25 event_count: AtomicU64,
26 enabled: Arc<AtomicU64>,
27}
28
29impl GleanTracker {
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn track(&self, event: AnalyticsEvent) {
35 if self.is_enabled() {
36 self.event_count.fetch_add(1, Ordering::Relaxed);
37 self.send_event(event);
38 }
39 }
40
41 pub fn is_enabled(&self) -> bool {
42 self.enabled.load(Ordering::Relaxed) == 1
43 }
44
45 pub fn set_enabled(&self, enabled: bool) {
46 self.enabled
47 .store(if enabled { 1 } else { 0 }, Ordering::Relaxed);
48 }
49
50 pub fn event_count(&self) -> u64 {
51 self.event_count.load(Ordering::Relaxed)
52 }
53
54 fn send_event(&self, _event: AnalyticsEvent) {}
55}
56
57pub fn track_page_view(tracker: &GleanTracker, path: &str) {
58 tracker.track(AnalyticsEvent::PageView {
59 path: path.to_string(),
60 });
61}
62
63pub fn track_action(tracker: &GleanTracker, name: &str, metadata: Vec<(String, String)>) {
64 tracker.track(AnalyticsEvent::Action {
65 name: name.to_string(),
66 metadata,
67 });
68}
69
70pub fn track_error(tracker: &GleanTracker, message: &str, stack: Option<String>) {
71 tracker.track(AnalyticsEvent::Error {
72 message: message.to_string(),
73 stack,
74 });
75}
76
77pub fn track_performance(tracker: &GleanTracker, metric: &str, value: f64) {
78 tracker.track(AnalyticsEvent::Performance {
79 metric: metric.to_string(),
80 value,
81 });
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_tracker_disabled() {
90 let tracker = GleanTracker::new();
91 tracker.set_enabled(false);
92 tracker.track(AnalyticsEvent::PageView {
93 path: "/test".to_string(),
94 });
95 assert_eq!(tracker.event_count(), 0);
96 }
97
98 #[test]
99 fn test_tracker_enabled() {
100 let tracker = GleanTracker::new();
101 tracker.set_enabled(true);
102 track_page_view(&tracker, "/test");
103 assert_eq!(tracker.event_count(), 1);
104 }
105}