Skip to content

Instantly share code, notes, and snippets.

@capttwinky
Created March 20, 2012 22:07
Show Gist options
  • Save capttwinky/2141762 to your computer and use it in GitHub Desktop.
Save capttwinky/2141762 to your computer and use it in GitHub Desktop.
beginnings of a /proc fs -> serialized object script
import re
from collections import namedtuple
from itertools import islice as itslice
def sdict(ntpl, keys, defval = None):
return {k: getattr(ntpl, k, defval) for k in keys}
class ParseHolder(object):
attribs = {}
def __init__(self):
self.attribs = ParseHolder.attribs
def add_attrib_str(self,k,v,strict=True):
if k in self.attribs:
raise KeyError('Key exists in strict mode: %s'%k)
self.attribs[k] = v
def stParse(lines_in):
return {k.strip():v.strip() for k, _, v in
(line.strip('\n').partition(':') for line in lines_in if line) if k and v}
def mkParse(fname,lines_in):
tfields = dictParse[fname]['fields']
if dictParse[fname].get('fslice', None):
lines_in = itslice(lines_in,*dictParse[fname]['fslice'])
Ntpl = namedtuple('Ntpl', tfields)
tfields.remove(dictParse[fname].get('kfield', 'name'))
for tfield in dictParse[fname].get('ignore', []):
tfields.remove(tfield)
try:
df = {getattr(line, dictParse[fname].get('kfield', 'name')).strip():sdict(line, tfields)
for line in [Ntpl(*[f for f in re.split('\s', pline.strip()) if f])
for pline in lines_in if pline]}
except:
for pline in lines_in:
if pline: print [f for f in re.split('\s', pline.strip()) if f]
print lines_in
raise Exception()
return df
def fiParse(fname, lines_in):
dout = {}
lines = [re.split('\s', sline.strip()) for sline in lines_in if sline]
for mline in lines:
if len(mline) == 1: dout[mline[0]] = dictParse[fname].get('default', None)
else: dout[mline[dictParse[fname].get('kindex',0)]]=mline[dictParse[fname].get('vindex',1)]
return dout
dictParse = {
# the 'simple' files := space delimited text -> named tuples -> dict
'partitions': {'fields':['major','minor','blocks','name'], 'fslice': (2,None)},
'diskstats': {'fields':['maj','min','name','nreadissue','nreadmerge',
'nsectread','millsecread','numwricomp','numwrimerge','sectwri',
'milsecwri','ioprog','milsecio','wmilsecio']},
'swaps':{'fields':['name','type','size','used','priority'], 'fslice':(1,None)},
'buddyinfo':{'fields':['node','nnum','zone','name','exp0', 'exp1',
'exp2', 'exp3', 'exp4', 'exp5', 'exp6', 'exp7', 'exp8', 'exp9',
'exp10'],'ignore':['node','nnum','zone']},
'cgroups':{'fields':['name','hiera','cgroups','enabled'], 'fslice':(1,None)},
'mounts':{'fields':['dev','name','type','opts','dump','passno']},
'modules':{'fields':['name','size','instances','depends','state','offset']},
#'consoles':{'fields':['name','ops','flags','number']},
# the 'filedict' files := keys, values in row -> file as dictionary
'vmstat': {},
'misc': {'kindex':1,'vindex':0},
'filesystems': {'kindex':1,'vindex':0,'default':'dev'},
'kallsyms':{'kindex':2,'vindex':1},
}
if __name__ == '__main__':
import os
import json
lstErr = []
ph = ParseHolder()
lstSimple= ['partitions','diskstats','swaps','buddyinfo','cgroups',
'mounts','modules']
lstFdict= ['misc','filesystems','vmstat','kallsyms']
lstAttrib= ['version','version_signature','uptime','loadavg','cmdline',
'execdomains','fb','latency_stats','dma','consoles']
lstComplex= ['schedstat','stat','devices']
bstr = '/proc'
lstFiles = filter(lambda x: not os.path.isdir('%s/%s'%(bstr,x)), os.listdir(bstr))
for mfile in lstFiles:
try:
with open('/proc/%s'%mfile, 'r') as ofile:
mstr = [line.strip('\n') for line in ofile.read().split('\n') if line]
except Exception as e:
lstErr.append(str(e))
continue
if mfile in lstFdict:
print "fdict: %s"%mfile
setattr(ph, mfile, fiParse(mfile,mstr))
elif mfile in lstSimple:
print "simp: %s"%mfile
setattr(ph, mfile, mkParse(mfile,mstr))
elif mfile in lstAttrib:
print "attr: %s"%mfile
ph.add_attrib_str(mfile,mstr[0])
elif mfile in lstComplex:
print "cmplx NI: %s"%mfile
else:
print "def: %s"%mfile
setattr(ph, mfile, stParse(mstr))
with open('proc.json','w') as jfile:
jfile.write(json.dumps( ph.__dict__))
print "\n\nwrotefile"
@capttwinky
Copy link
Author

a couple of basic parsers for some of the files found in /proc
these currently bundle their output into an object, which is output as a dictionary
and serialized to JSON, although you could use anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment