Server IP : 184.154.167.98 / Your IP : 3.142.198.250 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/modules/ |
Upload File : |
# # Copyright (C) 2020 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. # """ PCP BCC PMDA netproc module """ import ctypes as ct from collections import namedtuple import os from bcc import BPF from pcp.pmapi import pmUnits from cpmapi import ( PM_TYPE_U64, PM_COUNT_ONE, PM_SPACE_BYTE, PM_SEM_COUNTER, ) from cpmda import PMDA_FETCH_NOVALUES from modules.pcpbcc import PCPBCCBase # # BPF program # bpf_src = "modules/netproc.bpf" # # PCP BCC PMDA constants # MODULE = "netproc" BASENS = "proc.net." units_bytes = pmUnits(1, 0, 0, PM_SPACE_BYTE, 0, 0) units_count = pmUnits(0, 0, 1, 0, 0, PM_COUNT_ONE) units_none = pmUnits(0, 0, 0, 0, 0, 0) # use tuple here instead of a dict or class to access the fields by index in the bpfdata method # do not change the first 8 items Netstats = namedtuple( "Netstats", [ "tcp_send_calls", "tcp_send_bytes", "tcp_recv_calls", "tcp_recv_bytes", "udp_send_calls", "udp_send_bytes", "udp_recv_calls", "udp_recv_bytes", "instance_name", ], ) # # PCP BCC Module # class PCPBCCModule(PCPBCCBase): """ PCP BCC netproc module """ def __init__(self, config, log, err): """ Constructor """ PCPBCCBase.__init__(self, MODULE, config, log, err) self.remove_stopped_processes = True for opt in self.config.options(MODULE): if opt == "remove_stopped_processes": self.remove_stopped_processes = self.config.getboolean(MODULE, opt) self.netstats_cache = {} self.insts = {} self.log("Initialized.") def metrics(self): """ Get metric definitions """ name = BASENS self.items = ( # Name - reserved - type - semantics - units - help # note: ordering of these metrics must match ordering of the Netstats named tuple ( name + "tcp.send.calls", None, PM_TYPE_U64, PM_SEM_COUNTER, units_count, "number of TCP send calls (tcp_sendmsg())", ), ( name + "tcp.send.bytes", None, PM_TYPE_U64, PM_SEM_COUNTER, units_bytes, "amount of bytes requested to be sent", ), ( name + "tcp.recv.calls", None, PM_TYPE_U64, PM_SEM_COUNTER, units_count, "number of TCP recv calls (tcp_recvmsg()/tcp_cleanup_rbuf())", ), ( name + "tcp.recv.bytes", None, PM_TYPE_U64, PM_SEM_COUNTER, units_bytes, "amount of bytes received", ), ( name + "udp.send.calls", None, PM_TYPE_U64, PM_SEM_COUNTER, units_count, "number of UDP send calls (udp_sendmsg())", ), ( name + "udp.send.bytes", None, PM_TYPE_U64, PM_SEM_COUNTER, units_bytes, "amount of bytes requested to be sent", ), ( name + "udp.recv.calls", None, PM_TYPE_U64, PM_SEM_COUNTER, units_count, "number of UDP recv calls (udp_recvmsg()/skb_consume_udp())", ), ( name + "udp.recv.bytes", None, PM_TYPE_U64, PM_SEM_COUNTER, units_bytes, "amount of bytes received", ), ) return True, self.items def compile(self): """ Compile BPF """ try: self.bpf = BPF(src_file=bpf_src) 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 netstats_per_pid = self.bpf["netstats_per_pid"] for pid_ct, cur_netstat in netstats_per_pid.items(): pid = pid_ct.value prev_netstat = self.netstats_cache.get(pid, None) if not prev_netstat: instance_name = self.get_instance_name_for_pid(pid) prev_netstat = Netstats(0, 0, 0, 0, 0, 0, 0, 0, instance_name) netstat = Netstats( tcp_send_calls=prev_netstat.tcp_send_calls + cur_netstat.tcp_send_calls, tcp_send_bytes=prev_netstat.tcp_send_bytes + cur_netstat.tcp_send_bytes, tcp_recv_calls=prev_netstat.tcp_recv_calls + cur_netstat.tcp_recv_calls, tcp_recv_bytes=prev_netstat.tcp_recv_bytes + cur_netstat.tcp_recv_bytes, udp_send_calls=prev_netstat.udp_send_calls + cur_netstat.udp_send_calls, udp_send_bytes=prev_netstat.udp_send_bytes + cur_netstat.udp_send_bytes, udp_recv_calls=prev_netstat.udp_recv_calls + cur_netstat.udp_recv_calls, udp_recv_bytes=prev_netstat.udp_recv_bytes + cur_netstat.udp_recv_bytes, instance_name=prev_netstat.instance_name, ) self.netstats_cache[pid] = netstat self.insts[netstat.instance_name] = ct.c_int(pid) netstats_per_pid.clear() # remove stopped processes if self.remove_stopped_processes: current_pids = frozenset( [int(dirname) for dirname in os.listdir("/proc") if dirname.isdigit()] ) cached_pids = frozenset(self.netstats_cache.keys()) stopped_pids = cached_pids - current_pids for pid in stopped_pids: netstat = self.netstats_cache[pid] del self.insts[netstat.instance_name] del self.netstats_cache[pid] return self.insts def bpfdata(self, item, inst): """ Return BPF data as PCP metric value """ try: value = self.netstats_cache[inst][item] return [value, 1] except Exception: # pylint: disable=broad-except return [PMDA_FETCH_NOVALUES, 0]