Created
March 20, 2012 22:07
-
-
Save capttwinky/2141762 to your computer and use it in GitHub Desktop.
beginnings of a /proc fs -> serialized object script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.