aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2013-06-17 20:55:08 +0200
committerDavid Sommerseth <davids@redhat.com>2013-06-17 21:00:52 +0200
commit9b1ec7ab89fa047877e5713ff33054ac55ecb710 (patch)
treeed9a6403c32acbfd987fbaa68e05ab6717de647a
parentb19b3048de0075e08069b3f9e91776a3542f959b (diff)
downloadrteval-9b1ec7ab89fa047877e5713ff33054ac55ecb710.tar.gz
Added new measurement module, sysstat
This module runs in parallel with cyclictest and will every minute use sysstat/sadc to collect all available system statistics. These statistics is both added as a single file to the tarball and embedded into the summary.xml. Also changed the polling time which checks if measurement and load modules are alive from every second to every minute. Signed-off-by: David Sommerseth <davids@redhat.com>
-rwxr-xr-xrteval-cmd3
-rw-r--r--rteval/__init__.py2
-rw-r--r--rteval/modules/__init__.py2
-rw-r--r--rteval/modules/measurement/sysstat.py157
-rw-r--r--rteval/rteval_text.xsl18
5 files changed, 178 insertions, 4 deletions
diff --git a/rteval-cmd b/rteval-cmd
index 4111e03..9ac2a52 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -210,7 +210,8 @@ if __name__ == '__main__':
if not config.HasSection('measurement'):
config.AppendConfig('measurement', {
- 'cyclictest' : 'module'})
+ 'cyclictest' : 'module',
+ 'sysstat' : 'module'})
# Prepare log levels before loading modules, not to have unwanted log messages
rtevcfg = config.GetSection('rteval')
diff --git a/rteval/__init__.py b/rteval/__init__.py
index 7f90b82..e1f5556 100644
--- a/rteval/__init__.py
+++ b/rteval/__init__.py
@@ -200,7 +200,7 @@ class RtEval(rtevalReport):
rpttime = currtime + report_interval
load_avg_checked = 5
while (currtime <= stoptime) and not sigint_received:
- time.sleep(1.0)
+ time.sleep(60.0)
if not measure_profile.isAlive():
stoptime = currtime
self.__logger.log(Log.WARN,
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
index 5d400fb..de70e03 100644
--- a/rteval/modules/__init__.py
+++ b/rteval/modules/__init__.py
@@ -191,7 +191,7 @@ class rtevalModulePrototype(threading.Thread):
if not self.WorkloadAlive():
self._log(Log.DEBUG, "%s workload stopped running." % self._module_type)
break
- time.sleep(1.0)
+ time.sleep(60.0)
self.__timestamps["runloop_stop"] = datetime.now()
self._log(Log.DEBUG, "stopping %s workload" % self._module_type)
else:
diff --git a/rteval/modules/measurement/sysstat.py b/rteval/modules/measurement/sysstat.py
new file mode 100644
index 0000000..033e882
--- /dev/null
+++ b/rteval/modules/measurement/sysstat.py
@@ -0,0 +1,157 @@
+#
+# sysstat.py - rteval measurment module collecting system statistics
+# using the sysstat utility
+#
+# Copyright 2013 David Sommerseth <davids@redhat.com>
+#
+# 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)
diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl
index 2613189..e99c016 100644
--- a/rteval/rteval_text.xsl
+++ b/rteval/rteval_text.xsl
@@ -183,7 +183,7 @@
<!-- -->
<!-- select="cyclictest|new_foo_section|another_section" -->
<!-- -->
- <xsl:apply-templates select="cyclictest|hwlatdetect[@format='1.0']"/>
+ <xsl:apply-templates select="cyclictest|hwlatdetect[@format='1.0']|sysstat"/>
<xsl:text>&#10;</xsl:text>
</xsl:template>
@@ -322,6 +322,22 @@
<xsl:text>us&#10;</xsl:text>
</xsl:template>
+ <!-- Format the cyclic test section of the report -->
+ <xsl:template match="/rteval/Measurements/Profile/sysstat">
+ <xsl:text> sysstat measurements&#10;</xsl:text>
+
+ <xsl:text> Started: </xsl:text>
+ <xsl:value-of select="timestamps/runloop_start"/>
+ <xsl:text>&#10;</xsl:text>
+
+ <xsl:text> Stopped: </xsl:text>
+ <xsl:value-of select="timestamps/runloop_stop"/>
+ <xsl:text>&#10;</xsl:text>
+
+ <xsl:text> Records saved: </xsl:text>
+ <xsl:value-of select="@num_entries"/>
+ <xsl:text>&#10;</xsl:text>
+ </xsl:template>
<!-- Format information about aborts - if present -->
<xsl:template match="abort_report">