Initial commit

This commit is contained in:
Arseniy Kuznetsov
2021-01-02 17:07:43 +01:00
parent 329090b8a4
commit f1feace229
12 changed files with 109 additions and 48 deletions

View File

@@ -11,7 +11,7 @@
## GNU General Public License for more details. ## GNU General Public License for more details.
[Sample_RouterBoard] [SampleRouter]
enabled = False enabled = False
hostname = localhost hostname = localhost
@@ -33,4 +33,4 @@
monitor = True monitor = True
route = True route = True
wireless = True wireless = True
caps_man = True capsman = True

View File

@@ -11,6 +11,8 @@
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details. ## GNU General Public License for more details.
from mktxp.utils.utils import parse_uptime
from mktxp.cli.config.config import MKTXPConfigKeys
from mktxp.collectors.base_collector import BaseCollector from mktxp.collectors.base_collector import BaseCollector
from mktxp.router_metric import RouterMetric from mktxp.router_metric import RouterMetric
@@ -20,14 +22,54 @@ class CapsmanCollector(BaseCollector):
''' '''
@staticmethod @staticmethod
def collect(router_metric): def collect(router_metric):
resource_labels = ['uptime', 'version', 'free-memory', 'total-memory', remote_caps_labels = ['identity', 'version', 'base_mac', 'board', 'base_mac']
'cpu', 'cpu-count', 'cpu-frequency', 'cpu-load', remote_caps_records = router_metric.capsman_remote_caps_records(remote_caps_labels)
'free-hdd-space', 'total-hdd-space', if not remote_caps_records:
'architecture-name', 'board-name']
resource_records = router_metric.resource_records(resource_labels)
if not resource_records:
return return
resource_metrics = BaseCollector.info_collector('resource', 'resource', resource_records, resource_labels) remote_caps_metrics = BaseCollector.info_collector('capsman_remote_caps', 'CAPsMAN remote caps', remote_caps_records, remote_caps_labels)
yield resource_metrics yield remote_caps_metrics
registration_labels = ['interface', 'ssid', 'mac_address', 'tx_rate', 'rx_rate', 'rx_signal', 'uptime', 'bytes']
registration_records = router_metric.capsman_registration_table_records(registration_labels)
if not registration_records:
return
# calculate number of registrations per interface
registration_per_interface = {}
for registration_record in registration_records:
registration_per_interface[registration_record['interface']] = registration_per_interface.get(registration_record['interface'], 0) + 1
# compile registrations-per-interface records
registration_per_interface_records = [{ MKTXPConfigKeys.ROUTERBOARD_NAME: router_metric.router_id[MKTXPConfigKeys.ROUTERBOARD_NAME],
MKTXPConfigKeys.ROUTERBOARD_ADDRESS: router_metric.router_id[MKTXPConfigKeys.ROUTERBOARD_ADDRESS],
'interface': key, 'count': value} for key, value in registration_per_interface.items()]
# yield registrations-per-interface metrics
registration_per_interface_metrics = BaseCollector.gauge_collector('capsman_registrations_count', 'Number of active registration per CAPsMAN interface', registration_per_interface_records, 'count', ['interface'])
yield registration_per_interface_metrics
# translate / trim / augment registration records
dhcp_lease_labels = ['mac_address', 'host_name', 'comment']
dhcp_lease_records = router_metric.dhcp_lease_records(dhcp_lease_labels)
for registration_record in registration_records:
dhcp_lease_record = next((dhcp_lease_record for dhcp_lease_record in dhcp_lease_records if dhcp_lease_record['mac_address']==registration_record['mac_address']))
if dhcp_lease_record:
registration_record['name'] = dhcp_lease_record.get('comment', dhcp_lease_record.get('host_name', dhcp_lease_record.get('mac_address')))
else:
registration_record['name'] = registration_record['mac_address']
# split out tx/rx bytes
registration_record['tx_bytes'] = registration_record['bytes'].split(',')[0]
registration_record['rx_bytes'] = registration_record['bytes'].split(',')[1]
del registration_record['bytes']
tx_byte_metrics = BaseCollector.counter_collector('capsman_traffic_tx_bytes', 'Number of sent packet bytes', registration_records, 'tx_bytes', ['name'])
yield tx_byte_metrics
rx_byte_metrics = BaseCollector.counter_collector('capsman_traffic_rx_bytes', 'Number of received packet bytes', registration_records, 'rx_bytes', ['name'])
yield rx_byte_metrics
registration_metrics = BaseCollector.info_collector('capsman_registered_devices', 'Registered devices info',
registration_records, ['name', 'rx_signal', 'ssid', 'tx_rate', 'rx_rate', 'interface', 'mac_address', 'uptime'])
yield registration_metrics

View File

@@ -25,9 +25,9 @@ class HealthCollector(BaseCollector):
if not health_records: if not health_records:
return return
voltage_metrics = BaseCollector.gauge_collector('routerboard_voltage', 'Supplied routerboard voltage', health_records, 'voltage') voltage_metrics = BaseCollector.gauge_collector('system_routerboard_voltage', 'Supplied routerboard voltage', health_records, 'voltage')
yield voltage_metrics yield voltage_metrics
temperature_metrics = BaseCollector.gauge_collector('routerboard_temperature', ' Routerboard current temperature', health_records, 'temperature') temperature_metrics = BaseCollector.gauge_collector('system_routerboard_temperature', ' Routerboard current temperature', health_records, 'temperature')
yield temperature_metrics yield temperature_metrics

View File

@@ -25,6 +25,6 @@ class IdentityCollector(BaseCollector):
if not identity_records: if not identity_records:
return return
identity_metrics = BaseCollector.info_collector('identity', 'System identity', identity_records, identity_labels) identity_metrics = BaseCollector.info_collector('system_identity', 'System identity', identity_records, identity_labels)
yield identity_metrics yield identity_metrics

View File

@@ -25,28 +25,28 @@ class InterfaceCollector(BaseCollector):
if not interface_traffic_records: if not interface_traffic_records:
return return
rx_byte_metric = BaseCollector.counter_collector('rx_byte', 'Number of received bytes', interface_traffic_records, 'rx_byte', ['name']) rx_byte_metric = BaseCollector.counter_collector('interface_rx_byte', 'Number of received bytes', interface_traffic_records, 'rx_byte', ['name'])
yield rx_byte_metric yield rx_byte_metric
tx_byte_metric = BaseCollector.counter_collector('tx_byte', 'Number of transmitted bytes', interface_traffic_records, 'tx_byte', ['name']) tx_byte_metric = BaseCollector.counter_collector('interface_tx_byte', 'Number of transmitted bytes', interface_traffic_records, 'tx_byte', ['name'])
yield tx_byte_metric yield tx_byte_metric
rx_packet_metric = BaseCollector.counter_collector('rx_packet', 'Number of packets received', interface_traffic_records, 'rx_packet', ['name']) rx_packet_metric = BaseCollector.counter_collector('interface_rx_packet', 'Number of packets received', interface_traffic_records, 'rx_packet', ['name'])
yield rx_packet_metric yield rx_packet_metric
tx_packet_metric = BaseCollector.counter_collector('tx_packet', 'Number of transmitted packets', interface_traffic_records, 'tx_packet', ['name']) tx_packet_metric = BaseCollector.counter_collector('interface_tx_packet', 'Number of transmitted packets', interface_traffic_records, 'tx_packet', ['name'])
yield tx_packet_metric yield tx_packet_metric
rx_error_metric = BaseCollector.counter_collector('rx_error', 'Number of packets received with an error', interface_traffic_records, 'rx_error', ['name']) rx_error_metric = BaseCollector.counter_collector('interface_rx_error', 'Number of packets received with an error', interface_traffic_records, 'rx_error', ['name'])
yield rx_error_metric yield rx_error_metric
tx_error_metric = BaseCollector.counter_collector('tx_error', 'Number of packets transmitted with an error', interface_traffic_records, 'tx_error', ['name']) tx_error_metric = BaseCollector.counter_collector('interface_tx_error', 'Number of packets transmitted with an error', interface_traffic_records, 'tx_error', ['name'])
yield tx_error_metric yield tx_error_metric
rx_drop_metric = BaseCollector.counter_collector('rx_drop', 'Number of received packets being dropped', interface_traffic_records, 'rx_drop', ['name']) rx_drop_metric = BaseCollector.counter_collector('interface_rx_drop', 'Number of received packets being dropped', interface_traffic_records, 'rx_drop', ['name'])
yield rx_drop_metric yield rx_drop_metric
tx_drop_metric = BaseCollector.counter_collector('tx_drop', 'Number of transmitted packets being dropped', interface_traffic_records, 'tx_drop', ['name']) tx_drop_metric = BaseCollector.counter_collector('interface_tx_drop', 'Number of transmitted packets being dropped', interface_traffic_records, 'tx_drop', ['name'])
yield tx_drop_metric yield tx_drop_metric

View File

@@ -33,16 +33,16 @@ class MonitorCollector(BaseCollector):
if value: if value:
monitor_record[monitor_label] = MonitorCollector._translated_values(monitor_label, value) monitor_record[monitor_label] = MonitorCollector._translated_values(monitor_label, value)
monitor_status_metrics = BaseCollector.gauge_collector('status', 'Current interface link status', monitor_records, 'status', ['name']) monitor_status_metrics = BaseCollector.gauge_collector('interface_status', 'Current interface link status', monitor_records, 'status', ['name'])
yield monitor_status_metrics yield monitor_status_metrics
# limit records according to the relevant metrics # limit records according to the relevant metrics
rate_records = [monitor_record for monitor_record in monitor_records if monitor_record.get('rate', None)] rate_records = [monitor_record for monitor_record in monitor_records if monitor_record.get('rate', None)]
monitor_rates_metrics = BaseCollector.gauge_collector('rate', 'Actual interface connection data rate', rate_records, 'rate', ['name']) monitor_rates_metrics = BaseCollector.gauge_collector('interface_rate', 'Actual interface connection data rate', rate_records, 'rate', ['name'])
yield monitor_rates_metrics yield monitor_rates_metrics
full_duplex_records = [monitor_record for monitor_record in monitor_records if monitor_record.get('full_duplex', None)] full_duplex_records = [monitor_record for monitor_record in monitor_records if monitor_record.get('full_duplex', None)]
monitor_rates_metrics = BaseCollector.gauge_collector('full_duplex', 'Full duplex data transmission', full_duplex_records, 'full_duplex', ['name']) monitor_rates_metrics = BaseCollector.gauge_collector('interface_full_duplex', 'Full duplex data transmission', full_duplex_records, 'full_duplex', ['name'])
yield monitor_rates_metrics yield monitor_rates_metrics

View File

@@ -12,7 +12,7 @@
## GNU General Public License for more details. ## GNU General Public License for more details.
import re import re
from datetime import timedelta from mktxp.utils.utils import parse_uptime
from mktxp.collectors.base_collector import BaseCollector from mktxp.collectors.base_collector import BaseCollector
from mktxp.router_metric import RouterMetric from mktxp.router_metric import RouterMetric
@@ -38,28 +38,28 @@ class SystemResourceCollector(BaseCollector):
if value: if value:
resource_record[translated_field] = SystemResourceCollector._translated_values(translated_field, value) resource_record[translated_field] = SystemResourceCollector._translated_values(translated_field, value)
uptime_metrics = BaseCollector.gauge_collector('uptime', 'Time interval since boot-up', resource_records, 'uptime', ['version', 'board_name', 'cpu', 'architecture_name']) uptime_metrics = BaseCollector.gauge_collector('system_uptime', 'Time interval since boot-up', resource_records, 'uptime', ['version', 'board_name', 'cpu', 'architecture_name'])
yield uptime_metrics yield uptime_metrics
free_memory_metrics = BaseCollector.gauge_collector('free_memory', 'Unused amount of RAM', resource_records, 'free_memory', ['version', 'board_name', 'cpu', 'architecture_name']) free_memory_metrics = BaseCollector.gauge_collector('system_free_memory', 'Unused amount of RAM', resource_records, 'free_memory', ['version', 'board_name', 'cpu', 'architecture_name'])
yield free_memory_metrics yield free_memory_metrics
total_memory_metrics = BaseCollector.gauge_collector('total_memory', 'Amount of installed RAM', resource_records, 'total_memory', ['version', 'board_name', 'cpu', 'architecture_name']) total_memory_metrics = BaseCollector.gauge_collector('system_total_memory', 'Amount of installed RAM', resource_records, 'total_memory', ['version', 'board_name', 'cpu', 'architecture_name'])
yield total_memory_metrics yield total_memory_metrics
free_hdd_metrics = BaseCollector.gauge_collector('free_hdd_space', 'Free space on hard drive or NAND', resource_records, 'free_hdd_space', ['version', 'board_name', 'cpu', 'architecture_name']) free_hdd_metrics = BaseCollector.gauge_collector('system_free_hdd_space', 'Free space on hard drive or NAND', resource_records, 'free_hdd_space', ['version', 'board_name', 'cpu', 'architecture_name'])
yield free_hdd_metrics yield free_hdd_metrics
total_hdd_metrics = BaseCollector.gauge_collector('total_hdd_space', 'Size of the hard drive or NAND', resource_records, 'total_hdd_space', ['version', 'board_name', 'cpu', 'architecture_name']) total_hdd_metrics = BaseCollector.gauge_collector('system_total_hdd_space', 'Size of the hard drive or NAND', resource_records, 'total_hdd_space', ['version', 'board_name', 'cpu', 'architecture_name'])
yield total_hdd_metrics yield total_hdd_metrics
cpu_load_metrics = BaseCollector.gauge_collector('cpu_load', 'Percentage of used CPU resources', resource_records, 'cpu_load', ['version', 'board_name', 'cpu', 'architecture_name']) cpu_load_metrics = BaseCollector.gauge_collector('system_cpu_load', 'Percentage of used CPU resources', resource_records, 'cpu_load', ['version', 'board_name', 'cpu', 'architecture_name'])
yield cpu_load_metrics yield cpu_load_metrics
cpu_count_metrics = BaseCollector.gauge_collector('cpu_count', 'Number of CPUs present on the system', resource_records, 'cpu_count', ['version', 'board_name', 'cpu', 'architecture_name']) cpu_count_metrics = BaseCollector.gauge_collector('system_cpu_count', 'Number of CPUs present on the system', resource_records, 'cpu_count', ['version', 'board_name', 'cpu', 'architecture_name'])
yield cpu_count_metrics yield cpu_count_metrics
cpu_frequency_metrics = BaseCollector.gauge_collector('cpu_frequency', 'Current CPU frequency', resource_records, 'cpu_frequency', ['version', 'board_name', 'cpu', 'architecture_name']) cpu_frequency_metrics = BaseCollector.gauge_collector('system_cpu_frequency', 'Current CPU frequency', resource_records, 'cpu_frequency', ['version', 'board_name', 'cpu', 'architecture_name'])
yield cpu_frequency_metrics yield cpu_frequency_metrics
@@ -67,11 +67,6 @@ class SystemResourceCollector(BaseCollector):
@staticmethod @staticmethod
def _translated_values(translated_field, value): def _translated_values(translated_field, value):
return { return {
'uptime': lambda value: SystemResourceCollector._parse_uptime(value) 'uptime': lambda value: parse_uptime(value)
}[translated_field](value) }[translated_field](value)
@staticmethod
def _parse_uptime(time):
time_dict = re.match(r'((?P<weeks>\d+)w)?((?P<days>\d+)d)?((?P<hours>\d+)h)?((?P<minutes>\d+)m)?((?P<seconds>\d+)s)?', time).groupdict()
return timedelta(**{key: int(value) for key, value in time_dict.items() if value}).total_seconds()

View File

@@ -32,7 +32,7 @@ class RouteCollector(BaseCollector):
MKTXPConfigKeys.ROUTERBOARD_ADDRESS: router_metric.router_id[MKTXPConfigKeys.ROUTERBOARD_ADDRESS], MKTXPConfigKeys.ROUTERBOARD_ADDRESS: router_metric.router_id[MKTXPConfigKeys.ROUTERBOARD_ADDRESS],
'count': total_routes 'count': total_routes
}] }]
total_routes_metrics = BaseCollector.gauge_collector('total_routes', 'Overall number of routes in RIB', total_routes_records, 'count') total_routes_metrics = BaseCollector.gauge_collector('routes_total_routes', 'Overall number of routes in RIB', total_routes_records, 'count')
yield total_routes_metrics yield total_routes_metrics

View File

@@ -30,9 +30,9 @@ class WLANCollector(BaseCollector):
tx_ccq_records = [monitor_record for monitor_record in monitor_records if monitor_record.get('overall_tx_ccq')] tx_ccq_records = [monitor_record for monitor_record in monitor_records if monitor_record.get('overall_tx_ccq')]
if noise_floor_records: if noise_floor_records:
noise_floor_metrics = BaseCollector.gauge_collector('noise_floor', 'Noise floor threshold', noise_floor_records, 'noise_floor', ['channel']) noise_floor_metrics = BaseCollector.gauge_collector('wlan_noise_floor', 'Noise floor threshold', noise_floor_records, 'noise_floor', ['channel'])
yield noise_floor_metrics yield noise_floor_metrics
if tx_ccq_records: if tx_ccq_records:
overall_tx_ccq_metrics = BaseCollector.gauge_collector('overall_tx_ccq', ' Client Connection Quality for transmitting', tx_ccq_records, 'overall_tx_ccq', ['channel']) overall_tx_ccq_metrics = BaseCollector.gauge_collector('wlan_overall_tx_ccq', ' Client Connection Quality for transmitting', tx_ccq_records, 'overall_tx_ccq', ['channel'])
yield overall_tx_ccq_metrics yield overall_tx_ccq_metrics

View File

@@ -20,6 +20,7 @@ from mktxp.collectors.pool_collector import PoolCollector
from mktxp.collectors.resource_collector import SystemResourceCollector from mktxp.collectors.resource_collector import SystemResourceCollector
from mktxp.collectors.route_collector import RouteCollector from mktxp.collectors.route_collector import RouteCollector
from mktxp.collectors.wlan_collector import WLANCollector from mktxp.collectors.wlan_collector import WLANCollector
from mktxp.collectors.capsman_collector import CapsmanCollector
class CollectorsHandler: class CollectorsHandler:
''' MKTXP Collectors Handler ''' MKTXP Collectors Handler
@@ -51,7 +52,6 @@ class CollectorsHandler:
if router_metric.router_entry.wireless: if router_metric.router_entry.wireless:
yield from WLANCollector.collect(router_metric) yield from WLANCollector.collect(router_metric)
if router_metric.router_entry.capsman:
yield from CapsmanCollector.collect(router_metric)

View File

@@ -111,7 +111,30 @@ class RouterMetric:
except Exception as exc: except Exception as exc:
print(f'Error getting pool active routes info from router{self.router_name}@{self.router_entry.hostname}: {exc}') print(f'Error getting pool active routes info from router{self.router_name}@{self.router_entry.hostname}: {exc}')
return None return None
def wireless_registration_table_records(self, registration_table_labels = []):
try:
registration_table_records = self.api_connection.router_api().get_resource('/interface/wireless/registration-table').get()
return self._trimmed_records(registration_table_records, registration_table_labels)
except Exception as exc:
print(f'Error getting wireless registration table info from router{self.router_name}@{self.router_entry.hostname}: {exc}')
return None
def capsman_remote_caps_records(self, remote_caps_labels = []):
try:
remote_caps_records = self.api_connection.router_api().get_resource('/caps-man/remote-cap').get()
return self._trimmed_records(remote_caps_records, remote_caps_labels)
except Exception as exc:
print(f'Error getting caps-man remote caps info from router{self.router_name}@{self.router_entry.hostname}: {exc}')
return None
def capsman_registration_table_records(self, registration_table_labels = []):
try:
registration_table_records = self.api_connection.router_api().get_resource('/caps-man/registration-table').get()
return self._trimmed_records(registration_table_records, registration_table_labels)
except Exception as exc:
print(f'Error getting caps-man registration table info from router{self.router_name}@{self.router_entry.hostname}: {exc}')
return None
# Helpers # Helpers
def _trimmed_records(self, router_records, metric_labels): def _trimmed_records(self, router_records, metric_labels):

View File

@@ -12,6 +12,7 @@
## GNU General Public License for more details. ## GNU General Public License for more details.
import os, sys, shlex, tempfile, shutil, re import os, sys, shlex, tempfile, shutil, re
from datetime import timedelta
import subprocess, hashlib import subprocess, hashlib
import keyring, getpass import keyring, getpass
from collections import Iterable from collections import Iterable
@@ -67,9 +68,9 @@ def get_last_digit(str_to_search):
else: else:
return -1 return -1
def encfs_version(): def parse_uptime(time):
cmd = 'encfs --version' time_dict = re.match(r'((?P<weeks>\d+)w)?((?P<days>\d+)d)?((?P<hours>\d+)h)?((?P<minutes>\d+)m)?((?P<seconds>\d+)s)?', time).groupdict()
return get_last_digit_from_shell_cmd(cmd) return timedelta(**{key: int(value) for key, value in time_dict.items() if value}).total_seconds()
class FSHelper: class FSHelper: