Nihal2000 commited on
Commit
672ea87
·
verified ·
1 Parent(s): 10d036a

Update src/utils/performance.py

Browse files
Files changed (1) hide show
  1. src/utils/performance.py +125 -90
src/utils/performance.py CHANGED
@@ -1,90 +1,125 @@
1
- # src/utils/performance.py
2
- import time
3
- import psutil
4
- import threading
5
- from dataclasses import dataclass
6
- from typing import Dict, Any, List
7
- from src.utils.logger import get_logger
8
-
9
- logger = get_logger(__name__)
10
-
11
- @dataclass
12
- class PerformanceMetrics:
13
- start_time: float
14
- end_time: float
15
- duration: float
16
- cpu_usage: List[float]
17
- memory_usage: List[float]
18
- peak_memory: float
19
- operation_name: str
20
-
21
- class PerformanceMonitor:
22
- def __init__(self, operation_name: str):
23
- self.operation_name = operation_name
24
- self.start_time = None
25
- self.end_time = None
26
- self.cpu_usage = []
27
- self.memory_usage = []
28
- self.monitoring = False
29
- self.monitor_thread = None
30
-
31
- def __enter__(self):
32
- self.start_monitoring()
33
- return self
34
-
35
- def __exit__(self, exc_type, exc_val, exc_tb):
36
- self.stop_monitoring()
37
-
38
- def start_monitoring(self):
39
- """Start performance monitoring"""
40
- self.start_time = time.time()
41
- self.monitoring = True
42
-
43
- self.monitor_thread = threading.Thread(target=self._monitor_resources)
44
- self.monitor_thread.daemon = True
45
- self.monitor_thread.start()
46
-
47
- logger.info(f"Started monitoring: {self.operation_name}")
48
-
49
- def stop_monitoring(self):
50
- """Stop performance monitoring and return metrics"""
51
- self.end_time = time.time()
52
- self.monitoring = False
53
-
54
- if self.monitor_thread:
55
- self.monitor_thread.join(timeout=1.0)
56
-
57
- metrics = PerformanceMetrics(
58
- start_time=self.start_time,
59
- end_time=self.end_time,
60
- duration=self.end_time - self.start_time,
61
- cpu_usage=self.cpu_usage,
62
- memory_usage=self.memory_usage,
63
- peak_memory=max(self.memory_usage) if self.memory_usage else 0,
64
- operation_name=self.operation_name
65
- )
66
-
67
- self._log_metrics(metrics)
68
- return metrics
69
-
70
- def _monitor_resources(self):
71
- """Monitor CPU and memory usage in background"""
72
- while self.monitoring:
73
- try:
74
- cpu_percent = psutil.cpu_percent(interval=0.1)
75
- memory_info = psutil.virtual_memory()
76
-
77
- self.cpu_usage.append(cpu_percent)
78
- self.memory_usage.append(memory_info.used / 1024 / 1024) # Convert to MB
79
-
80
- time.sleep(0.5) # Monitor every 0.5 seconds
81
- except Exception as e:
82
- logger.error(f"Error monitoring resources: {str(e)}")
83
- break
84
-
85
- def _log_metrics(self, metrics: PerformanceMetrics):
86
- """Log performance metrics"""
87
- logger.info(f"Performance Report for: {metrics.operation_name}")
88
- logger.info(f" Duration: {metrics.duration:.2f} seconds")
89
- logger.info(f" Peak Memory: {metrics.peak_memory:.2f} MB")
90
- logger.info(f" Average CPU: {sum(metrics.cpu_usage)/len(metrics.cpu_usage):.1f}%" if metrics.cpu_usage else "N/A")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import psutil
3
+ import threading
4
+ import os
5
+ from dataclasses import dataclass
6
+ from typing import Dict, Any, List
7
+ from src.utils.logger import get_logger
8
+
9
+ logger = get_logger(__name__)
10
+
11
+ @dataclass
12
+ class PerformanceMetrics:
13
+ start_time: float
14
+ end_time: float
15
+ duration: float
16
+ cpu_usage: List[float]
17
+ memory_usage: List[float]
18
+ peak_memory: float
19
+ operation_name: str
20
+
21
+ class PerformanceMonitor:
22
+ def __init__(self, operation_name: str):
23
+ self.operation_name = operation_name
24
+ self.start_time = None
25
+ self.end_time = None
26
+ self.cpu_usage = []
27
+ self.memory_usage = []
28
+ self.monitoring = False
29
+ self.monitor_thread = None
30
+ # Get current process for accurate memory tracking
31
+ self.process = psutil.Process(os.getpid())
32
+ self.baseline_memory = self.process.memory_info().rss / 1024 / 1024 # MB
33
+
34
+ def __enter__(self):
35
+ """Context manager entry - start monitoring"""
36
+ self.start_monitoring()
37
+ return self
38
+
39
+ def __exit__(self, exc_type, exc_val, exc_tb):
40
+ """Context manager exit - stop monitoring"""
41
+ return self.stop_monitoring()
42
+
43
+ def start_monitoring(self):
44
+ """Start monitoring system resources"""
45
+ self.start_time = time.time()
46
+ self.monitoring = True
47
+ self.cpu_usage = []
48
+ self.memory_usage = []
49
+
50
+ # Start monitoring thread
51
+ self.monitor_thread = threading.Thread(target=self._monitor_resources)
52
+ self.monitor_thread.daemon = True
53
+ self.monitor_thread.start()
54
+
55
+ logger.info(f"Started monitoring: {self.operation_name}")
56
+
57
+ def stop_monitoring(self):
58
+ """Stop resource monitoring and return metrics"""
59
+ self.end_time = time.time()
60
+ self.monitoring = False
61
+
62
+ if self.monitor_thread:
63
+ self.monitor_thread.join()
64
+
65
+ # Calculate memory increase from baseline
66
+ if self.memory_usage:
67
+ current_memory = self.process.memory_info().rss / 1024 / 1024
68
+ memory_increase = max(self.memory_usage) - self.baseline_memory
69
+ peak_memory = max(memory_increase, 0) # Ensure non-negative
70
+ else:
71
+ peak_memory = 0
72
+
73
+ metrics = PerformanceMetrics(
74
+ start_time=self.start_time,
75
+ end_time=self.end_time,
76
+ duration=self.end_time - self.start_time,
77
+ cpu_usage=self.cpu_usage,
78
+ memory_usage=self.memory_usage,
79
+ peak_memory=peak_memory, # Memory increase from baseline
80
+ operation_name=self.operation_name
81
+ )
82
+
83
+ self._log_metrics(metrics)
84
+ return metrics
85
+
86
+ def _monitor_resources(self):
87
+ """Monitor CPU and memory usage in background"""
88
+ while self.monitoring:
89
+ try:
90
+ # Get process-specific CPU usage
91
+ cpu_percent = self.process.cpu_percent()
92
+
93
+ # Get process-specific memory usage (RSS - Resident Set Size)
94
+ memory_info = self.process.memory_info()
95
+ memory_mb = memory_info.rss / 1024 / 1024 # Convert to MB
96
+
97
+ self.cpu_usage.append(cpu_percent)
98
+ self.memory_usage.append(memory_mb)
99
+
100
+ time.sleep(0.1) # Monitor every 0.1 seconds for more precision
101
+ except Exception as e:
102
+ logger.error(f"Error monitoring resources: {str(e)}")
103
+ break
104
+
105
+ def _log_metrics(self, metrics: PerformanceMetrics):
106
+ """Log performance metrics"""
107
+ logger.info(f"Performance Report for: {metrics.operation_name}")
108
+ logger.info(f" Duration: {metrics.duration:.2f} seconds")
109
+ logger.info(f" Peak Memory: {metrics.peak_memory:.2f} MB")
110
+ if metrics.cpu_usage:
111
+ avg_cpu = sum(metrics.cpu_usage) / len(metrics.cpu_usage)
112
+ logger.info(f" Average CPU: {avg_cpu:.1f}%")
113
+
114
+ def get_current_memory_usage(self):
115
+ """Get current process memory usage in MB"""
116
+ return self.process.memory_info().rss / 1024 / 1024
117
+
118
+ def get_system_info():
119
+ """Get system information for performance context"""
120
+ process = psutil.Process()
121
+ return {
122
+ "cpu_count": psutil.cpu_count(),
123
+ "memory_total_gb": psutil.virtual_memory().total / 1024 / 1024 / 1024,
124
+ "process_memory_mb": process.memory_info().rss / 1024 / 1024
125
+ }