@@ -1470,46 +1470,83 @@ def convert_values_to_unit(data, convert_unit):
14701470 return data
14711471
14721472
1473- def get_cpu_time ():
1473+ def get_cpu_time () -> Dict [str , Dict [str , float ]]:
1474+ """
1475+ Reads /proc/stat to gather CPU time statistics for each CPU core.
1476+ Returns a dictionary with CPU IDs and their respective time metrics.
1477+ """
14741478 cpu_infos = {}
1475- if os .path .exists ('/proc/stat' ):
1476- with open ('/proc/stat' , 'r' ) as file_stat :
1477- cpu_lines = []
1478- for lines in file_stat .readlines ():
1479- for line in lines .split ('\n ' ):
1480- if line .startswith ('cpu' ):
1481- cpu_lines .append (line .split (' ' ))
1482- for cpu_line in cpu_lines :
1483- if '' in cpu_line :
1484- cpu_line .remove ('' ) # First row(cpu) exist '' and Remove ''
1485- cpu_id = cpu_line [0 ]
1486- cpu_line = [float (item ) for item in cpu_line [1 :]]
1487- user , nice , system , idle , iowait , irq , softirq , steal , guest , guest_nice = cpu_line
1488-
1489- idle_time = idle + iowait
1490- non_idle_time = user + nice + system + irq + softirq + steal
1491- total = idle_time + non_idle_time
1492-
1493- cpu_infos .update ({cpu_id : {'total' : total , 'idle' : idle_time , 'iowait' : iowait }})
1479+ if not os .path .exists ('/proc/stat' ):
1480+ return cpu_infos # Return empty dict if /proc/stat is unavailable
1481+
1482+ with open ('/proc/stat' , 'r' ) as file_stat :
1483+ for line in file_stat :
1484+ if not line .startswith ('cpu' ):
1485+ continue
1486+ fields = [field for field in line .split () if field ] # Remove empty strings
1487+ if len (fields ) < 5 : # Basic validation for expected fields
1488+ continue
1489+
1490+ cpu_id = fields [0 ]
1491+ times = [float (t ) for t in fields [1 :]] # Convert to floats
1492+ user , nice , system , idle , iowait = times [:5 ] # Core fields
1493+ # Optional fields (irq, softirq, etc.) may not always be present
1494+ irq = times [5 ] if len (times ) > 5 else 0
1495+ softirq = times [6 ] if len (times ) > 6 else 0
1496+ steal = times [7 ] if len (times ) > 7 else 0
1497+
1498+ idle_time = idle + iowait
1499+ non_idle_time = user + nice + system + irq + softirq + steal
1500+ total_time = idle_time + non_idle_time
1501+
1502+ cpu_infos [cpu_id ] = {
1503+ 'total' : total_time ,
1504+ 'idle' : idle_time ,
1505+ 'iowait' : iowait
1506+ }
14941507 return cpu_infos
14951508
14961509
1497- def get_cpu_usage_percentage ():
1510+ def get_cpu_usage_percentage (interval : float = 1.0 ) -> Dict [str , float ]:
1511+ """
1512+ Calculates CPU usage percentage over a given interval.
1513+ Returns a dictionary with CPU usage percentages per core, average, and iowait.
1514+ """
14981515 start = get_cpu_time ()
1499- time .sleep (1 )
1516+ if not start :
1517+ return {}
1518+
1519+ time .sleep (interval )
15001520 end = get_cpu_time ()
1521+ if not end :
1522+ return {}
1523+
15011524 cpu_usages = {}
15021525 iowait_usages = []
1526+
15031527 for cpu in start :
1504- diff_total = end [cpu ]['total' ] - start [cpu ]['total' ]
1505- diff_idle = end [cpu ]['idle' ] - start [cpu ]['idle' ]
1506- diff_iowait = end [cpu ].get ('iowait' , 0 ) - start [cpu ].get ('iowait' , 0 )
1507- iowait_usages .append (diff_iowait )
1508- cpu_usage_percentage = (diff_total - diff_idle ) / diff_total * 100
1509- cpu_usages .update ({cpu : round (cpu_usage_percentage , 2 )})
1528+ if cpu not in end :
1529+ continue # Skip if CPU data is missing in end snapshot
1530+ try :
1531+ diff_total = end [cpu ]['total' ] - start [cpu ]['total' ]
1532+ diff_idle = end [cpu ]['idle' ] - start [cpu ]['idle' ]
1533+ diff_iowait = end [cpu ]['iowait' ] - start [cpu ]['iowait' ]
1534+
1535+ if diff_total <= 0 : # Avoid division by zero or negative time
1536+ cpu_usage_percentage = 0.0
1537+ else :
1538+ cpu_usage_percentage = (diff_total - diff_idle ) / diff_total * 100
1539+
1540+ cpu_usages [cpu ] = round (cpu_usage_percentage , 2 )
1541+ iowait_usages .append (diff_iowait )
1542+ except KeyError as e :
1543+ print (f"Warning: Missing data for { cpu } : { e } " )
1544+ continue
1545+
15101546 if cpu_usages :
1511- cpu_usages ['avg' ] = round (sum (cpu_usages .values ()) / len (cpu_usages . values () ), 2 )
1547+ cpu_usages ['avg' ] = round (sum (cpu_usages .values ()) / len (cpu_usages ), 2 )
15121548 cpu_usages ['iowait' ] = round (sum (iowait_usages ) / len (iowait_usages ), 2 )
1549+
15131550 return cpu_usages
15141551
15151552
0 commit comments