Skip to content
Snippets Groups Projects
Commit e2cd058b authored by Amit Bansod's avatar Amit Bansod
Browse files

rebase with master

parents 7d2b13b4 928aebce
No related branches found
No related tags found
1 merge request!5gim_exporter with aioredis, wip
...@@ -555,7 +555,7 @@ class GenericGimExporter: ...@@ -555,7 +555,7 @@ class GenericGimExporter:
finally: finally:
await asyncio.sleep(0.001) await asyncio.sleep(0.001)
async def heartbeat(self, initial_wait_time=300, heartbeats_connected=False): async def heartbeat(self, initial_wait_time=300, heartbeats_connected=0):
""" """
Callback to implement the heartbeat functionality. Callback to implement the heartbeat functionality.
Should be executed as loop: loop.create_task(exporter.heartbeat()) Should be executed as loop: loop.create_task(exporter.heartbeat())
... ...
......
...@@ -280,7 +280,7 @@ class GimGenericWrapper: ...@@ -280,7 +280,7 @@ class GimGenericWrapper:
while self._katcp_client.device_state_get(keep=True) != KatcpClient.DeviceStates.INITIALIZED: while self._katcp_client.device_state_get(keep=True) != KatcpClient.DeviceStates.INITIALIZED:
# Set heartbeats to disconnected # Set heartbeats to disconnected
self._exporter.heartbeats_connected = False self._exporter.heartbeats_connected = 0
# Make sure to stop also during init # Make sure to stop also during init
if self._main_thread_stop: if self._main_thread_stop:
...@@ -303,7 +303,7 @@ class GimGenericWrapper: ...@@ -303,7 +303,7 @@ class GimGenericWrapper:
await self._exporter.update_from_tasklist(self._tasklist) await self._exporter.update_from_tasklist(self._tasklist)
# Set heartbeats to connected # Set heartbeats to connected
self._exporter.heartbeats_connected = True self._exporter.heartbeats_connected = 1
self._logger_main.write_info("Init of SET Queues") self._logger_main.write_info("Init of SET Queues")
self._loop.create_task(self._exporter.redis_get_streams()) self._loop.create_task(self._exporter.redis_get_streams())
... ...
......
from enum import Enum, auto
ifconfig_example_output = """enp0s31f6: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether 00:2b:67:98:a6:5f txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 16 memory 0xe3380000-e33a0000
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 2335 bytes 435485 (435.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2335 bytes 435485 (435.4 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp0s20f3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.6 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::10cb:684c:f9e0:26ba prefixlen 64 scopeid 0x20<link>
ether c8:58:c0:2a:5b:ca txqueuelen 1000 (Ethernet)
RX packets 99897 bytes 125833503 (125.8 MB)
RX errors 0 dropped 85 overruns 0 frame 0
TX packets 41392 bytes 4859750 (4.8 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0"""
class IfconfigParser:
"""
Class providing functionality for parsing ifconfig outputs.
"""
class IfcfgType(Enum):
"""
Enum to define the ifconfig type the output belongs to.
"""
LINUX = auto()
MAC = auto()
WINDOWS = auto()
class IfcfgFieldsLinux(Enum):
"""
Keys to map the ifconfig output fields.
"""
MTU = "mtu"
INET = "inet"
INET6 = "inet6"
NETMASK = "netmask"
PREFIX_LEN = "prefixlen"
SCOPE_ID = "scopeid"
TX_QUEUE_LEN = "txqueuelen"
RX_PACKETS = "rx packets"
RX_BYTES = "rx bytes"
RX_ERRORS = "rx errors"
RX_DROPPED = "rx dropped"
RX_OVERRUNS = "rx overruns"
RX_FRAME = "rx frame"
TX_PACKETS = "tx packets"
TX_BYTES = "tx bytes"
TX_ERRORS = "tx errors"
TX_DROPPED = "tx dropped"
TX_OVERRUNS = "tx overruns"
# Key/sub-key structure to parse the linux ifconfig result by
_IFCFG_KEYS_LINUX = [
IfcfgFieldsLinux.MTU.value,
IfcfgFieldsLinux.INET.value,
IfcfgFieldsLinux.INET6.value,
IfcfgFieldsLinux.NETMASK.value,
IfcfgFieldsLinux.PREFIX_LEN.value,
IfcfgFieldsLinux.SCOPE_ID.value,
IfcfgFieldsLinux.TX_QUEUE_LEN.value,
{
IfcfgFieldsLinux.RX_PACKETS.value.split(" ")[0]: [
IfcfgFieldsLinux.RX_PACKETS.value.split(" ")[1],
IfcfgFieldsLinux.RX_BYTES.value.split(" ")[1],
]
},
{
IfcfgFieldsLinux.RX_ERRORS.value.split(" ")[0]: [
IfcfgFieldsLinux.RX_ERRORS.value.split(" ")[1],
IfcfgFieldsLinux.RX_DROPPED.value.split(" ")[1],
IfcfgFieldsLinux.RX_OVERRUNS.value.split(" ")[1],
IfcfgFieldsLinux.RX_FRAME.value.split(" ")[1],
]
},
{
IfcfgFieldsLinux.TX_PACKETS.value.split(" ")[0]: [
IfcfgFieldsLinux.TX_PACKETS.value.split(" ")[1],
IfcfgFieldsLinux.TX_BYTES.value.split(" ")[1],
]
},
{
IfcfgFieldsLinux.TX_ERRORS.value.split(" ")[0]: [
IfcfgFieldsLinux.TX_ERRORS.value.split(" ")[1],
IfcfgFieldsLinux.TX_DROPPED.value.split(" ")[1],
IfcfgFieldsLinux.TX_OVERRUNS.value.split(" ")[1],
]
},
]
def __init__(self, ifconfig_output, ifconfig_type=IfcfgType.LINUX):
"""
Parses the ifconfig output. Results is stored in devices dict.
:param ifconfig_output: Output as how it comes from the ifconfig command.
"""
self.devices = {}
# Currently only Linux supported
ifcfg_keys = self._IFCFG_KEYS_LINUX
# Interfaces are separated by double \n
for iface_output in ifconfig_output.split("\n\n"):
# First get the interface
iface = iface_output.split(":")[0]
# Add an entry per interface
self.devices[iface] = {}
res_dict_iface = self.devices[iface]
# Join lines (makes searching easier) and replace double " "
iface_output = " ".join(iface_output.split("\n")).replace(" ", " ").lower()
# Search for keys from ifconfig keys lut
for key in ifcfg_keys:
try:
# Some keys (eg. rx/tx) have kind of a key-subkey setup, this is implemented as "dict:[list]"
if isinstance(key, dict):
# dict only hold one element -> the parent key
parent_key = list(key)[0]
# Loop over sub keys
for list_entry in key[parent_key]:
# Generate resulting key (parent+sub)
key_concatenate = "{} {}".format(parent_key, list_entry)
# Get value for key
res_dict_iface[key_concatenate] = iface_output.split(key_concatenate)[1].strip().split(" ")[
0]
# Delete (key + value) from iface, to make the algorithm work
replacer = "{} {}".format(key_concatenate, res_dict_iface[key_concatenate])
iface_output = iface_output.replace(replacer, parent_key)
else:
# Normal keys can be grabbed directly
res_dict_iface[key] = iface_output.split(key)[1].strip().split(" ")[0]
except IndexError:
# Depending on the interface's state, not all keys are present
res_dict_iface[key] = None
import datetime
from fabric import ThreadingGroup, exceptions from fabric import ThreadingGroup, exceptions
from enum import Enum, auto from enum import Enum, auto
from epl.epl_networking.epl_networking_ifconfig import IfconfigParser
class SystemStatsRemoteLinux: class SystemStatsRemoteLinux:
...@@ -136,6 +139,130 @@ class SystemStatsRemoteLinux: ...@@ -136,6 +139,130 @@ class SystemStatsRemoteLinux:
self.load_5min = float(output_list[-2]) self.load_5min = float(output_list[-2])
self.load_15min = float(output_list[-1]) self.load_15min = float(output_list[-1])
class IfConfigOutput:
def __init__(self, iface, mtu, rx_pck, rx_bytes, rx_err, rx_drp, rx_ovr, tx_pck, tx_bytes, tx_err, tx_drp,
tx_ovr, rx_bytes_rate=0, rx_pck_rate=0, rx_err_rate=0, rx_drp_rate=0, rx_ovr_rate=0,
tx_bytes_rate=0, tx_pck_rate=0, tx_err_rate=0, tx_drp_rate=0, tx_ovr_rate=0, rate_in_mbytes=True):
"""
Init the ifconfig output object.
"""
self._rate_in_mbytes = rate_in_mbytes
self.iface = iface
self.mtu = mtu
self.rx_pck = rx_pck
self.rx_bytes = rx_bytes
self.rx_err = rx_err
self.rx_drp = rx_drp
self.rx_ovr = rx_ovr
self.tx_pck = tx_pck
self.tx_bytes = tx_bytes
self.tx_err = tx_err
self.tx_drp = tx_drp
self.tx_ovr = tx_ovr
# Rates
self.rx_mbytes_rate = 0
self.rx_drp_rate = 0
self.rx_ovr_rate = 0
self.rx_err_rate = 0
self.rx_pck_rate = 0
self.tx_mbytes_rate = 0
self.tx_drp_rate = 0
self.tx_ovr_rate = 0
self.tx_err_rate = 0
self.tx_pck_rate = 0
self.rx_bytes_rate_set(rx_bytes_rate)
self.rx_err_rate_set(rx_err_rate)
self.rx_drp_rate_set(rx_drp_rate)
self.rx_ovr_rate_set(rx_ovr_rate)
self.rx_pck_rate_set(rx_pck_rate)
self.tx_bytes_rate_set(tx_bytes_rate)
self.tx_err_rate_set(tx_err_rate)
self.tx_drp_rate_set(tx_drp_rate)
self.tx_ovr_rate_set(tx_ovr_rate)
self.tx_pck_rate_set(tx_pck_rate)
def rx_bytes_rate_set(self, rate):
"""
Sets the rx_rate. Based on self._rate_in_mbytes this value represents bytes or mbytes.
:param rate: The rate in bytes.
:return:
"""
self.rx_mbytes_rate = rate / 1024 / 1024 if self._rate_in_mbytes else rate
def rx_drp_rate_set(self, rate):
"""
Sets the rx_drp_rate.
:param rate: The rate value.
:return:
"""
self.rx_drp_rate = rate
def rx_ovr_rate_set(self, rate):
"""
Sets the rx_ovr_rate.
:param rate: The rate value.
:return:
"""
self.rx_ovr_rate = rate
def rx_err_rate_set(self, rate):
"""
Sets the rx_err_rate.
:param rate: The rate value.
:return:
"""
self.rx_err_rate = rate
def rx_pck_rate_set(self, rate):
"""
Sets the rx_pck_rate.
:param rate: The rate value.
:return:
"""
self.rx_pck_rate = rate
def tx_bytes_rate_set(self, tx_rate):
"""
Sets the tx_rate. Based on self._rate_in_mbytes this value represents bytes or mbytes.
:param tx_rate: The rate in bytes.
:return:
"""
self.tx_mbytes_rate = tx_rate / 1024 / 1024 if self._rate_in_mbytes else tx_rate
def tx_drp_rate_set(self, rate):
"""
Sets the tx_drp_rate.
:param rate: The rate value.
:return:
"""
self.tx_drp_rate = rate
def tx_ovr_rate_set(self, rate):
"""
Sets the tx_ovr_rate.
:param rate: The rate value.
:return:
"""
self.tx_ovr_rate = rate
def tx_err_rate_set(self, rate):
"""
Sets the tx_err_rate.
:param rate: The rate value.
:return:
"""
self.tx_err_rate = rate
def tx_pck_rate_set(self, rate):
"""
Sets the tx_pck_rate.
:param rate: The rate value.
:return:
"""
self.tx_pck_rate = rate
def __init__(self, logger, hosts, user, password="", persistent_connections=True, port=22): def __init__(self, logger, hosts, user, password="", persistent_connections=True, port=22):
""" """
Initialize the module. Initialize the module.
...@@ -168,6 +295,10 @@ class SystemStatsRemoteLinux: ...@@ -168,6 +295,10 @@ class SystemStatsRemoteLinux:
"password": self._password, "password": self._password,
}) })
# Special task related variables
# ifconfig
self._ifconfig_last = {}
def _host_string_create(self, connection): def _host_string_create(self, connection):
""" """
Creates a host string based on connection info. Creates a host string based on connection info.
...@@ -336,9 +467,10 @@ class SystemStatsRemoteLinux: ...@@ -336,9 +467,10 @@ class SystemStatsRemoteLinux:
# Create TopOutput objects list # Create TopOutput objects list
# Note: top output is `\n` separated and contains (double) spaces # Note: top output is `\n` separated and contains (double) spaces
# Note: Replace "," by "." as fractional separator
entry_outputs = [ entry_outputs = [
" ".join(ent.split()).split(" ") " ".join(ent.split()).split(" ")
for ent in con[1].stdout.strip().split('\n') for ent in con[1].stdout.replace(",", ".").strip().split('\n')
] ]
# Create objects # Create objects
...@@ -425,3 +557,103 @@ class SystemStatsRemoteLinux: ...@@ -425,3 +557,103 @@ class SystemStatsRemoteLinux:
) )
return ret_list return ret_list
def ifconfig(self, interfaces=[]):
"""
:return:
"""
# Create the command
cmd = '/usr/sbin/ifconfig'
# Execute the command
ret = self.run_command(cmd)
# List for return values
ret_list = []
# First handle `failed` items (need to be treated specially)
self._result_handle_failed(ret.failed, ret_list)
# Now loop over `succeeded` items
for con in ret.succeeded.items():
ifconfig_results = {}
# Get the output of the ifconfig command
ifconfig_output = con[1].stdout.strip()
self._logger.write_debug('ifconfig output: `{};{}`'.format(con, ifconfig_output))
# Parse the ifconfig outputs
ifconfig_parser = IfconfigParser(ifconfig_output, IfconfigParser.IfcfgType.LINUX)
for device_name, device_params in ifconfig_parser.devices.items():
ifconfig_results[device_name] = self.IfConfigOutput(iface=device_name, mtu=device_params[
IfconfigParser.IfcfgFieldsLinux.MTU.value], rx_pck=device_params[
IfconfigParser.IfcfgFieldsLinux.RX_PACKETS.value], rx_bytes=device_params[
IfconfigParser.IfcfgFieldsLinux.RX_BYTES.value], rx_err=device_params[
IfconfigParser.IfcfgFieldsLinux.RX_ERRORS.value], rx_drp=device_params[
IfconfigParser.IfcfgFieldsLinux.RX_DROPPED.value], rx_ovr=device_params[
IfconfigParser.IfcfgFieldsLinux.RX_OVERRUNS.value], tx_pck=device_params[
IfconfigParser.IfcfgFieldsLinux.TX_PACKETS.value], tx_bytes=device_params[
IfconfigParser.IfcfgFieldsLinux.TX_BYTES.value], tx_err=device_params[
IfconfigParser.IfcfgFieldsLinux.TX_ERRORS.value], tx_drp=device_params[
IfconfigParser.IfcfgFieldsLinux.TX_DROPPED.value], tx_ovr=device_params[
IfconfigParser.IfcfgFieldsLinux.TX_OVERRUNS.value])
# Calculate rates
if con[0].host in self._ifconfig_last:
history = self._ifconfig_last[con[0].host]
for device, ifconfig_history in history["data"].items():
time_delta_s = datetime.datetime.now().timestamp() - history["timestamp"]
# rx rates
ifconfig_results[device].rx_bytes_rate_set((float(ifconfig_results[device].rx_bytes) - float(
ifconfig_history.rx_bytes)) / time_delta_s)
ifconfig_results[device].rx_pck_rate_set((float(ifconfig_results[device].rx_pck) - float(
ifconfig_history.rx_pck)) / time_delta_s)
ifconfig_results[device].rx_drp_rate_set((float(ifconfig_results[device].rx_drp) - float(
ifconfig_history.rx_drp)) / time_delta_s)
ifconfig_results[device].rx_ovr_rate_set((float(ifconfig_results[device].rx_ovr) - float(
ifconfig_history.rx_ovr)) / time_delta_s)
ifconfig_results[device].rx_err_rate_set((float(ifconfig_results[device].rx_err) - float(
ifconfig_history.rx_err)) / time_delta_s)
# tx rates
ifconfig_results[device].tx_bytes_rate_set((float(ifconfig_results[device].tx_bytes) - float(
ifconfig_history.tx_bytes)) / time_delta_s)
ifconfig_results[device].tx_pck_rate_set((float(ifconfig_results[device].tx_pck) - float(
ifconfig_history.tx_pck)) / time_delta_s)
ifconfig_results[device].tx_drp_rate_set((float(ifconfig_results[device].tx_drp) - float(
ifconfig_history.tx_drp)) / time_delta_s)
ifconfig_results[device].tx_ovr_rate_set((float(ifconfig_results[device].tx_ovr) - float(
ifconfig_history.tx_ovr)) / time_delta_s)
ifconfig_results[device].tx_err_rate_set((float(ifconfig_results[device].tx_err) - float(
ifconfig_history.tx_err)) / time_delta_s)
# Save current results
self._ifconfig_last[con[0].host] = {
"timestamp": datetime.datetime.now().timestamp(),
"data": ifconfig_results
}
# Filter interfaces
if len(interfaces) == 0:
ret_output = ifconfig_results
else:
ret_output = {}
for iface in interfaces:
if iface in ifconfig_results:
ret_output[iface] = ifconfig_results[iface]
break
# Format for output is {COMMAND:[OUTPUT_ARGS]}
ret_list.append(
self.RetVal(
host=self._host_string_create(con[0]),
status=self.RetValState.OK,
output=ret_output
)
)
return ret_list
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment