# # sysstat.py - rteval measurment module collecting system statistics # using the sysstat utility # # Copyright 2013 David Sommerseth # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # For the avoidance of doubt the "preferred form" of this code is one which # is in an open unpatent encumbered format. Where cryptographic key signing # forms part of the process of creating an executable the information # including keys needed to generate an equivalently functional executable # are deemed to be part of the source code. # import os, sys, libxml2, tempfile, time, subprocess, base64, bz2, textwrap from rteval.Log import Log from rteval.modules import rtevalModulePrototype class sysstat(rtevalModulePrototype): def __init__(self, config, logger=None): rtevalModulePrototype.__init__(self, 'measurement', 'sysstat', logger) self.__cfg = config self.__started = False self.__logentry = 0 self.__bin_sadc = "/usr/lib64/sa/sadc" # FIXME: Do dynamically self.__datadir = os.path.join(self.__cfg.reportdir, 'sysstat') self.__datafile = os.path.join(self.__datadir, "sysstat.dat") def _WorkloadSetup(self): # Nothing to do here for sysstat pass def _WorkloadBuild(self): # Nothing to build self._setReady() def _WorkloadPrepare(self): os.mkdir(self.__datadir) def _WorkloadTask(self): # This workload will actually not run any process, but # it will update the data files each time rteval checks # if this workload is alive. # # Just add a single notification that rteval started if self.__logentry == 0: cmd = [self.__bin_sadc, "-S", "XALL", "-C", "rteval started", self.__datafile] subprocess.call(cmd) self.__logentry += 1 def WorkloadAlive(self): # Here the sysstat tool will be called, which will update # the file containing the system information cmd = [self.__bin_sadc, "-S", "XALL", "1", "1", self.__datafile] subprocess.call(cmd) self.__logentry += 1 return True def _WorkloadCleanup(self): # Add 'rteval stopped' comment line cmd = [self.__bin_sadc, "-S", "XALL", "-C", "rteval stopped", self.__datafile] subprocess.call(cmd) self.__logentry += 1 self._setFinished() def MakeReport(self): rep_n = libxml2.newNode('sysstat') rep_n.newProp('command_line', '(sysstat specifics)') rep_n.newProp('num_entries', str(self.__logentry)) fp = open(self.__datafile, "rb") compr = bz2.BZ2Compressor(9) cmpr = compr.compress(fp.read()) data = base64.b64encode(cmpr + compr.flush()) data_n = rep_n.newTextChild(None, 'data', "\n"+"\n".join(textwrap.wrap(data,75))+"\n") data_n.newProp('contents', 'sysstat/sar binary data') data_n.newProp('encoding','base64') data_n.newProp('compression','bz2') fp.close() del cmpr del compr # Return the report return rep_n def ModuleInfo(): # sysstat features - run in parallel with outher measurement modules with loads return {"parallel": True, "loads": True} def ModuleParameters(): return {} # No arguments available def create(params, logger): return sysstat(params, logger) if __name__ == '__main__': from rteval.rtevalConfig import rtevalConfig l = Log() l.SetLogVerbosity(Log.INFO|Log.DEBUG|Log.ERR|Log.WARN) cfg = rtevalConfig({}, logger=l) prms = {} modprms = ModuleParameters() for c, p in modprms.items(): prms[c] = p['default'] cfg.AppendConfig('MeasurementModuleTemplate', prms) cfg_ct = cfg.GetSection('MeasurementModuleTemplate') cfg_ct.reportdir = "." runtime = 10 c = sysstat(cfg_ct, l) c._WorkloadSetup() c._WorkloadPrepare() c._WorkloadTask() print "Running for approx %i seconds" % runtime while runtime > 0: c.WorkloadAlive() time.sleep(1) runtime -= 1 c._WorkloadCleanup() rep_n = c.MakeReport() xml = libxml2.newDoc('1.0') xml.setRootElement(rep_n) xml.saveFormatFileEnc('-','UTF-8',1)