8
8
9
9
"""CPU percent stats shared between CPU and Quicklook plugins."""
10
10
11
+ from typing import List , Optional , TypedDict
12
+
11
13
import psutil
12
14
13
15
from glances .logger import logger
14
16
from glances .timer import Timer
15
17
18
+ __all__ = ["cpu_percent" ]
19
+
20
+
21
+ class CpuInfo (TypedDict ):
22
+ cpu_name : str
23
+ cpu_hz : Optional [float ]
24
+ cpu_hz_current : Optional [float ]
25
+
26
+
27
+ class PerCpuPercentInfo (TypedDict ):
28
+ key : str
29
+ cpu_number : int
30
+ total : float
31
+ user : float
32
+ system : float
33
+ idle : float
34
+ nice : Optional [float ]
35
+ iowait : Optional [float ]
36
+ irq : Optional [float ]
37
+ softirq : Optional [float ]
38
+ steal : Optional [float ]
39
+ guest : Optional [float ]
40
+ guest_nice : Optional [float ]
41
+ dpc : Optional [float ]
42
+ interrupt : Optional [float ]
43
+
16
44
17
45
class CpuPercent :
18
46
"""Get and store the CPU percent."""
19
47
20
- def __init__ (self , cached_timer_cpu = 2 ):
48
+ def __init__ (self , cached_timer_cpu : int = 2 ):
21
49
# cached_timer_cpu is the minimum time interval between stats updates
22
50
# since last update is passed (will retrieve old cached info instead)
23
51
self .cached_timer_cpu = cached_timer_cpu
@@ -27,21 +55,21 @@ def __init__(self, cached_timer_cpu=2):
27
55
28
56
# Get CPU name
29
57
self .timer_cpu_info = Timer (0 )
30
- self .cpu_info = {'cpu_name' : self .__get_cpu_name (), 'cpu_hz_current' : None , 'cpu_hz' : None }
58
+ self .cpu_info : CpuInfo = {'cpu_name' : self .__get_cpu_name (), 'cpu_hz_current' : None , 'cpu_hz' : None }
31
59
32
60
# Warning from PsUtil documentation
33
61
# The first time this function is called with interval = 0.0 or None
34
62
# it will return a meaningless 0.0 value which you are supposed to ignore.
35
63
self .timer_cpu = Timer (0 )
36
- self .cpu_percent = self .get_cpu ()
64
+ self .cpu_percent = self ._compute_cpu ()
37
65
self .timer_percpu = Timer (0 )
38
- self .percpu_percent = self .get_percpu ()
66
+ self .percpu_percent = self ._compute_percpu ()
39
67
40
68
def get_key (self ):
41
69
"""Return the key of the per CPU list."""
42
70
return 'cpu_number'
43
71
44
- def get_info (self ):
72
+ def get_info (self ) -> CpuInfo :
45
73
"""Get additional information about the CPU"""
46
74
# Never update more than 1 time per cached_timer_cpu_info
47
75
if self .timer_cpu_info .finished () and hasattr (psutil , 'cpu_freq' ):
@@ -63,70 +91,69 @@ def get_info(self):
63
91
self .timer_cpu_info .reset (duration = self .cached_timer_cpu_info )
64
92
return self .cpu_info
65
93
66
- def __get_cpu_name (self ):
94
+ @staticmethod
95
+ def __get_cpu_name () -> str :
67
96
# Get the CPU name once from the /proc/cpuinfo file
68
97
# Read the first line with the "model name" ("Model" for Raspberry Pi)
69
- ret = None
70
98
try :
71
- cpuinfo_file = open ('/proc/cpuinfo' ).readlines ()
99
+ cpuinfo_lines = open ('/proc/cpuinfo' ).readlines ()
72
100
except (FileNotFoundError , PermissionError ):
73
- pass
74
- else :
75
- for line in cpuinfo_file :
76
- if line .startswith ('model name' ) or line .startswith ('Model' ) or line .startswith ('cpu model' ):
77
- ret = line .split (':' )[1 ].strip ()
78
- break
79
- return ret if ret else 'CPU'
80
-
81
- def get_cpu (self ):
101
+ logger .debug ("No permission to read '/proc/cpuinfo'" )
102
+ return 'CPU'
103
+
104
+ for line in cpuinfo_lines :
105
+ if line .startswith ('model name' ) or line .startswith ('Model' ) or line .startswith ('cpu model' ):
106
+ return line .split (':' )[1 ].strip ()
107
+
108
+ return 'CPU'
109
+
110
+ def get_cpu (self ) -> float :
82
111
"""Update and/or return the CPU using the psutil library."""
83
112
# Never update more than 1 time per cached_timer_cpu
84
113
if self .timer_cpu .finished ():
85
114
# Reset timer for cache
86
115
self .timer_cpu .reset (duration = self .cached_timer_cpu )
87
116
# Update the stats
88
- self .cpu_percent = psutil . cpu_percent ( interval = 0.0 )
117
+ self .cpu_percent = self . _compute_cpu ( )
89
118
return self .cpu_percent
90
119
91
- def get_percpu (self ):
120
+ @staticmethod
121
+ def _compute_cpu () -> float :
122
+ return psutil .cpu_percent (interval = 0.0 )
123
+
124
+ def get_percpu (self ) -> List [PerCpuPercentInfo ]:
92
125
"""Update and/or return the per CPU list using the psutil library."""
93
126
# Never update more than 1 time per cached_timer_cpu
94
127
if self .timer_percpu .finished ():
95
128
# Reset timer for cache
96
129
self .timer_percpu .reset (duration = self .cached_timer_cpu )
97
- # Get stats
98
- percpu_percent = []
99
- psutil_percpu = enumerate (psutil .cpu_times_percent (interval = 0.0 , percpu = True ))
100
- for cpu_number , cputimes in psutil_percpu :
101
- cpu = {
102
- 'key' : self .get_key (),
103
- 'cpu_number' : cpu_number ,
104
- 'total' : round (100 - cputimes .idle , 1 ),
105
- 'user' : cputimes .user ,
106
- 'system' : cputimes .system ,
107
- 'idle' : cputimes .idle ,
108
- }
109
- # The following stats are for API purposes only
110
- if hasattr (cputimes , 'nice' ):
111
- cpu ['nice' ] = cputimes .nice
112
- if hasattr (cputimes , 'iowait' ):
113
- cpu ['iowait' ] = cputimes .iowait
114
- if hasattr (cputimes , 'irq' ):
115
- cpu ['irq' ] = cputimes .irq
116
- if hasattr (cputimes , 'softirq' ):
117
- cpu ['softirq' ] = cputimes .softirq
118
- if hasattr (cputimes , 'steal' ):
119
- cpu ['steal' ] = cputimes .steal
120
- if hasattr (cputimes , 'guest' ):
121
- cpu ['guest' ] = cputimes .guest
122
- if hasattr (cputimes , 'guest_nice' ):
123
- cpu ['guest_nice' ] = cputimes .guest_nice
124
- # Append new CPU to the list
125
- percpu_percent .append (cpu )
126
130
# Update stats
127
- self .percpu_percent = percpu_percent
131
+ self .percpu_percent = self . _compute_percpu ()
128
132
return self .percpu_percent
129
133
134
+ def _compute_percpu (self ) -> List [PerCpuPercentInfo ]:
135
+ psutil_percpu = enumerate (psutil .cpu_times_percent (interval = 0.0 , percpu = True ))
136
+ return [
137
+ {
138
+ 'key' : self .get_key (),
139
+ 'cpu_number' : cpu_number ,
140
+ 'total' : round (100 - cpu_times .idle , 1 ),
141
+ 'user' : cpu_times .user ,
142
+ 'system' : cpu_times .system ,
143
+ 'idle' : cpu_times .idle ,
144
+ 'nice' : cpu_times .nice if hasattr (cpu_times , 'nice' ) else None ,
145
+ 'iowait' : cpu_times .iowait if hasattr (cpu_times , 'iowait' ) else None ,
146
+ 'irq' : cpu_times .irq if hasattr (cpu_times , 'irq' ) else None ,
147
+ 'softirq' : cpu_times .softirq if hasattr (cpu_times , 'softirq' ) else None ,
148
+ 'steal' : cpu_times .steal if hasattr (cpu_times , 'steal' ) else None ,
149
+ 'guest' : cpu_times .guest if hasattr (cpu_times , 'guest' ) else None ,
150
+ 'guest_nice' : cpu_times .steal if hasattr (cpu_times , 'guest_nice' ) else None ,
151
+ 'dpc' : cpu_times .dpc if hasattr (cpu_times , 'dpc' ) else None ,
152
+ 'interrupt' : cpu_times .interrupt if hasattr (cpu_times , 'interrupt' ) else None ,
153
+ }
154
+ for cpu_number , cpu_times in psutil_percpu
155
+ ]
156
+
130
157
131
158
# CpuPercent instance shared between plugins
132
159
cpu_percent = CpuPercent ()
0 commit comments