cpu_meter.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # Author: David Harrison
  2. # Multi-cpu and Windows version: Greg Hazel
  3. import os
  4. if os.name == "nt":
  5. import win32pdh
  6. import win32api
  7. class CPUMeterBase(object):
  8. def __init__(self, update_interval = 2):
  9. from twisted.internet import reactor
  10. self.reactor = reactor
  11. self._util = 0.0
  12. self._util_each = []
  13. self._interval = update_interval
  14. self.reactor.callLater(self._interval, self._update)
  15. def _update(self):
  16. self.update()
  17. self.reactor.callLater(self._interval, self._update)
  18. def update(self):
  19. raise NotImplementedError
  20. def get_utilization(self):
  21. return self._util
  22. def get_utilization_each(self):
  23. return self._util_each
  24. def get_interval(self):
  25. return self._interval
  26. class CPUMeterUnix(CPUMeterBase):
  27. """Averages CPU utilization over an update_interval."""
  28. def __init__(self, update_interval = 2):
  29. self._old_stats = self._get_stats()
  30. CPUMeterBase.__init__(self, update_interval)
  31. def _get_stats(self):
  32. fp = open("/proc/stat")
  33. ln = fp.readline()
  34. stats = ln[4:].strip().split()[:4]
  35. total = [long(x) for x in stats]
  36. cpus = []
  37. ln = fp.readline()
  38. while ln.startswith("cpu"):
  39. stats = ln[4:].strip().split()[:4]
  40. cpu = [long(x) for x in stats]
  41. cpus.append(cpu)
  42. ln = fp.readline()
  43. return total, cpus
  44. def _get_util(self, oldl, newl):
  45. old_user, old_nice, old_sys, old_idle = oldl
  46. user, nice, sys, idle = newl
  47. user -= old_user
  48. nice -= old_nice
  49. sys -= old_sys
  50. idle -= old_idle
  51. total = user + nice + sys + idle
  52. return float((user + nice + sys)) / total
  53. def update(self):
  54. old_total, old_cpus = self._old_stats
  55. total, cpus = self._old_stats = self._get_stats()
  56. self._util = self._get_util(old_total, total)
  57. self._util_each = []
  58. for old_cpu, cpu in zip(old_cpus, cpus):
  59. self._util_each.append(self._get_util(old_cpu, cpu))
  60. class CPUMeterWin32(CPUMeterBase):
  61. """Averages CPU utilization over an update_interval."""
  62. def __init__(self, update_interval = 2):
  63. self.format = win32pdh.PDH_FMT_DOUBLE
  64. self.hcs = []
  65. self.hqs = []
  66. self._setup_query("_Total")
  67. num_cpus = win32api.GetSystemInfo()[4]
  68. for x in xrange(num_cpus):
  69. self._setup_query(x)
  70. CPUMeterBase.__init__(self, update_interval)
  71. def __del__(self):
  72. self.close()
  73. def _setup_query(self, which):
  74. inum = -1
  75. instance = None
  76. machine = None
  77. object = "Processor(%s)" % which
  78. counter = "% Processor Time"
  79. path = win32pdh.MakeCounterPath( (machine, object, instance,
  80. None, inum, counter) )
  81. hq = win32pdh.OpenQuery()
  82. self.hqs.append(hq)
  83. try:
  84. hc = win32pdh.AddCounter(hq, path)
  85. self.hcs.append(hc)
  86. except:
  87. self.close()
  88. raise
  89. def close(self):
  90. for hc in self.hcs:
  91. if not hc:
  92. continue
  93. try:
  94. win32pdh.RemoveCounter(hc)
  95. except:
  96. pass
  97. self.hcs = []
  98. for hq in self.hqs:
  99. if not hq:
  100. continue
  101. try:
  102. win32pdh.CloseQuery(hq)
  103. except:
  104. pass
  105. self.hqs = []
  106. def _get_util(self, i):
  107. win32pdh.CollectQueryData(self.hqs[i])
  108. type, val = win32pdh.GetFormattedCounterValue(self.hcs[i], self.format)
  109. val = val / 100.0
  110. return val
  111. def update(self):
  112. self._util = self._get_util(0)
  113. self._util_each = []
  114. for i in xrange(1, len(self.hcs)):
  115. self._util_each.append(self._get_util(i))
  116. if os.name == "nt":
  117. CPUMeter = CPUMeterWin32
  118. else:
  119. CPUMeter = CPUMeterUnix
  120. if __name__ == "__main__":
  121. from twisted.internet import reactor
  122. cpu = CPUMeter(1)
  123. def print_util():
  124. print cpu.get_utilization()
  125. print cpu.get_utilization_each()
  126. reactor.callLater(1, print_util)
  127. reactor.callLater(1, print_util)
  128. reactor.run()