@@ -145,46 +145,88 @@ def _database_version() -> tuple[str, bool]:
145
145
146
146
def _system_metrics () -> Dict [str , Any ]:
147
147
"""
148
- Gather system and process metrics using psutil if available.
148
+ Gather system-wide and per-process metrics using psutil, falling back gracefully
149
+ if psutil is not installed or certain APIs are unavailable.
149
150
150
151
Returns:
151
- Dict[str, Any]: Metrics including CPU, memory, disk, and process details.
152
+ Dict[str, Any]: A dictionary containing:
153
+ - boot_time (str): ISO-formatted system boot time.
154
+ - cpu_percent (float): Total CPU utilization percentage.
155
+ - cpu_count (int): Number of logical CPU cores.
156
+ - cpu_freq_mhz (int | None): Current CPU frequency in MHz, or None if unavailable.
157
+ - load_avg (tuple[float | None, float | None, float | None]):
158
+ System load average over 1, 5, and 15 minutes, or (None, None, None)
159
+ on platforms without getloadavg.
160
+ - mem_total_mb (int): Total physical memory in megabytes.
161
+ - mem_used_mb (int): Used physical memory in megabytes.
162
+ - swap_total_mb (int): Total swap memory in megabytes.
163
+ - swap_used_mb (int): Used swap memory in megabytes.
164
+ - disk_total_gb (float): Total size of the root disk partition in gigabytes.
165
+ - disk_used_gb (float): Used space of the root disk partition in gigabytes.
166
+ - process (Dict[str, Any]): A nested dict with per-process metrics:
167
+ * pid (int): Current process ID.
168
+ * threads (int): Number of active threads.
169
+ * rss_mb (float): Resident Set Size memory usage in megabytes.
170
+ * vms_mb (float): Virtual Memory Size usage in megabytes.
171
+ * open_fds (int | None): Number of open file descriptors, or None if unsupported.
172
+ * proc_cpu_percent (float): CPU utilization percentage for this process.
173
+ {}: Empty dict if psutil is not installed.
152
174
"""
153
175
if not psutil :
154
176
return {}
177
+
178
+ # System memory and swap
155
179
vm = psutil .virtual_memory ()
156
180
swap = psutil .swap_memory ()
181
+
182
+ # Load average (Unix); on Windows returns (None, None, None)
157
183
try :
158
184
load = tuple (round (x , 2 ) for x in os .getloadavg ())
159
185
except (AttributeError , OSError ):
160
186
load = (None , None , None )
187
+
188
+ # CPU metrics
161
189
freq = psutil .cpu_freq ()
190
+ cpu_pct = psutil .cpu_percent (interval = 0.3 )
191
+ cpu_count = psutil .cpu_count (logical = True )
192
+
193
+ # Process metrics
162
194
proc = psutil .Process ()
163
195
try :
164
196
open_fds = proc .num_fds ()
165
197
except Exception :
166
198
open_fds = None
167
- root = Path (os .getenv ("SystemDrive" , "C:\\ " )) if os .name == "nt" else Path ("/" )
168
- disk = psutil .disk_usage (root )
199
+ proc_cpu_pct = proc .cpu_percent (interval = 0.1 )
200
+ rss_mb = round (proc .memory_info ().rss / 1_048_576 , 2 )
201
+ vms_mb = round (proc .memory_info ().vms / 1_048_576 , 2 )
202
+ threads = proc .num_threads ()
203
+ pid = proc .pid
204
+
205
+ # Disk usage for root partition (ensure str on Windows)
206
+ root = os .getenv ("SystemDrive" , "C:\\ " ) if os .name == "nt" else "/"
207
+ disk = psutil .disk_usage (str (root ))
208
+ disk_total_gb = round (disk .total / 1_073_741_824 , 2 )
209
+ disk_used_gb = round (disk .used / 1_073_741_824 , 2 )
210
+
169
211
return {
170
212
"boot_time" : datetime .fromtimestamp (psutil .boot_time ()).isoformat (),
171
- "cpu_percent" : psutil . cpu_percent ( interval = 0.3 ) ,
172
- "cpu_count" : psutil . cpu_count ( logical = True ) ,
213
+ "cpu_percent" : cpu_pct ,
214
+ "cpu_count" : cpu_count ,
173
215
"cpu_freq_mhz" : round (freq .current ) if freq else None ,
174
216
"load_avg" : load ,
175
217
"mem_total_mb" : round (vm .total / 1_048_576 ),
176
218
"mem_used_mb" : round (vm .used / 1_048_576 ),
177
219
"swap_total_mb" : round (swap .total / 1_048_576 ),
178
220
"swap_used_mb" : round (swap .used / 1_048_576 ),
179
- "disk_total_gb" : round ( disk . total / 1_073_741_824 , 2 ) ,
180
- "disk_used_gb" : round ( disk . used / 1_073_741_824 , 2 ) ,
221
+ "disk_total_gb" : disk_total_gb ,
222
+ "disk_used_gb" : disk_used_gb ,
181
223
"process" : {
182
- "pid" : proc . pid ,
183
- "threads" : proc . num_threads () ,
184
- "rss_mb" : round ( proc . memory_info (). rss / 1_048_576 , 2 ) ,
185
- "vms_mb" : round ( proc . memory_info (). vms / 1_048_576 , 2 ) ,
224
+ "pid" : pid ,
225
+ "threads" : threads ,
226
+ "rss_mb" : rss_mb ,
227
+ "vms_mb" : vms_mb ,
186
228
"open_fds" : open_fds ,
187
- "proc_cpu_percent" : proc . cpu_percent ( interval = 0.1 ) ,
229
+ "proc_cpu_percent" : proc_cpu_pct ,
188
230
},
189
231
}
190
232
0 commit comments