From daa2be6d556b8a137ef143bcb46b9668b89a24aa Mon Sep 17 00:00:00 2001 From: Toby Date: Wed, 20 Sep 2023 00:21:50 +0200 Subject: [PATCH] create monitor v2 --- monitor2.py | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100755 monitor2.py diff --git a/monitor2.py b/monitor2.py new file mode 100755 index 0000000..94e30fe --- /dev/null +++ b/monitor2.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 + +import time +import paramiko +import threading +import yaml + +out_buf = [] + +def string_to_float(data): + return float(data.strip().split(' ', 2)[0].strip()) + +def parse_top_string(data): + rows = data.splitlines() + + load = rows[0].split('load average: ', 2)[1] + + cpu_data = rows[1].split(':', 2)[1].strip().split(',') + cpu_percent = 100.0 - float(cpu_data[3].strip().split(' ', 2)[0].strip()) - float(cpu_data[7].strip().split(' ', 2)[0].strip()) + if (cpu_percent < 0): + cpu_percent = 0 + + ram_unit, ram_data = rows[2].split(':', 2) + ram_factor = 1 + if ram_unit[0] == 'K': + ram_factor = 1024 * 1024 + elif ram_unit[0] == 'M': + ram_factor = 1024 + elif ram_unit[0] == 'G': + ram_factor = 1 + ram_data = ram_data.strip().split(',') + ram_total = float(ram_data[0].strip().split(' ', 2)[0].strip()) / ram_factor + ram_free = float(ram_data[1].strip().split(' ', 2)[0].strip()) / ram_factor + + return load, cpu_percent, ram_total, ram_free + +class Host(threading.Thread): + def __init__(self, host, port, host_length, idx): + threading.Thread.__init__(self) + self.host = host + self.port = port + self.host_length = host_length + self.idx = idx + self.status = 'none' + self.done = False + + def render_status(self): + if self.status == 'none': + return '[ .. ] ' + elif self.status == 'ok': + return '[ \033[92mok\033[0m ] ' + elif self.status == 'fail': + return '[\033[91mfail\033[0m] ' + + def render_top(self): + if self.status != 'ok': + return '' + + stdin, stdout, stderr = self.client.exec_command('top -bn1 | grep "^top\\|^%Cpu\\|^.iB Mem"') + stdin.close() + + data = stdout.read().decode('utf-8').strip() + self.client.close() + + load, cpu_percent, ram_total, ram_free = parse_top_string(data) + ram_used = ram_total - ram_free + + return load + ' (' + '{:3.1f}'.format(cpu_percent).rjust(5) + '%) ' + '{:3.1f}'.format(ram_used).rjust(5) + ' / ' + '{:3.1f}'.format(ram_total).rjust(5) + ' GiB (' + '{:3.1f}'.format(ram_used / ram_total * 100).rjust(5) + '%)' + + def render_row(self): + return self.render_status() + self.host.ljust(self.host_length + 3) + self.render_top() + + def run(self): + try: + self.status = 'none' + out_buf[self.idx] = self.render_row() + self.client = paramiko.SSHClient() + self.client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy()) + self.client.connect(self.host, port = self.port, username = 'root', timeout = 1) + self.status = 'ok' + out_buf[self.idx] = self.render_row() + except Exception as e: + #print(e) + self.status = 'fail' + out_buf[self.idx] = self.render_row() + self.done = True + +def read_config(): + with open('config.yaml', 'r') as stream: + return yaml.safe_load(stream) + +def main(): + config = read_config() + hosts = [] + + host_length = 0 + for host in config['hosts']: + if len(host['host']) > host_length: + host_length = len(host['host']) + + print('Host'.center(7 + host_length + 3) + 'Load'.center(25) + ' ' + 'Ram Usage'.center(26)) + + config_hosts = config['hosts'] + config_hosts.sort(key=lambda x: x['host']) + + for i, host in enumerate(config_hosts): + for user_name, user_data in host['users'].items(): + if user_name != 'root': + continue + host_keys = [] + if 'groups' in user_data.keys(): + for group in user_data['groups']: + if group not in config['groups'].keys(): + continue + for key_name in config['groups'][group]: + host_keys.append(config['keys'][key_name]) + if 'keys' in user_data.keys(): + for key_name in user_data['keys']: + if key_name not in config['keys'].keys(): + continue + host_keys.append(config['keys'][key_name]) + host_keys = list(set(host_keys)) # Filter duplicates + if not host_keys: + continue + if not 'port' in host: + host['port'] = 22 + out_buf.append('') + hosts.append(Host(host['host'], host['port'] or 22, host_length, i)) + + for host in hosts: + host.start() + + end = False + first = True + + while True: + screen = [] + for row in out_buf: + screen.append(row) + + for host in hosts: + if not host.done: + break + end = True + + if first: + first = False + else: + print('\033[' + str(len(screen)) + 'F', end = '') + + print('\n'.join(screen)) + + if end: + break + + time.sleep(0.1) + +if __name__ == '__main__': + main()