Server IP : 184.154.167.98 / Your IP : 3.142.55.138 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 7.2.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/libexec/pcp/pmdas/bcc/ |
Upload File : |
#!/usr/bin/pmpython # # Copyright (C) 2017-2019 Marko Myllynen <myllynen@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. # """ PCP BCC Performance Metrics Domain Agent """ try: import configparser except ImportError: import ConfigParser as configparser import importlib import traceback import fnmatch import atexit import sys import os from collections import OrderedDict from pcp.pmapi import pmContext as PCP from pcp.pmda import PMDA, pmdaInstid, pmdaIndom, pmdaMetric from cpmapi import PM_INDOM_NULL, PM_ERR_VALUE, PM_ERR_BADSTORE, PM_LABEL_CLUSTER, PM_LABEL_INDOM # Module references CACHED = 0 CONFIG = 1 MODULE = 2 CLUSTER = 3 PREFIX = 4 METRICS = 5 HELPERS = 6 COMPILE = 7 REFRESH = 8 BPFDATA = 9 CLEANUP = 10 INDOM = 11 INSTS = 12 LABEL_INDOM = 13 LABEL_CLUSTER = 14 LABEL_INSTANCE = 15 STORE = 16 FREEMEM = 17 class BCCPMDA(PMDA): """ PCP BCC PMDA """ def __init__(self, name, domain): """ Constructor """ PMDA.__init__(self, name, domain) # See Install self.log("Initializing, currently in 'notready' state.") self.fail_fatal = True self.modules = OrderedDict() self.clusters = OrderedDict() self.indoms = {} self.prefix = "bcc." self.proc_helper = None self.proc_refresh = 0 self.read_config_file() self.connect_pmcd() self.init_modules() self.register_metrics() self.register_helpers() self.compile_modules() self.free_memory() self.set_refresh(self.bcc_refresh) self.set_fetch_callback(self.bcc_fetch_callback) self.set_label(self.bcc_label) self.set_label_callback(self.bcc_label_callback) self.set_store_callback(self.bcc_store_callback) self.pmda_ready() if not os.environ.get('PCP_PYTHON_DOMAIN') and not os.environ.get('PCP_PYTHON_PMNS'): self.log("Ready to process requests.") @atexit.register def cleanup(): # pylint: disable=unused-variable """ Clean up """ if not os.environ.get('PCP_PYTHON_DOMAIN') and not os.environ.get('PCP_PYTHON_PMNS'): self.log("Cleaning up modules:") for module in self.modules: self.log(module) self.modules[module][CLEANUP]() self.log("Modules cleaned up.") # pylint: disable=too-many-branches def read_config_file(self): """ Read configuration file """ conffile = PCP.pmGetConfig('PCP_PMDAS_DIR') conffile += '/' + self.read_name() + '/' + self.read_name() + '.conf' if not os.path.isfile(conffile): self.err("Configuration file %s not found, aborting." % conffile) sys.exit(1) # Python < 3.2 compat if sys.version_info[0] >= 3 and sys.version_info[1] >= 2: config = configparser.ConfigParser() else: config = configparser.SafeConfigParser() try: config.read(conffile) except Exception as error: # pylint: disable=broad-except self.err(str(error)) sys.exit(1) if config.has_section('pmda'): for opt in config.options('pmda'): if opt == 'module_failure_fatal': self.fail_fatal = config.getboolean('pmda', opt) elif opt == 'modules': if config.get('pmda', opt): for module in config.get('pmda', opt).split(","): self.modules[module] = {} elif opt == 'prefix': self.prefix = config.get('pmda', opt) elif opt == 'process_refresh': self.proc_refresh = int(config.get('pmda', opt)) else: self.err("Invalid directive '%s' in %s, aborting." % (opt, conffile)) sys.exit(1) else: self.err("No [pmda] section found, aborting.") sys.exit(1) if not self.modules: self.err("No modules enabled, aborting.") sys.exit(1) self.log("Enabled modules:") self.log(str([str(module) for module in self.modules.keys()])) self.log("Configuring modules:") for module in self.modules: self.log(module) self.read_module_config(config, module) self.log("Modules configured.") def read_module_config(self, config, module): """ Read common module configuration """ if config.has_section(module): self.modules[module][CONFIG] = config for opt in config.options(module): if opt == 'module': self.modules[module][MODULE] = config.get(module, opt) if opt == 'cluster': try: self.modules[module][CLUSTER] = int(config.get(module, opt)) except ValueError: self.err("Integer expected for 'cluster', aborting.") sys.exit(1) if opt == 'prefix': self.modules[module][PREFIX] = config.get(module, opt) if opt == 'pmda_indom_cache': self.modules[module][CACHED] = config.getboolean(module, opt) else: self.err("No [%s] section found, aborting." % module) sys.exit(1) if MODULE not in self.modules[module] or CLUSTER not in self.modules[module]: self.err("Both 'module' and 'cluster' are mandatory, aborting.") sys.exit(1) if PREFIX not in self.modules[module]: self.modules[module][PREFIX] = self.prefix if CACHED not in self.modules[module]: self.modules[module][CACHED] = True def init_modules(self): """ Initialize modules """ self.log("Initializing modules:") # For packaging, allow both .python and .py suffixed files cwd = os.getcwd() pmdadir = PCP.pmGetConfig('PCP_PMDASADM_DIR') + '/' + self.read_name() for root, _, filenames in os.walk(pmdadir): os.chdir(root) for filename in fnmatch.filter(filenames, '*.python'): if filename in ('pmdabcc.python', 'domain.h.python', 'pmns.python'): continue pyf = filename[:-4] if not os.path.exists(pyf): os.symlink(filename, pyf) os.chdir(pmdadir) os.chdir(cwd) import pmdautil # pylint: disable=import-outside-toplevel self.proc_helper = pmdautil.ProcMon(self.log, self.err) for module in self.modules: self.log(module) try: mod = importlib.import_module('modules.%s' % self.modules[module][MODULE]) except ImportError as error: self.err(str(error)) self.err(traceback.format_exc()) self.err("Module %s not found, aborting." % module) sys.exit(1) try: obj = mod.PCPBCCModule(self.modules[module][CONFIG], self.log, self.err, self.proc_refresh) except TypeError: # Compat for older modules, will be removed in the future obj = mod.PCPBCCModule(self.modules[module][CONFIG], self.log, self.err) self.modules[module][METRICS] = obj.metrics self.modules[module][HELPERS] = obj.helpers self.modules[module][COMPILE] = obj.compile self.modules[module][FREEMEM] = obj.free_memory self.modules[module][REFRESH] = obj.refresh self.modules[module][BPFDATA] = obj.bpfdata self.modules[module][CLEANUP] = obj.cleanup self.modules[module][LABEL_CLUSTER] = obj.label_cluster self.modules[module][LABEL_INDOM] = obj.label_indom self.modules[module][LABEL_INSTANCE] = obj.label_instance self.modules[module][STORE] = obj.store self.proc_helper.add_module(module, obj) self.log("Modules initialized.") def register_metrics(self): """ Register metrics """ self.log("Registering metrics:") for module in self.modules: self.log(module) cluster = self.modules[module][CLUSTER] indom, metrics = self.modules[module][METRICS]() caching = {} if self.modules[module][CACHED] else [] self.modules[module][INDOM] = PM_INDOM_NULL if indom: self.modules[module][INDOM] = self.indom(cluster) self.modules[module][INSTS] = pmdaIndom(self.modules[module][INDOM], caching) self.add_indom(self.modules[module][INSTS]) for item, _ in enumerate(metrics): self.add_metric(self.modules[module][PREFIX] + metrics[item][0], pmdaMetric(self.pmid(cluster, item), metrics[item][2], self.modules[module][INDOM], metrics[item][3], metrics[item][4]), metrics[item][5], metrics[item][5]) self.indoms[self.modules[module][INDOM]] = module self.clusters[cluster] = module self.log("Metrics registered.") def register_helpers(self): """ Register helper function references """ self.log("Registering helpers:") for module in self.modules: if self.modules[module][INDOM] != PM_INDOM_NULL: self.log(module) self.modules[module][HELPERS](self.modules[module][INSTS]) self.log("Helpers registered.") def compile_modules(self): """ Compile modules """ if not os.environ.get('PCP_PYTHON_DOMAIN') and not os.environ.get('PCP_PYTHON_PMNS'): self.log("Compiling modules:") for module in self.modules: self.log(module) try: self.modules[module][COMPILE]() except Exception: # pylint: disable=broad-except if self.fail_fatal: self.err("Failed to compile module " + module + ", aborting.") sys.exit(1) self.log("Modules compiled.") self.proc_helper.enable_proc_refresh(self.proc_refresh) def free_memory(self): """ Free memory of compilation of modules """ if not os.environ.get('PCP_PYTHON_DOMAIN') and not os.environ.get('PCP_PYTHON_PMNS'): self.log("Freeing memory:") for module in self.modules: self.log(module) try: self.modules[module][FREEMEM]() except Exception: # pylint: disable=broad-except if self.fail_fatal: self.err("Failed to free memory of " + module + ", aborting.") sys.exit(1) self.log("Memory freed.") def bcc_refresh(self, cluster): """ Refresh """ module = self.clusters[cluster] insts = {} try: insts = self.modules[module][REFRESH]() except Exception as error: # pylint: disable=broad-except self.err(str(error)) self.err(traceback.format_exc()) if self.modules[module][INDOM] != PM_INDOM_NULL: if not self.modules[module][CACHED]: insts_array = [] if insts: for name, i in insts.items(): insts_array.append(pmdaInstid(i, name)) insts = insts_array self.modules[module][INSTS].set_instances(self.modules[module][INDOM], insts) self.replace_indom(self.modules[module][INDOM], insts) def bcc_fetch_callback(self, cluster, item, inst): """ Fetch callback """ module = self.clusters[cluster] try: return self.modules[module][BPFDATA](item, inst) except Exception as error: # pylint: disable=broad-except self.err(str(error)) self.err(traceback.format_exc()) return [PM_ERR_VALUE, 0] def bcc_label(self, ident, label_type): """ Cluster and instance domain labels """ if label_type == PM_LABEL_CLUSTER: module = self.clusters[ident] return self.modules[module][LABEL_CLUSTER]() if label_type == PM_LABEL_INDOM: module = self.indoms[ident] return self.modules[module][LABEL_INDOM]() return '{}' def bcc_label_callback(self, indom, inst): """ Instance labels """ module = self.indoms[indom] return self.modules[module][LABEL_INSTANCE](inst) def bcc_store_callback(self, cluster, item, inst, val): """ Store callback """ module = self.clusters[cluster] try: return self.modules[module][STORE](item, inst, val) except Exception as error: # pylint: disable=broad-except self.err(str(error)) self.err(traceback.format_exc()) return PM_ERR_BADSTORE if __name__ == '__main__': BCCPMDA('bcc', 149).run()