invincible-jha commited on
Commit
f83b968
·
1 Parent(s): 76166e3

Add comprehensive logging system and analytics with log rotation

Browse files
Files changed (5) hide show
  1. .gitignore +2 -0
  2. README.md +105 -1
  3. requirements.txt +3 -1
  4. utils/analytics_logger.py +170 -0
  5. utils/log_manager.py +169 -0
.gitignore CHANGED
@@ -32,7 +32,9 @@ ENV/
32
  *.swo
33
 
34
  # Logs
 
35
  *.log
 
36
 
37
  # Local configuration
38
  .env
 
32
  *.swo
33
 
34
  # Logs
35
+ logs/
36
  *.log
37
+ *.log.*
38
 
39
  # Local configuration
40
  .env
README.md CHANGED
@@ -9,4 +9,108 @@ app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  pinned: false
10
  ---
11
 
12
+ # Mental Wellness Platform
13
+
14
+ A comprehensive mental wellness support system powered by AI, deployed on Hugging Face Spaces.
15
+
16
+ ## Features
17
+ - 🤖 Multi-agent AI support system
18
+ - 💬 Natural therapeutic conversations
19
+ - 📊 Mental health assessments
20
+ - 🧘‍♀️ Guided meditation and mindfulness
21
+ - 🚨 Crisis intervention support
22
+ - 📱 Multi-modal interaction (text, voice, image)
23
+ - 📈 Comprehensive logging and analytics
24
+ - 🔄 Automatic log rotation and management
25
+
26
+ ## System Components
27
+ - Therapeutic Conversation Agent
28
+ - Assessment Agent
29
+ - Mindfulness Agent
30
+ - Crisis Intervention Agent
31
+ - Analytics and Logging System
32
+
33
+ ## Logging System
34
+ The platform includes a comprehensive logging system with:
35
+ - Agent-specific logs
36
+ - System health monitoring
37
+ - Analytics tracking
38
+ - Performance metrics
39
+ - Security event logging
40
+ - Automatic log rotation
41
+ - Log cleanup for older files
42
+
43
+ ### Log Categories
44
+ 1. Agent Logs (`logs/agents/`)
45
+ - Individual agent activities
46
+ - Performance metrics
47
+ - Error tracking
48
+
49
+ 2. System Logs (`logs/system/`)
50
+ - System health
51
+ - Resource usage
52
+ - General operations
53
+
54
+ 3. Analytics Logs (`logs/analytics/`)
55
+ - User interactions
56
+ - Session metrics
57
+ - Model performance
58
+ - Usage statistics
59
+
60
+ ## Usage
61
+ 1. Open the chat interface
62
+ 2. Type your message or use voice/image input
63
+ 3. Choose from available tools:
64
+ - Mental Health Check
65
+ - Start Meditation
66
+ - View Resources
67
+
68
+ ## Important Note
69
+ This is an AI-powered support tool and not a substitute for professional mental health care. In case of emergency:
70
+ - Call emergency services: 911 (US)
71
+ - National Crisis Hotline: 988
72
+ - Crisis Text Line: Text HOME to 741741
73
+
74
+ ## Technical Details
75
+ Built with:
76
+ - Gradio for interface
77
+ - Hugging Face Transformers for AI models
78
+ - CrewAI for multi-agent orchestration
79
+ - Advanced voice and image processing
80
+ - Comprehensive logging system
81
+
82
+ ## Development
83
+ To run locally:
84
+ 1. Clone the repository
85
+ 2. Install dependencies:
86
+ ```bash
87
+ pip install -r requirements.txt
88
+ ```
89
+ 3. Run the application:
90
+ ```bash
91
+ python app.py
92
+ ```
93
+
94
+ ## Monitoring
95
+ The system includes:
96
+ - Real-time performance monitoring
97
+ - Error tracking and alerts
98
+ - Usage analytics
99
+ - System health metrics
100
+
101
+ ## Security
102
+ - All conversations are encrypted
103
+ - Comprehensive security logging
104
+ - Access control and monitoring
105
+ - Data retention policies
106
+
107
+ ## License
108
+ MIT License
109
+
110
+ ## Authors
111
+ Created by Invincible Jha
112
+
113
+ ## Acknowledgments
114
+ - CrewAI for the multi-agent framework
115
+ - Hugging Face for AI models and hosting
116
+ - Gradio for the interface framework
requirements.txt CHANGED
@@ -15,4 +15,6 @@ pillow>=10.1.0
15
  redis>=5.0.1
16
  pytest>=7.4.3
17
  crewai>=0.11.0
18
- huggingface_hub>=0.26.5
 
 
 
15
  redis>=5.0.1
16
  pytest>=7.4.3
17
  crewai>=0.11.0
18
+ huggingface_hub>=0.26.5
19
+ psutil>=5.9.0
20
+ python-json-logger>=2.0.7
utils/analytics_logger.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Any, Optional
2
+ import json
3
+ import time
4
+ from datetime import datetime
5
+ from utils.log_manager import LogManager
6
+
7
+ class AnalyticsLogger:
8
+ """Handles logging of analytics events and metrics"""
9
+
10
+ def __init__(self):
11
+ self.log_manager = LogManager()
12
+ self.logger = self.log_manager.get_analytics_logger("events")
13
+ self.metrics_logger = self.log_manager.get_analytics_logger("metrics")
14
+
15
+ def log_user_interaction(self,
16
+ user_id: str,
17
+ interaction_type: str,
18
+ agent_type: str,
19
+ duration: float,
20
+ success: bool,
21
+ details: Optional[Dict] = None):
22
+ """Log user interaction events"""
23
+ event = {
24
+ "event_type": "user_interaction",
25
+ "user_id": user_id,
26
+ "interaction_type": interaction_type,
27
+ "agent_type": agent_type,
28
+ "duration": duration,
29
+ "success": success,
30
+ "timestamp": datetime.now().isoformat(),
31
+ "details": details or {}
32
+ }
33
+
34
+ self.logger.info(f"User Interaction: {json.dumps(event, indent=2)}")
35
+
36
+ def log_agent_performance(self,
37
+ agent_type: str,
38
+ operation: str,
39
+ response_time: float,
40
+ success: bool,
41
+ error: Optional[str] = None):
42
+ """Log agent performance metrics"""
43
+ metric = {
44
+ "metric_type": "agent_performance",
45
+ "agent_type": agent_type,
46
+ "operation": operation,
47
+ "response_time": response_time,
48
+ "success": success,
49
+ "error": error,
50
+ "timestamp": datetime.now().isoformat()
51
+ }
52
+
53
+ self.metrics_logger.info(f"Agent Performance: {json.dumps(metric, indent=2)}")
54
+
55
+ def log_system_health(self,
56
+ cpu_usage: float,
57
+ memory_usage: float,
58
+ active_users: int,
59
+ active_sessions: int):
60
+ """Log system health metrics"""
61
+ metric = {
62
+ "metric_type": "system_health",
63
+ "cpu_usage": cpu_usage,
64
+ "memory_usage": memory_usage,
65
+ "active_users": active_users,
66
+ "active_sessions": active_sessions,
67
+ "timestamp": datetime.now().isoformat()
68
+ }
69
+
70
+ self.metrics_logger.info(f"System Health: {json.dumps(metric, indent=2)}")
71
+
72
+ def log_error(self,
73
+ error_type: str,
74
+ error_message: str,
75
+ severity: str,
76
+ context: Optional[Dict] = None):
77
+ """Log error events"""
78
+ event = {
79
+ "event_type": "error",
80
+ "error_type": error_type,
81
+ "error_message": error_message,
82
+ "severity": severity,
83
+ "context": context or {},
84
+ "timestamp": datetime.now().isoformat()
85
+ }
86
+
87
+ self.logger.error(f"Error Event: {json.dumps(event, indent=2)}")
88
+
89
+ def log_security_event(self,
90
+ event_type: str,
91
+ user_id: str,
92
+ success: bool,
93
+ details: Optional[Dict] = None):
94
+ """Log security-related events"""
95
+ event = {
96
+ "event_type": "security",
97
+ "security_event_type": event_type,
98
+ "user_id": user_id,
99
+ "success": success,
100
+ "details": details or {},
101
+ "timestamp": datetime.now().isoformat()
102
+ }
103
+
104
+ self.logger.info(f"Security Event: {json.dumps(event, indent=2)}")
105
+
106
+ def log_model_performance(self,
107
+ model_name: str,
108
+ operation: str,
109
+ input_tokens: int,
110
+ output_tokens: int,
111
+ response_time: float,
112
+ success: bool):
113
+ """Log AI model performance metrics"""
114
+ metric = {
115
+ "metric_type": "model_performance",
116
+ "model_name": model_name,
117
+ "operation": operation,
118
+ "input_tokens": input_tokens,
119
+ "output_tokens": output_tokens,
120
+ "response_time": response_time,
121
+ "success": success,
122
+ "timestamp": datetime.now().isoformat()
123
+ }
124
+
125
+ self.metrics_logger.info(f"Model Performance: {json.dumps(metric, indent=2)}")
126
+
127
+ def log_user_feedback(self,
128
+ user_id: str,
129
+ interaction_id: str,
130
+ rating: int,
131
+ feedback_text: Optional[str] = None):
132
+ """Log user feedback"""
133
+ event = {
134
+ "event_type": "user_feedback",
135
+ "user_id": user_id,
136
+ "interaction_id": interaction_id,
137
+ "rating": rating,
138
+ "feedback_text": feedback_text,
139
+ "timestamp": datetime.now().isoformat()
140
+ }
141
+
142
+ self.logger.info(f"User Feedback: {json.dumps(event, indent=2)}")
143
+
144
+ def log_session_metrics(self,
145
+ session_id: str,
146
+ user_id: str,
147
+ session_type: str,
148
+ start_time: str,
149
+ end_time: str,
150
+ metrics: Dict[str, Any]):
151
+ """Log session-specific metrics"""
152
+ session_data = {
153
+ "metric_type": "session_metrics",
154
+ "session_id": session_id,
155
+ "user_id": user_id,
156
+ "session_type": session_type,
157
+ "start_time": start_time,
158
+ "end_time": end_time,
159
+ "duration": self._calculate_duration(start_time, end_time),
160
+ "metrics": metrics,
161
+ "timestamp": datetime.now().isoformat()
162
+ }
163
+
164
+ self.metrics_logger.info(f"Session Metrics: {json.dumps(session_data, indent=2)}")
165
+
166
+ def _calculate_duration(self, start_time: str, end_time: str) -> float:
167
+ """Calculate duration between two ISO format timestamps"""
168
+ start = datetime.fromisoformat(start_time)
169
+ end = datetime.fromisoformat(end_time)
170
+ return (end - start).total_seconds()
utils/log_manager.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from logging.handlers import RotatingFileHandler
3
+ import os
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ class LogManager:
8
+ """Manages logging configuration and rotation for all agents"""
9
+
10
+ def __init__(self, log_dir: str = "logs", max_bytes: int = 5_000_000, backup_count: int = 5):
11
+ """Initialize log manager
12
+
13
+ Args:
14
+ log_dir: Directory to store log files
15
+ max_bytes: Maximum size of each log file before rotation
16
+ backup_count: Number of backup files to keep
17
+ """
18
+ self.log_dir = Path(log_dir)
19
+ self.max_bytes = max_bytes
20
+ self.backup_count = backup_count
21
+
22
+ # Create log directories
23
+ self._create_log_dirs()
24
+
25
+ # Configure root logger
26
+ self._configure_root_logger()
27
+
28
+ def _create_log_dirs(self):
29
+ """Create necessary log directories"""
30
+ dirs = [
31
+ self.log_dir,
32
+ self.log_dir / "agents",
33
+ self.log_dir / "system",
34
+ self.log_dir / "analytics"
35
+ ]
36
+
37
+ for dir_path in dirs:
38
+ dir_path.mkdir(parents=True, exist_ok=True)
39
+
40
+ def _configure_root_logger(self):
41
+ """Configure the root logger"""
42
+ root_logger = logging.getLogger()
43
+ root_logger.setLevel(logging.INFO)
44
+
45
+ # System log handler
46
+ system_handler = RotatingFileHandler(
47
+ self.log_dir / "system" / "system.log",
48
+ maxBytes=self.max_bytes,
49
+ backupCount=self.backup_count
50
+ )
51
+ system_handler.setLevel(logging.INFO)
52
+ formatter = logging.Formatter(
53
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
54
+ )
55
+ system_handler.setFormatter(formatter)
56
+ root_logger.addHandler(system_handler)
57
+
58
+ def get_agent_logger(self, agent_name: str, log_level: int = logging.INFO) -> logging.Logger:
59
+ """Get a configured logger for an agent
60
+
61
+ Args:
62
+ agent_name: Name of the agent (used in log file name)
63
+ log_level: Logging level for this logger
64
+
65
+ Returns:
66
+ Configured logger instance
67
+ """
68
+ logger = logging.getLogger(f"agent.{agent_name}")
69
+ logger.setLevel(log_level)
70
+
71
+ # Remove any existing handlers
72
+ logger.handlers = []
73
+
74
+ # Add rotating file handler
75
+ handler = RotatingFileHandler(
76
+ self.log_dir / "agents" / f"{agent_name}.log",
77
+ maxBytes=self.max_bytes,
78
+ backupCount=self.backup_count
79
+ )
80
+ handler.setLevel(log_level)
81
+ formatter = logging.Formatter(
82
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
83
+ )
84
+ handler.setFormatter(formatter)
85
+ logger.addHandler(handler)
86
+
87
+ return logger
88
+
89
+ def get_analytics_logger(self, name: str, log_level: int = logging.INFO) -> logging.Logger:
90
+ """Get a configured logger for analytics
91
+
92
+ Args:
93
+ name: Analytics category name
94
+ log_level: Logging level for this logger
95
+
96
+ Returns:
97
+ Configured logger instance
98
+ """
99
+ logger = logging.getLogger(f"analytics.{name}")
100
+ logger.setLevel(log_level)
101
+
102
+ # Remove any existing handlers
103
+ logger.handlers = []
104
+
105
+ # Add rotating file handler
106
+ handler = RotatingFileHandler(
107
+ self.log_dir / "analytics" / f"{name}.log",
108
+ maxBytes=self.max_bytes,
109
+ backupCount=self.backup_count
110
+ )
111
+ handler.setLevel(log_level)
112
+ formatter = logging.Formatter(
113
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
114
+ )
115
+ handler.setFormatter(formatter)
116
+ logger.addHandler(handler)
117
+
118
+ return logger
119
+
120
+ def cleanup_old_logs(self, max_age_days: int = 30):
121
+ """Clean up log files older than specified days
122
+
123
+ Args:
124
+ max_age_days: Maximum age of log files in days
125
+ """
126
+ import time
127
+ current_time = time.time()
128
+ max_age_seconds = max_age_days * 24 * 60 * 60
129
+
130
+ for root, _, files in os.walk(self.log_dir):
131
+ for file in files:
132
+ file_path = os.path.join(root, file)
133
+ if os.path.getmtime(file_path) < (current_time - max_age_seconds):
134
+ try:
135
+ os.remove(file_path)
136
+ logging.info(f"Removed old log file: {file_path}")
137
+ except Exception as e:
138
+ logging.error(f"Error removing old log file {file_path}: {str(e)}")
139
+
140
+ def get_log_stats(self) -> dict:
141
+ """Get statistics about log files
142
+
143
+ Returns:
144
+ Dictionary containing log statistics
145
+ """
146
+ stats = {
147
+ "total_size": 0,
148
+ "file_count": 0,
149
+ "categories": {}
150
+ }
151
+
152
+ for root, _, files in os.walk(self.log_dir):
153
+ category = os.path.basename(root)
154
+ if category not in stats["categories"]:
155
+ stats["categories"][category] = {
156
+ "size": 0,
157
+ "file_count": 0
158
+ }
159
+
160
+ for file in files:
161
+ file_path = os.path.join(root, file)
162
+ size = os.path.getsize(file_path)
163
+
164
+ stats["total_size"] += size
165
+ stats["file_count"] += 1
166
+ stats["categories"][category]["size"] += size
167
+ stats["categories"][category]["file_count"] += 1
168
+
169
+ return stats