system_stats.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """Utilities for getting system resource statistics."""
  2. import time
  3. import psutil
  4. def get_system_stats() -> dict:
  5. """Get current system resource statistics.
  6. Returns:
  7. dict: A dictionary containing:
  8. - cpu_percent: CPU usage percentage for the current process
  9. - memory: Memory usage stats (rss, vms, percent)
  10. - disk: Disk usage stats (total, used, free, percent)
  11. - io: I/O statistics (read/write bytes)
  12. """
  13. process = psutil.Process()
  14. # Get initial CPU percentage (this will return 0.0)
  15. process.cpu_percent()
  16. # Wait a bit and get the actual CPU percentage
  17. time.sleep(0.1)
  18. with process.oneshot():
  19. cpu_percent = process.cpu_percent()
  20. memory_info = process.memory_info()
  21. memory_percent = process.memory_percent()
  22. disk_usage = psutil.disk_usage('/')
  23. # Get I/O stats directly from /proc/[pid]/io to avoid psutil's field name assumptions
  24. try:
  25. with open(f'/proc/{process.pid}/io', 'rb') as f:
  26. io_stats = {}
  27. for line in f:
  28. if line:
  29. try:
  30. name, value = line.strip().split(b': ')
  31. io_stats[name.decode('ascii')] = int(value)
  32. except (ValueError, UnicodeDecodeError):
  33. continue
  34. except (FileNotFoundError, PermissionError):
  35. io_stats = {'read_bytes': 0, 'write_bytes': 0}
  36. return {
  37. 'cpu_percent': cpu_percent,
  38. 'memory': {
  39. 'rss': memory_info.rss,
  40. 'vms': memory_info.vms,
  41. 'percent': memory_percent,
  42. },
  43. 'disk': {
  44. 'total': disk_usage.total,
  45. 'used': disk_usage.used,
  46. 'free': disk_usage.free,
  47. 'percent': disk_usage.percent,
  48. },
  49. 'io': {
  50. 'read_bytes': io_stats.get('read_bytes', 0),
  51. 'write_bytes': io_stats.get('write_bytes', 0),
  52. },
  53. }