diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmdas/simple/pmdasimple.python | |
download | pcp-debian.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmdas/simple/pmdasimple.python')
-rw-r--r-- | src/pmdas/simple/pmdasimple.python | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/src/pmdas/simple/pmdasimple.python b/src/pmdas/simple/pmdasimple.python new file mode 100644 index 0000000..5d0295a --- /dev/null +++ b/src/pmdas/simple/pmdasimple.python @@ -0,0 +1,244 @@ +''' +Python implementation of the "simple" Performance Metrics Domain Agent. +''' +# +# Copyright (c) 2013 Red Hat. +# +# 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. +# + +import os +import time +import ctypes +from ctypes import c_int, POINTER, cast +import cpmapi as c_api +from pcp.pmda import PMDA, pmdaMetric, pmdaIndom, pmdaInstid +from pcp.pmapi import pmUnits, pmContext as PCP + +class SimplePMDA(PMDA): + ''' + A simple Performance Metrics Domain Agent with very simple metrics. + Install it and make basic use of it, as follows: + + # $PCP_PMDAS_DIR/simple/Install + [select python option] + $ pminfo -fmdtT simple + + Then experiment with the simple.conf file (see simple.now metrics). + ''' + + # simple.color instance domain + red = 0 + green = 100 + blue = 200 + colors = [pmdaInstid(0, 'red'), + pmdaInstid(1, 'green'), + pmdaInstid(2, 'blue')] + + # simple.now instance domain + configfile = '' + timeslices = {} + times = () + + # simple.numfetch properties + numfetch = 0 + oldfetch = -1 + + + def simple_instance(self, serial): + ''' Called once per "instance request" PDU ''' + # self.log("instance update for %d" % serial) + if (serial == 1): + self.simple_timenow_check() + + + def simple_fetch(self): + ''' Called once per "fetch" PDU, before callbacks ''' + self.numfetch += 1 + self.simple_timenow_check() + + def simple_fetch_color_callback(self, item, inst): + ''' + Returns a list of value,status (single pair) for color cluster + Helper for the fetch callback + ''' + if (item == 0): + if (inst != c_api.PM_IN_NULL): + return [c_api.PM_ERR_INST, 0] + return [self.numfetch, 1] + elif (item == 1): + if (inst == 0): + self.red = (self.red + 1) % 255 + return [self.red, 1] + elif (inst == 1): + self.green = (self.green + 1) % 255 + return [self.green, 1] + elif (inst == 2): + self.blue = (self.blue + 1) % 255 + return [self.blue, 1] + else: + return [c_api.PM_ERR_INST, 0] + else: + return [c_api.PM_ERR_PMID, 0] + + def simple_fetch_times_callback(self, item, inst): + ''' + Returns a list of value,status (single pair) for times cluster + Helper for the fetch callback + ''' + if (inst != c_api.PM_IN_NULL): + return [c_api.PM_ERR_INST, 0] + if (self.oldfetch < self.numfetch): # get current values, if needed + self.times = os.times() + self.oldfetch = self.numfetch + if (item == 2): + return [self.times[0], 1] + elif (item == 3): + return [self.times[1], 1] + return [c_api.PM_ERR_PMID, 0] + + def simple_fetch_now_callback(self, item, inst): + ''' + Returns a list of value,status (single pair) for "now" cluster + Helper for the fetch callback + ''' + if (item == 4): + voidp = self.inst_lookup(self.now_indom, inst) + if (voidp == None): + return [c_api.PM_ERR_INST, 0] + valuep = cast(voidp, POINTER(c_int)) + return [valuep.contents.value, 1] + return [c_api.PM_ERR_PMID, 0] + + def simple_fetch_callback(self, cluster, item, inst): + ''' + Main fetch callback, defers to helpers for each cluster. + Returns a list of value,status (single pair) for requested pmid/inst + ''' + # self.log("fetch callback for %d.%d[%d]" % (cluster, item, inst)) + if (cluster == 0): + return self.simple_fetch_color_callback(item, inst) + elif (cluster == 1): + return self.simple_fetch_times_callback(item, inst) + elif (cluster == 2): + return self.simple_fetch_now_callback(item, inst) + return [c_api.PM_ERR_PMID, 0] + + + def simple_store_count_callback(self, val): + ''' Helper for the store callback, handles simple.numfetch ''' + sts = 0 + if (val < 0): + sts = c_api.PM_ERR_SIGN + val = 0 + self.numfetch = val + return sts + + def simple_store_color_callback(self, val, inst): + ''' Helper for the store callback, handles simple.color ''' + sts = 0 + if (val < 0): + sts = c_api.PM_ERR_SIGN + val = 0 + elif (val > 255): + sts = c_api.PM_ERR_CONV + val = 255 + + if (inst == 0): + self.red = val + elif (inst == 1): + self.green = val + elif (inst == 2): + self.blue = val + else: + sts = c_api.PM_ERR_INST + return sts + + def simple_store_callback(self, cluster, item, inst, val): + ''' + Store callback, executed when a request to write to a metric happens + Defers to helpers for each storable metric. Returns a single value. + ''' + if (cluster == 0): + if (item == 0): + return self.simple_store_count_callback(val) + elif (item == 1): + return self.simple_store_color_callback(val, inst) + else: + return c_api.PM_ERR_PMID + elif ((cluster == 1 and (item == 2 or item == 3)) + or (cluster == 2 and item == 4)): + return c_api.PM_ERR_PERMISSION + return c_api.PM_ERR_PMID + + + def simple_timenow_check(self): + ''' + Read our configuration file and update instance domain + ''' + self.timeslices.clear() + try: + cfg = open(self.configfile) + fields = time.localtime() + values = {'sec': c_int(fields[5]), + 'min': c_int(fields[4]), + 'hour': c_int(fields[3])} + config = cfg.readline().strip() + for key in config.split(','): + if (key != '' and values[key] != None): + self.timeslices[key] = values[key] + finally: + cfg.close() + self.replace_indom(self.now_indom, self.timeslices) + + + def __init__(self, name, domain): + PMDA.__init__(self, name, domain) + + self.configfile = PCP.pmGetConfig('PCP_PMDAS_DIR') + self.configfile += '/' + name + '/' + name + '.conf' + + self.connect_pmcd(); + + self.color_indom = self.indom(0) + self.add_indom(pmdaIndom(self.color_indom, self.colors)) + + self.now_indom = self.indom(1) + self.add_indom(pmdaIndom(self.now_indom, self.timeslices)) + + self.add_metric(name + '.numfetch', pmdaMetric(self.pmid(0, 0), + c_api.PM_TYPE_U32, c_api.PM_INDOM_NULL, c_api.PM_SEM_INSTANT, + pmUnits(0, 0, 0, 0, 0, 0))) + self.add_metric(name + '.color', pmdaMetric(self.pmid(0, 1), + c_api.PM_TYPE_32, self.color_indom, c_api.PM_SEM_INSTANT, + pmUnits(0, 0, 0, 0, 0, 0))) + self.add_metric(name + '.time.user', pmdaMetric(self.pmid(1, 2), + c_api.PM_TYPE_DOUBLE, c_api.PM_INDOM_NULL, c_api.PM_SEM_COUNTER, + pmUnits(0, 1, 0, 0, c_api.PM_TIME_SEC, 0))) + self.add_metric(name + '.time.sys', pmdaMetric(self.pmid(1, 3), + c_api.PM_TYPE_DOUBLE, c_api.PM_INDOM_NULL, c_api.PM_SEM_COUNTER, + pmUnits(0, 1, 0, 0, c_api.PM_TIME_SEC, 0))) + self.add_metric(name + '.now', pmdaMetric(self.pmid(2, 4), + c_api.PM_TYPE_U32, self.now_indom, c_api.PM_SEM_INSTANT, + pmUnits(0, 0, 0, 0, 0, 0))) + + self.set_fetch(self.simple_fetch) + self.set_instance(self.simple_instance) + self.set_fetch_callback(self.simple_fetch_callback) + self.set_store_callback(self.simple_store_callback) + self.set_user(PCP.pmGetConfig('PCP_USER')) + self.simple_timenow_check() + + +if __name__ == '__main__': + + SimplePMDA('simple', 253).run() + |