00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 """ module for investigating the Linux /proc filesystem
00086
00087 """
00088 import os, re, string
00089 __ext_version__ = '1.0'
00090 __version__ = '$Revision: 1.2 $'
00091
00092 DIGITS = {}
00093 for d in "1234567890":
00094 DIGITS[d] = 1
00095
00096
00097 l2_2_18_procstat = [
00098 'pid', 'comm', 'state', 'ppid', 'pgrp', 'session', 'tty', 'tty_pgrp',
00099 'flags', 'min_flt', 'cmin_flt', 'maj_flt', 'cmaj_flt', 'utime',
00100 'stime', 'cutime', 'cstime', 'priority', 'nice', 'NULL',
00101 'it_real_value', 'start_time', 'vsize', 'rss', 'rlim', 'start_code',
00102 'end_code', 'start_stack', 'esp', 'eip', 'signal',
00103 'blocked', 'sigign', 'sigcatch', 'wchan', 'nswap', 'cnswap',
00104 'exit_signal', 'processor'
00105 ]
00106
00107
00108 l2_2_18_loadavg = ['1min', '5min', '15min', 'running', 'cumulative']
00109
00110
00111 l2_2_18_uptime = ['uptime', 'idle']
00112
00113
00114 l2_2_18_procstatm = ['size', 'resident', 'shared', 'trs', 'drs', 'lrs', 'dt']
00115
00116
00117 l2_2_18_stat = {
00118 'cpu' : ['user', 'nice', 'system', 'idle'],
00119 'disk' : ['unknown1', 'unknown2', 'unknown3'],
00120 'disk_rio' : ['unknown1', 'unknown2', 'unknown3'],
00121 'disk_wio' : ['unknown1', 'unknown2', 'unknown3'],
00122 'disk_rblk' : ['unknown1', 'unknown2', 'unknown3'],
00123 'disk_wblk' : ['unknown1', 'unknown2', 'unknown3'],
00124 'page' : ['in', 'out'],
00125 'swap' : ['in', 'out'],
00126 'intr' : ['interrupts'],
00127 'ctxt' : ['context_switches'],
00128 'btime' : ['boot_time'],
00129 'processes' : ['processes'],
00130 }
00131
00132
00133 l2_4_2_stat = {
00134 'cpu' : ['user', 'nice', 'system', 'idle'],
00135 'cpu0' : ['user', 'nice', 'system', 'idle'],
00136 'cpu1' : ['user', 'nice', 'system', 'idle'],
00137 'cpu2' : ['user', 'nice', 'system', 'idle'],
00138 'cpu3' : ['user', 'nice', 'system', 'idle'],
00139 'cpu4' : ['user', 'nice', 'system', 'idle'],
00140 'cpu5' : ['user', 'nice', 'system', 'idle'],
00141 'cpu6' : ['user', 'nice', 'system', 'idle'],
00142 'cpu7' : ['user', 'nice', 'system', 'idle'],
00143 'cpu8' : ['user', 'nice', 'system', 'idle'],
00144 'cpu9' : ['user', 'nice', 'system', 'idle'],
00145 'cpu10' : ['user', 'nice', 'system', 'idle'],
00146 'cpu11' : ['user', 'nice', 'system', 'idle'],
00147 'page' : ['in', 'out'],
00148 'swap' : ['in', 'out'],
00149 'intr' : ['interrupts'],
00150 'disk_io' : ['unknown1', 'unknown2', 'unknown3'],
00151 'ctxt' : ['context_switches'],
00152 'btime' : ['boot_time'],
00153 'processes' : ['processes'],
00154 }
00155
00156 version_map = {
00157 ('2','2','18'): { 'procstat' : l2_2_18_procstat,
00158 'loadavg' : l2_2_18_loadavg,
00159 'uptime' : l2_2_18_uptime,
00160 'stat': l2_2_18_stat,
00161 'procstatm' : l2_2_18_procstatm,
00162 },
00163 ('2','4','2') : { 'procstat' : l2_2_18_procstat,
00164 'loadavg' : l2_2_18_loadavg,
00165 'uptime' : l2_2_18_uptime,
00166 'stat': l2_4_2_stat,
00167 'procstatm' : l2_2_18_procstatm,
00168 },
00169 }
00170
00171 version_guess_map = {
00172 ('2', '2') : ('2', '2', '18'),
00173 ('2', '4') : ('2', '4', '2'),
00174 ('2', '6') : ('2', '4', '2'),
00175 }
00176
00177 def get_struct(v, vmap=version_map.get, guess=version_guess_map.get):
00178 return vmap(v) or vmap(guess(tuple(v[:2])))
00179
00180 def get_kernel_version():
00181 version_match = re.compile(r'(\d+)\.(\d+)\.(\d+)').search
00182 s = open('/proc/version').readline()
00183 match = version_match(s)
00184 return (match.group(1), match.group(2), match.group(3))
00185
00186 VERSION = get_kernel_version()
00187
00188 def proc_statm(pid):
00189 return get_dict('procstatm', '/proc/%s/statm' % pid)
00190
00191 def self_statm():
00192 return get_dict('procstatm', '/proc/self/statm')
00193
00194 def proc_stat(pid):
00195 return get_dict('procstat', '/proc/%s/stat' % pid)
00196
00197 def self_stat():
00198 return get_dict('procstat', '/proc/self/stat')
00199
00200 def loadavg():
00201 return get_dict('loadavg', '/proc/loadavg')
00202
00203 def uptime():
00204 return get_dict('uptime', '/proc/uptime')
00205
00206 def stat():
00207 return get_multidict('stat', '/proc/stat')
00208
00209 def meminfo():
00210 """ very expensive on 2.2 kernels, not so on 2.4 kernels """
00211 lines = []; dict = {}
00212 for line in open('/proc/meminfo').readlines():
00213 if line:
00214 l = string.split(line)
00215 name, value = l[0], l[1:]
00216 if name in('total:', 'Mem:', 'Swap:'):
00217 continue
00218 key = string.lower(name)[:-1]
00219 value = value[0]
00220 if value and DIGITS.has_key(value[0]):
00221 value = maybe_number(value)
00222 dict[key] = value
00223 return dict
00224
00225 def getrunners(getsleepers=0, isdigit=DIGITS.has_key):
00226 running = []; swapped = []; blocked = []; sleeping = []
00227 addtorun = running.append
00228 addtoswap = swapped.append
00229 addtoblock = blocked.append
00230 addtosleep = sleeping.append
00231 names = os.listdir('/proc')
00232 for name in names:
00233 excp_happened = 0
00234 if isdigit(name[0]):
00235 try: stat = proc_stat(name)
00236 except: excp_happened = 1
00237 if excp_happened: continue
00238 state = stat['state']
00239 rss = stat['rss']
00240 if getsleepers and state == "S":
00241 addtosleep(name)
00242 elif state == "R":
00243 if rss > 0: addtorun(name)
00244 else: addtoswap(name)
00245 elif state == "D":
00246 if rss > 0: addtoblock(name)
00247 else: addtoswap(name)
00248 if getsleepers:
00249 return running, blocked, swapped, sleeping
00250 else:
00251 return running, blocked, swapped
00252
00253 def get_dict(structname, filename, isdigit=DIGITS.has_key,
00254 find=string.find):
00255 lookup = get_struct(VERSION)[structname]
00256 d = {}; i = 0
00257 raw = string.split(open(filename).readline())
00258 for value in raw:
00259 if value and isdigit(value[0]):
00260 value = maybe_number(value)
00261 try:
00262 name = lookup[i]
00263 d[name] = value
00264 except:
00265 pass
00266 i = i + 1
00267 return d
00268
00269 def get_multidict(structname, filename, isdigit=DIGITS.has_key,
00270 find=string.find):
00271 dict = {}
00272 lookup = get_struct(VERSION)[structname]
00273 for line in open(filename, 'r').readlines():
00274 l = string.split(line)
00275 category = l[0]
00276 if not lookup.has_key(category):
00277 continue
00278 items = l[1:]
00279 d = {}; i = 0
00280 for name in lookup[category]:
00281 value = items[i]
00282 if value and isdigit(value[0]):
00283 value = maybe_number(value)
00284 d[name] = value
00285 i = i + 1
00286 dict[category] = d
00287 return dict
00288
00289 def maybe_number(value, find=string.find, float=float, int=int):
00290 try:
00291 if find(value, '.') != -1:
00292 return float(value)
00293 else:
00294 return int(value)
00295 except ValueError:
00296 return value
00297
00298 if __name__ == '__main__':
00299 import time
00300 start = time.time()
00301 for x in xrange(100):
00302 getrunners()
00303 uptime()
00304 loadavg()
00305 self_statm()
00306 self_stat()
00307 stat()
00308 meminfo()
00309 end = time.time()
00310 print end-start
00311
00312
00313 for key, value in self_stat().items():
00314 print key, value
00315 for key, value in loadavg().items():
00316 print key, value
00317 for key, value in uptime().items():
00318 print key, value
00319 for key, value in stat().items():
00320 print key, value
00321 for key, value in meminfo().items():
00322 print key, value
00323 for key, value in self_statm().items():
00324 print key, value
00325
00326