# # Copyright (C) 2018 Marko Myllynen # # 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 PMDA exectop module """ # pylint: disable=invalid-name from ctypes import c_int from bcc import BPF from pcp.pmapi import pmUnits from cpmapi import PM_TYPE_U64, PM_SEM_COUNTER, PM_COUNT_ONE from cpmda import PMDA_FETCH_NOVALUES from modules.pcpbcc import PCPBCCBase # # BPF program # bpf_src = "modules/exectop.bpf" # # PCP BCC PMDA constants # MODULE = 'exectop' BASENS = 'proc.exec.count' units_count = pmUnits(0, 0, 1, 0, 0, PM_COUNT_ONE) # # PCP BCC Module # class PCPBCCModule(PCPBCCBase): """ PCP BCC exectop module """ def __init__(self, config, log, err, _): """ Constructor """ PCPBCCBase.__init__(self, MODULE, config, log, err) self.cache = {} self.log("Initialized.") def metrics(self): """ Get metric definitions """ name = BASENS self.items.append( # Name - reserved - type - semantics - units - help (name, None, PM_TYPE_U64, PM_SEM_COUNTER, units_count, 'exec'), ) return True, self.items def compile(self): """ Compile BPF """ try: self.bpf = BPF(src_file=bpf_src) execve_fnname = self.get_syscall_fnname("execve") self.bpf.attach_kretprobe(event=execve_fnname, fn_name="trace_execve") self.log("Compiled.") except Exception as error: # pylint: disable=broad-except self.bpf = None self.err(str(error)) self.err("Module NOT active!") raise def refresh(self): """ Refresh BPF data """ if self.bpf is None: return None for k, v in self.bpf["stats"].items(): key = k.comm.decode("UTF-8") self.cache[key] = v.value self.insts[key] = c_int(1) return self.insts def bpfdata(self, item, inst): """ Return BPF data as PCP metric value """ try: key = self.pmdaIndom.inst_name_lookup(inst) return [self.cache[key], 1] except Exception: # pylint: disable=broad-except return [PMDA_FETCH_NOVALUES, 0]