Skip to main content

torsh_hub/
analytics.rs

1//! Model analytics and usage tracking system
2//!
3//! This module provides comprehensive analytics for model usage, performance,
4//! and behavior tracking including:
5//! - Real-time model usage metrics
6//! - Performance profiling and benchmarking  
7//! - User interaction analytics
8//! - Model popularity and recommendation analytics
9//! - A/B testing framework for model comparison
10
11// Framework infrastructure - components designed for future use
12#![allow(dead_code)]
13use chrono::Timelike;
14use clap::ValueEnum;
15use serde::{Deserialize, Serialize};
16use std::collections::HashMap;
17use std::path::PathBuf;
18use std::time::{Duration, SystemTime, UNIX_EPOCH};
19use torsh_core::error::{Result, TorshError};
20
21/// Comprehensive analytics manager
22pub struct AnalyticsManager {
23    usage_tracker: UsageTracker,
24    performance_profiler: PerformanceProfiler,
25    user_analytics: UserAnalytics,
26    ab_testing: ABTestingFramework,
27    recommendation_engine: RecommendationEngine,
28    storage_path: PathBuf,
29}
30
31/// Tracks model usage patterns and statistics
32pub struct UsageTracker {
33    model_usage: HashMap<String, ModelUsageStats>,
34    session_data: Vec<SessionData>,
35    real_time_metrics: RealTimeMetrics,
36}
37
38/// Performance profiling for models
39pub struct PerformanceProfiler {
40    profiling_data: HashMap<String, ModelPerformanceData>,
41    benchmark_results: Vec<BenchmarkResult>,
42    system_metrics: SystemMetrics,
43}
44
45/// User behavior and interaction analytics
46pub struct UserAnalytics {
47    user_sessions: HashMap<String, Vec<UserSession>>,
48    interaction_patterns: InteractionPatterns,
49    user_preferences: HashMap<String, UserPreferences>,
50}
51
52/// A/B testing framework for model comparison
53pub struct ABTestingFramework {
54    active_tests: HashMap<String, ABTest>,
55    test_results: HashMap<String, ABTestResult>,
56    test_configurations: HashMap<String, ABTestConfig>,
57}
58
59/// Recommendation engine for suggesting models
60pub struct RecommendationEngine {
61    model_similarities: HashMap<String, Vec<ModelSimilarity>>,
62    user_model_matrix: HashMap<String, HashMap<String, f32>>,
63    trending_models: Vec<TrendingModel>,
64}
65
66/// Model usage statistics
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct ModelUsageStats {
69    pub model_id: String,
70    pub total_loads: u64,
71    pub total_inferences: u64,
72    pub total_runtime: Duration,
73    pub average_inference_time: Duration,
74    pub memory_usage: MemoryUsage,
75    pub error_rate: f32,
76    pub last_used: SystemTime,
77    pub popularity_score: f32,
78    pub daily_usage: HashMap<String, u64>, // Date -> usage count
79    pub hourly_patterns: [u64; 24],        // Usage by hour of day
80}
81
82/// Real-time metrics dashboard data
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct RealTimeMetrics {
85    pub active_models: u32,
86    pub total_active_sessions: u32,
87    pub current_memory_usage: u64,
88    pub current_cpu_usage: f32,
89    pub requests_per_second: f32,
90    pub average_response_time: Duration,
91    pub error_rate_last_minute: f32,
92    pub timestamp: SystemTime,
93}
94
95/// Session tracking data
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct SessionData {
98    pub session_id: String,
99    pub user_id: Option<String>,
100    pub start_time: SystemTime,
101    pub end_time: Option<SystemTime>,
102    pub models_used: Vec<String>,
103    pub total_inferences: u32,
104    pub errors_encountered: u32,
105    pub user_agent: Option<String>,
106    pub ip_address: Option<String>,
107}
108
109/// Memory usage tracking
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct MemoryUsage {
112    pub peak_memory: u64,
113    pub average_memory: u64,
114    pub memory_efficiency: f32,
115    pub gc_pressure: f32,
116}
117
118/// Performance profiling data
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct ModelPerformanceData {
121    pub model_id: String,
122    pub inference_times: Vec<Duration>,
123    pub throughput_data: Vec<ThroughputMeasurement>,
124    pub resource_utilization: ResourceUtilization,
125    pub bottlenecks: Vec<PerformanceBottleneck>,
126    pub optimization_suggestions: Vec<OptimizationSuggestion>,
127}
128
129/// Throughput measurement
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct ThroughputMeasurement {
132    pub timestamp: SystemTime,
133    pub requests_per_second: f32,
134    pub batch_size: u32,
135    pub concurrent_requests: u32,
136}
137
138/// Resource utilization metrics
139#[derive(Debug, Clone, Serialize, Deserialize, Default)]
140pub struct ResourceUtilization {
141    pub cpu_usage: Vec<f32>,
142    pub memory_usage: Vec<u64>,
143    pub gpu_usage: Option<Vec<f32>>,
144    pub io_usage: IOMetrics,
145    pub network_usage: NetworkMetrics,
146}
147
148/// Performance bottleneck identification
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct PerformanceBottleneck {
151    pub bottleneck_type: BottleneckType,
152    pub severity: BottleneckSeverity,
153    pub description: String,
154    pub impact_percentage: f32,
155    pub suggestions: Vec<String>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
159pub enum BottleneckType {
160    CPU,
161    Memory,
162    IO,
163    Network,
164    ModelComputation,
165    DataLoading,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize)]
169pub enum BottleneckSeverity {
170    Low,
171    Medium,
172    High,
173    Critical,
174}
175
176/// Optimization suggestions
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct OptimizationSuggestion {
179    pub suggestion_type: OptimizationType,
180    pub description: String,
181    pub expected_improvement: f32,
182    pub implementation_difficulty: DifficultyLevel,
183    pub estimated_cost: EstimatedCost,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub enum OptimizationType {
188    ModelQuantization,
189    BatchSizeOptimization,
190    CachingStrategy,
191    HardwareUpgrade,
192    AlgorithmicOptimization,
193    DataPipeline,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
197pub enum DifficultyLevel {
198    Easy,
199    Medium,
200    Hard,
201    Expert,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
205pub enum EstimatedCost {
206    Free,
207    Low,
208    Medium,
209    High,
210}
211
212/// System-wide metrics
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct SystemMetrics {
215    pub cpu_info: CPUInfo,
216    pub memory_info: MemoryInfo,
217    pub disk_info: DiskInfo,
218    pub network_info: NetworkInfo,
219    pub gpu_info: Option<GPUInfo>,
220}
221
222/// Benchmark result
223#[derive(Debug, Clone, Serialize, Deserialize)]
224pub struct BenchmarkResult {
225    pub model_id: String,
226    pub benchmark_type: BenchmarkType,
227    pub score: f32,
228    pub details: HashMap<String, f32>,
229    pub timestamp: SystemTime,
230    pub environment: BenchmarkEnvironment,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub enum BenchmarkType {
235    Latency,
236    Throughput,
237    Accuracy,
238    MemoryEfficiency,
239    EnergyEfficiency,
240}
241
242/// User session data
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct UserSession {
245    pub session_id: String,
246    pub start_time: SystemTime,
247    pub duration: Duration,
248    pub actions: Vec<UserAction>,
249    pub models_accessed: Vec<String>,
250    pub success_rate: f32,
251}
252
253/// User action tracking
254#[derive(Debug, Clone, Serialize, Deserialize)]
255pub struct UserAction {
256    pub action_type: ActionType,
257    pub timestamp: SystemTime,
258    pub model_id: Option<String>,
259    pub parameters: HashMap<String, String>,
260    pub success: bool,
261    pub error_message: Option<String>,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize)]
265pub enum ActionType {
266    ModelLoad,
267    ModelInference,
268    ModelDownload,
269    ModelSearch,
270    ModelRate,
271    ModelShare,
272    ProfileView,
273    SettingsChange,
274}
275
276/// User interaction patterns
277#[derive(Debug, Clone, Serialize, Deserialize, Default)]
278pub struct InteractionPatterns {
279    pub most_popular_models: Vec<String>,
280    pub common_workflows: Vec<Workflow>,
281    pub usage_patterns_by_time: HashMap<String, Vec<u32>>,
282    pub model_transition_matrix: HashMap<String, HashMap<String, f32>>,
283}
284
285/// Workflow pattern
286#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct Workflow {
288    pub name: String,
289    pub steps: Vec<WorkflowStep>,
290    pub frequency: u32,
291    pub success_rate: f32,
292}
293
294#[derive(Debug, Clone, Serialize, Deserialize)]
295pub struct WorkflowStep {
296    pub action: ActionType,
297    pub model_category: Option<String>,
298    pub typical_duration: Duration,
299}
300
301/// User preferences
302#[derive(Debug, Clone, Serialize, Deserialize)]
303pub struct UserPreferences {
304    pub preferred_model_types: Vec<String>,
305    pub performance_vs_accuracy_preference: f32, // 0.0 = performance, 1.0 = accuracy
306    pub preferred_model_size: ModelSizePreference,
307    pub usage_patterns: HashMap<String, f32>,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
311pub enum ModelSizePreference {
312    Small,
313    Medium,
314    Large,
315    Any,
316}
317
318/// A/B Test configuration
319#[derive(Debug, Clone, Serialize, Deserialize)]
320pub struct ABTestConfig {
321    pub test_name: String,
322    pub description: String,
323    pub models_to_test: Vec<String>,
324    pub traffic_split: HashMap<String, f32>,
325    pub success_metrics: Vec<String>,
326    pub min_sample_size: u32,
327    pub max_duration: Duration,
328    pub confidence_level: f32,
329}
330
331/// A/B Test state
332#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct ABTest {
334    pub config: ABTestConfig,
335    pub start_time: SystemTime,
336    pub current_assignments: HashMap<String, String>, // user_id -> model_id
337    pub metrics: HashMap<String, ABTestMetrics>,
338    pub status: ABTestStatus,
339}
340
341#[derive(Debug, Clone, Serialize, Deserialize)]
342pub enum ABTestStatus {
343    Running,
344    Completed,
345    Stopped,
346    Failed,
347}
348
349/// A/B Test metrics
350#[derive(Debug, Clone, Serialize, Deserialize)]
351pub struct ABTestMetrics {
352    pub model_id: String,
353    pub sample_size: u32,
354    pub conversion_rate: f32,
355    pub average_satisfaction: f32,
356    pub error_rate: f32,
357    pub performance_metrics: HashMap<String, f32>,
358}
359
360/// A/B Test result
361#[derive(Debug, Clone, Serialize, Deserialize)]
362pub struct ABTestResult {
363    pub test_name: String,
364    pub winner: Option<String>,
365    pub confidence: f32,
366    pub effect_size: f32,
367    pub p_value: f32,
368    pub metrics_comparison: HashMap<String, ABTestMetrics>,
369    pub recommendation: String,
370}
371
372/// Model similarity for recommendations
373#[derive(Debug, Clone, Serialize, Deserialize)]
374pub struct ModelSimilarity {
375    pub model_id: String,
376    pub similarity_score: f32,
377    pub similarity_type: SimilarityType,
378}
379
380#[derive(Debug, Clone, Serialize, Deserialize)]
381pub enum SimilarityType {
382    ContentBased,  // Based on model characteristics
383    Collaborative, // Based on user behavior
384    Hybrid,        // Combination of both
385}
386
387/// Trending model data
388#[derive(Debug, Clone, Serialize, Deserialize)]
389pub struct TrendingModel {
390    pub model_id: String,
391    pub trend_score: f32,
392    pub growth_rate: f32,
393    pub velocity: f32, // Rate of change in popularity
394    pub reasons: Vec<TrendReason>,
395}
396
397#[derive(Debug, Clone, Serialize, Deserialize)]
398pub enum TrendReason {
399    HighAccuracy,
400    FastInference,
401    RecentRelease,
402    CommunityRecommendation,
403    MediaCoverage,
404    ResearchBreakthrough,
405}
406
407/// Various info structs
408#[derive(Debug, Clone, Serialize, Deserialize)]
409pub struct CPUInfo {
410    pub cores: u32,
411    pub threads: u32,
412    pub model: String,
413    pub frequency: f32,
414}
415
416#[derive(Debug, Clone, Serialize, Deserialize)]
417pub struct MemoryInfo {
418    pub total: u64,
419    pub available: u64,
420    pub used: u64,
421}
422
423#[derive(Debug, Clone, Serialize, Deserialize)]
424pub struct DiskInfo {
425    pub total: u64,
426    pub available: u64,
427    pub read_speed: f32,
428    pub write_speed: f32,
429}
430
431#[derive(Debug, Clone, Serialize, Deserialize)]
432pub struct NetworkInfo {
433    pub bandwidth: f32,
434    pub latency: Duration,
435}
436
437#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct GPUInfo {
439    pub model: String,
440    pub memory: u64,
441    pub compute_capability: String,
442}
443
444#[derive(Debug, Clone, Serialize, Deserialize)]
445pub struct IOMetrics {
446    pub read_bytes_per_sec: f32,
447    pub write_bytes_per_sec: f32,
448    pub read_ops_per_sec: f32,
449    pub write_ops_per_sec: f32,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
453pub struct NetworkMetrics {
454    pub bytes_sent_per_sec: f32,
455    pub bytes_received_per_sec: f32,
456    pub packets_sent_per_sec: f32,
457    pub packets_received_per_sec: f32,
458}
459
460#[derive(Debug, Clone, Serialize, Deserialize)]
461pub struct BenchmarkEnvironment {
462    pub hardware: SystemMetrics,
463    pub software_versions: HashMap<String, String>,
464    pub configuration: HashMap<String, String>,
465}
466
467impl AnalyticsManager {
468    /// Create a new analytics manager
469    pub fn new(storage_path: PathBuf) -> Result<Self> {
470        std::fs::create_dir_all(&storage_path).map_err(|e| TorshError::IoError(e.to_string()))?;
471
472        Ok(Self {
473            usage_tracker: UsageTracker::new(),
474            performance_profiler: PerformanceProfiler::new(),
475            user_analytics: UserAnalytics::new(),
476            ab_testing: ABTestingFramework::new(),
477            recommendation_engine: RecommendationEngine::new(),
478            storage_path,
479        })
480    }
481
482    /// Track model usage
483    pub fn track_model_usage(&mut self, model_id: &str, inference_time: Duration) -> Result<()> {
484        self.usage_tracker.track_usage(model_id, inference_time)
485    }
486
487    /// Start performance profiling for a model
488    pub fn start_profiling(&mut self, model_id: &str) -> Result<String> {
489        self.performance_profiler.start_profiling(model_id)
490    }
491
492    /// Stop performance profiling
493    pub fn stop_profiling(&mut self, profile_id: &str) -> Result<ModelPerformanceData> {
494        self.performance_profiler.stop_profiling(profile_id)
495    }
496
497    /// Record user action
498    pub fn record_user_action(&mut self, user_id: &str, action: UserAction) -> Result<()> {
499        self.user_analytics.record_action(user_id, action)
500    }
501
502    /// Start an A/B test
503    pub fn start_ab_test(&mut self, config: ABTestConfig) -> Result<String> {
504        self.ab_testing.start_test(config)
505    }
506
507    /// Get model recommendations for a user
508    pub fn get_recommendations(&self, user_id: &str, count: usize) -> Result<Vec<String>> {
509        self.recommendation_engine
510            .get_recommendations(user_id, count)
511    }
512
513    /// Get real-time metrics
514    pub fn get_real_time_metrics(&self) -> RealTimeMetrics {
515        self.usage_tracker.get_real_time_metrics()
516    }
517
518    /// Generate analytics report
519    pub fn generate_report(&self, model_id: Option<&str>) -> Result<AnalyticsReport> {
520        let usage_stats = if let Some(id) = model_id {
521            self.usage_tracker.get_model_stats(id).cloned()
522        } else {
523            None
524        };
525
526        let performance_data = if let Some(id) = model_id {
527            self.performance_profiler.get_performance_data(id).cloned()
528        } else {
529            None
530        };
531
532        Ok(AnalyticsReport {
533            timestamp: SystemTime::now(),
534            model_id: model_id.map(String::from),
535            usage_stats,
536            performance_data,
537            real_time_metrics: self.get_real_time_metrics(),
538            trending_models: self.recommendation_engine.get_trending_models(10),
539            system_health: self.get_system_health(),
540        })
541    }
542
543    /// Export analytics data
544    pub fn export_data(
545        &self,
546        format: ExportFormat,
547        start_date: SystemTime,
548        end_date: SystemTime,
549    ) -> Result<String> {
550        let data = self.collect_data_for_period(start_date, end_date)?;
551
552        match format {
553            ExportFormat::JSON => Ok(serde_json::to_string_pretty(&data)?),
554            ExportFormat::CSV => self.export_to_csv(&data),
555            ExportFormat::Excel => self.export_to_excel(&data),
556        }
557    }
558
559    /// Get system health status
560    fn get_system_health(&self) -> SystemHealth {
561        SystemHealth {
562            overall_status: HealthStatus::Healthy,
563            cpu_health: HealthStatus::Healthy,
564            memory_health: HealthStatus::Healthy,
565            disk_health: HealthStatus::Healthy,
566            network_health: HealthStatus::Healthy,
567            alerts: vec![],
568            recommendations: vec![],
569        }
570    }
571
572    fn collect_data_for_period(
573        &self,
574        _start: SystemTime,
575        _end: SystemTime,
576    ) -> Result<AnalyticsExportData> {
577        // Implementation would collect all relevant data for the period
578        Ok(AnalyticsExportData {
579            usage_data: HashMap::new(),
580            performance_data: HashMap::new(),
581            user_data: HashMap::new(),
582            ab_test_data: HashMap::new(),
583        })
584    }
585
586    fn export_to_csv(&self, _data: &AnalyticsExportData) -> Result<String> {
587        // Implementation would convert data to CSV format
588        Ok("CSV data here".to_string())
589    }
590
591    fn export_to_excel(&self, _data: &AnalyticsExportData) -> Result<String> {
592        // Implementation would convert data to Excel format
593        Ok("Excel data here".to_string())
594    }
595}
596
597impl UsageTracker {
598    fn new() -> Self {
599        Self {
600            model_usage: HashMap::new(),
601            session_data: Vec::new(),
602            real_time_metrics: RealTimeMetrics::default(),
603        }
604    }
605
606    fn track_usage(&mut self, model_id: &str, inference_time: Duration) -> Result<()> {
607        let stats = self
608            .model_usage
609            .entry(model_id.to_string())
610            .or_insert_with(|| ModelUsageStats {
611                model_id: model_id.to_string(),
612                total_loads: 0,
613                total_inferences: 0,
614                total_runtime: Duration::from_secs(0),
615                average_inference_time: Duration::from_secs(0),
616                memory_usage: MemoryUsage::default(),
617                error_rate: 0.0,
618                last_used: SystemTime::now(),
619                popularity_score: 0.0,
620                daily_usage: HashMap::new(),
621                hourly_patterns: [0; 24],
622            });
623
624        stats.total_inferences += 1;
625        stats.total_runtime += inference_time;
626        stats.average_inference_time = stats.total_runtime / stats.total_inferences as u32;
627        stats.last_used = SystemTime::now();
628
629        // Update daily usage
630        let today = chrono::Utc::now().format("%Y-%m-%d").to_string();
631        *stats.daily_usage.entry(today).or_insert(0) += 1;
632
633        // Update hourly patterns
634        let hour = chrono::Utc::now().hour() as usize;
635        stats.hourly_patterns[hour] += 1;
636
637        Ok(())
638    }
639
640    fn get_model_stats(&self, model_id: &str) -> Option<&ModelUsageStats> {
641        self.model_usage.get(model_id)
642    }
643
644    fn get_real_time_metrics(&self) -> RealTimeMetrics {
645        self.real_time_metrics.clone()
646    }
647}
648
649impl PerformanceProfiler {
650    fn new() -> Self {
651        Self {
652            profiling_data: HashMap::new(),
653            benchmark_results: Vec::new(),
654            system_metrics: SystemMetrics::default(),
655        }
656    }
657
658    fn start_profiling(&mut self, model_id: &str) -> Result<String> {
659        let profile_id = format!(
660            "{}_{}",
661            model_id,
662            SystemTime::now()
663                .duration_since(UNIX_EPOCH)
664                .expect("system time should be after UNIX epoch")
665                .as_secs()
666        );
667        // Implementation would start actual profiling
668        Ok(profile_id)
669    }
670
671    fn stop_profiling(&mut self, _profile_id: &str) -> Result<ModelPerformanceData> {
672        // Implementation would stop profiling and return data
673        Ok(ModelPerformanceData {
674            model_id: "test".to_string(),
675            inference_times: vec![],
676            throughput_data: vec![],
677            resource_utilization: ResourceUtilization::default(),
678            bottlenecks: vec![],
679            optimization_suggestions: vec![],
680        })
681    }
682
683    fn get_performance_data(&self, model_id: &str) -> Option<&ModelPerformanceData> {
684        self.profiling_data.get(model_id)
685    }
686}
687
688impl UserAnalytics {
689    fn new() -> Self {
690        Self {
691            user_sessions: HashMap::new(),
692            interaction_patterns: InteractionPatterns::default(),
693            user_preferences: HashMap::new(),
694        }
695    }
696
697    fn record_action(&mut self, user_id: &str, action: UserAction) -> Result<()> {
698        let _sessions = self.user_sessions.entry(user_id.to_string()).or_default();
699
700        // Implementation would record the action and update analytics
701        println!(
702            "Recording action for user {}: {:?}",
703            user_id, action.action_type
704        );
705
706        Ok(())
707    }
708}
709
710impl ABTestingFramework {
711    fn new() -> Self {
712        Self {
713            active_tests: HashMap::new(),
714            test_results: HashMap::new(),
715            test_configurations: HashMap::new(),
716        }
717    }
718
719    fn start_test(&mut self, config: ABTestConfig) -> Result<String> {
720        let test_id = format!(
721            "test_{}",
722            SystemTime::now()
723                .duration_since(UNIX_EPOCH)
724                .expect("system time should be after UNIX epoch")
725                .as_secs()
726        );
727
728        let test = ABTest {
729            config: config.clone(),
730            start_time: SystemTime::now(),
731            current_assignments: HashMap::new(),
732            metrics: HashMap::new(),
733            status: ABTestStatus::Running,
734        };
735
736        self.active_tests.insert(test_id.clone(), test);
737        self.test_configurations.insert(test_id.clone(), config);
738
739        Ok(test_id)
740    }
741}
742
743impl RecommendationEngine {
744    fn new() -> Self {
745        Self {
746            model_similarities: HashMap::new(),
747            user_model_matrix: HashMap::new(),
748            trending_models: Vec::new(),
749        }
750    }
751
752    fn get_recommendations(&self, _user_id: &str, count: usize) -> Result<Vec<String>> {
753        // Implementation would generate personalized recommendations
754        Ok(self
755            .trending_models
756            .iter()
757            .take(count)
758            .map(|m| m.model_id.clone())
759            .collect())
760    }
761
762    fn get_trending_models(&self, count: usize) -> Vec<TrendingModel> {
763        self.trending_models.iter().take(count).cloned().collect()
764    }
765}
766
767/// Analytics report structure
768#[derive(Debug, Clone, Serialize, Deserialize)]
769pub struct AnalyticsReport {
770    pub timestamp: SystemTime,
771    pub model_id: Option<String>,
772    pub usage_stats: Option<ModelUsageStats>,
773    pub performance_data: Option<ModelPerformanceData>,
774    pub real_time_metrics: RealTimeMetrics,
775    pub trending_models: Vec<TrendingModel>,
776    pub system_health: SystemHealth,
777}
778
779/// System health monitoring
780#[derive(Debug, Clone, Serialize, Deserialize)]
781pub struct SystemHealth {
782    pub overall_status: HealthStatus,
783    pub cpu_health: HealthStatus,
784    pub memory_health: HealthStatus,
785    pub disk_health: HealthStatus,
786    pub network_health: HealthStatus,
787    pub alerts: Vec<HealthAlert>,
788    pub recommendations: Vec<String>,
789}
790
791#[derive(Debug, Clone, Serialize, Deserialize)]
792pub enum HealthStatus {
793    Healthy,
794    Warning,
795    Critical,
796    Unknown,
797}
798
799#[derive(Debug, Clone, Serialize, Deserialize)]
800pub struct HealthAlert {
801    pub alert_type: AlertType,
802    pub severity: AlertSeverity,
803    pub message: String,
804    pub timestamp: SystemTime,
805}
806
807#[derive(Debug, Clone, Serialize, Deserialize)]
808pub enum AlertType {
809    HighCPUUsage,
810    LowMemory,
811    DiskSpaceLow,
812    NetworkLatency,
813    ModelError,
814    SystemError,
815}
816
817#[derive(Debug, Clone, Serialize, Deserialize)]
818pub enum AlertSeverity {
819    Info,
820    Warning,
821    Error,
822    Critical,
823}
824
825/// Export format options
826#[derive(Debug, Clone, ValueEnum)]
827pub enum ExportFormat {
828    JSON,
829    CSV,
830    Excel,
831}
832
833/// Data structure for exports
834#[derive(Debug, Clone, Serialize, Deserialize)]
835pub struct AnalyticsExportData {
836    pub usage_data: HashMap<String, ModelUsageStats>,
837    pub performance_data: HashMap<String, ModelPerformanceData>,
838    pub user_data: HashMap<String, Vec<UserSession>>,
839    pub ab_test_data: HashMap<String, ABTestResult>,
840}
841
842// Default implementations
843impl Default for RealTimeMetrics {
844    fn default() -> Self {
845        Self {
846            active_models: 0,
847            total_active_sessions: 0,
848            current_memory_usage: 0,
849            current_cpu_usage: 0.0,
850            requests_per_second: 0.0,
851            average_response_time: Duration::from_millis(0),
852            error_rate_last_minute: 0.0,
853            timestamp: SystemTime::now(),
854        }
855    }
856}
857
858impl Default for MemoryUsage {
859    fn default() -> Self {
860        Self {
861            peak_memory: 0,
862            average_memory: 0,
863            memory_efficiency: 1.0,
864            gc_pressure: 0.0,
865        }
866    }
867}
868
869impl Default for IOMetrics {
870    fn default() -> Self {
871        Self {
872            read_bytes_per_sec: 0.0,
873            write_bytes_per_sec: 0.0,
874            read_ops_per_sec: 0.0,
875            write_ops_per_sec: 0.0,
876        }
877    }
878}
879
880impl Default for NetworkMetrics {
881    fn default() -> Self {
882        Self {
883            bytes_sent_per_sec: 0.0,
884            bytes_received_per_sec: 0.0,
885            packets_sent_per_sec: 0.0,
886            packets_received_per_sec: 0.0,
887        }
888    }
889}
890
891impl Default for SystemMetrics {
892    fn default() -> Self {
893        Self {
894            cpu_info: CPUInfo {
895                cores: 1,
896                threads: 1,
897                model: "Unknown".to_string(),
898                frequency: 0.0,
899            },
900            memory_info: MemoryInfo {
901                total: 0,
902                available: 0,
903                used: 0,
904            },
905            disk_info: DiskInfo {
906                total: 0,
907                available: 0,
908                read_speed: 0.0,
909                write_speed: 0.0,
910            },
911            network_info: NetworkInfo {
912                bandwidth: 0.0,
913                latency: Duration::from_millis(0),
914            },
915            gpu_info: None,
916        }
917    }
918}
919
920#[cfg(test)]
921mod tests {
922    use super::*;
923    use std::time::Duration;
924
925    #[test]
926    fn test_analytics_manager_creation() {
927        let temp_dir = std::env::temp_dir().join("torsh_analytics_test");
928        let manager = AnalyticsManager::new(temp_dir);
929        assert!(manager.is_ok());
930    }
931
932    #[test]
933    fn test_usage_tracking() {
934        let temp_dir = std::env::temp_dir().join("torsh_analytics_test2");
935        let mut manager = AnalyticsManager::new(temp_dir).unwrap();
936
937        let result = manager.track_model_usage("test_model", Duration::from_millis(100));
938        assert!(result.is_ok());
939
940        let stats = manager.usage_tracker.get_model_stats("test_model");
941        assert!(stats.is_some());
942        assert_eq!(stats.unwrap().total_inferences, 1);
943    }
944
945    #[test]
946    fn test_ab_test_creation() {
947        let temp_dir = std::env::temp_dir().join("torsh_analytics_test3");
948        let mut manager = AnalyticsManager::new(temp_dir).unwrap();
949
950        let config = ABTestConfig {
951            test_name: "test_comparison".to_string(),
952            description: "Testing model A vs B".to_string(),
953            models_to_test: vec!["model_a".to_string(), "model_b".to_string()],
954            traffic_split: [("model_a".to_string(), 0.5), ("model_b".to_string(), 0.5)]
955                .iter()
956                .cloned()
957                .collect(),
958            success_metrics: vec!["accuracy".to_string()],
959            min_sample_size: 100,
960            max_duration: Duration::from_secs(3600),
961            confidence_level: 0.95,
962        };
963
964        let test_id = manager.start_ab_test(config);
965        assert!(test_id.is_ok());
966    }
967
968    #[test]
969    fn test_real_time_metrics() {
970        let temp_dir = std::env::temp_dir().join("torsh_analytics_test4");
971        let manager = AnalyticsManager::new(temp_dir).unwrap();
972
973        let metrics = manager.get_real_time_metrics();
974        assert_eq!(metrics.active_models, 0);
975        assert_eq!(metrics.total_active_sessions, 0);
976    }
977}