Package gmisclib :: Module system_load
[frames] | no frames]

Source Code for Module gmisclib.system_load

  1  import os 
  2  import re 
  3  import die 
  4   
5 -def load_avg():
6 return float(open("/proc/loadavg", "r").read().strip().split()[0])
7
8 -def mem_pressure(verbose=False):
9 """@rtype: L{float} 10 @return: Big (>1) when the system is really hurting for memory. Small (<0.5) when things are going well. 11 Also, by way of the amount of dirty memory, it indirectly looks at the rate of writing to the disk. 12 """ 13 SWAPFAC = 1.0 14 x = {} 15 for l in open("/proc/meminfo", "r"): 16 kvu = l.strip().split() 17 if len(kvu) > 1: 18 x[kvu[0].strip().rstrip(':')] = float(kvu[1]) 19 swap = SWAPFAC*(x['SwapTotal']-x['SwapFree'])/x['MemTotal'] 20 active = x['Active'] / x['MemTotal'] 21 dirty = 10 * x['Dirty'] / x['MemTotal'] 22 if verbose: 23 die.info("mem_pressure: sw=%.2f ac=%.2f d=%.2f" % (swap, active, dirty)) 24 return swap + active + dirty
25 26 27 _ncpu = None
28 -def ncpu():
29 global _ncpu 30 if _ncpu is not None: 31 return _ncpu 32 n = 0 33 for l in open("/proc/cpuinfo", "r"): 34 if l.startswith('processor'): 35 n += 1 36 assert n > 0 37 _ncpu = n 38 return n
39 40 get_ncpu = ncpu 41 get_loadavg = load_avg 42 43 # print mem_pressure() 44 # print get_loadavg() 45 46 47 PROC = '/proc' 48
49 -class pstat(object):
50 _spat = re.compile(r'(\d+) \((.*)\) ([A-Z]) ([0-9]+) ([0-9 -]+)') 51 _map = { 'minflt': 5, 'cminflt': 6, 'majflt': 7, 'cmajflt': 8, 52 'utime': 9, 'stime': 10, 'cutime': 11, 'cstime': 12, 53 'priority': 13, 'nice': 14, 'num_threads': 15, 54 'vsize': 18, 'rss': 19, 'rsslim': 20 55 } 56 57
58 - def __init__(self, pid):
59 self.pid = pid 60 fp = open(os.path.join(PROC, str(pid), 'stat'), 'r') 61 self.uid = os.fstat(fp.fileno()).st_uid 62 s = fp.read() 63 m = self._spat.match(s) 64 if not m: 65 raise ValueError, "/proc/pid/stat doesn't match pattern: %s" % s 66 self.comm = m.group(2) 67 self.state = m.group(3) 68 self.ppid = int(m.group(4)) 69 self._more = m.group(5).split()
70
71 - def __getattr__(self, name):
72 return int(self._more[self._map[name]])
73 74 75
76 -def load_now(my_weight=1, other_weight=2, d_weight=0.5, ignore=None, verbose=False):
77 me = os.getuid() 78 mypid = os.getpid() 79 myload = 0 80 oload = 0 81 kload = 0 82 dload = 0 83 for d in os.listdir(PROC): 84 try: 85 pid = int(d) 86 except ValueError: 87 continue 88 if pid == mypid: 89 continue 90 try: 91 fields = pstat(pid) 92 except (ValueError, IOError): 93 continue 94 if ignore is not None and ignore(pid, fields.ppid, fields.comm): 95 continue 96 if fields.state in "RD": 97 if verbose: 98 die.info("pid=%d proc=%s %s" % (fields.pid, fields.comm, fields.state)) 99 if fields.uid == me: 100 myload += 1 101 elif fields.uid == 0: # Kernel 102 kload += 1 103 else: 104 oload += 1 105 if fields.state == "D": 106 dload += 1 107 108 load = float(myload*my_weight + oload*other_weight + dload*d_weight) 109 load += kload * float((myload+1)*my_weight + oload*other_weight) / float(myload+1+oload) 110 return load
111 112
113 -def niceness():
114 """@return: positive numbers if the process is niced; negative numbers if not. 115 @rtype: float in the range [-0.5, 0.5] 116 """ 117 ni = pstat(os.getpid()).nice 118 return float(ni-9.5)/19.0
119 120 121 if __name__ == '__main__': 122 print 'ncpu=', ncpu() 123 print 'niceness=', niceness() 124 for i in range(5): 125 print 'load_now=', load_now(verbose=True), load_now(1,0,0), load_now(0,1,0), load_now(0,0,1) 126 print 'mem_pressure', mem_pressure(verbose=True) 127