diff --git a/outage_detector/main.py b/outage_detector/main.py index f7b0639..27b0c45 100644 --- a/outage_detector/main.py +++ b/outage_detector/main.py @@ -69,192 +69,19 @@ def isOnline(host: str, timeout: int) -> bool: return False -def log(config: dict) -> None: +def log(host: int, timeout: int, no_stdout: bool, log_path: None | str = None) -> None: """Log the connection status of a host""" - logline = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}][{config['host']}][{'OK' if isOnline(config['host'], config['timeout']) else 'FAIL'}]\n" + logline = f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}][{host}][{'OK' if isOnline(host, timeout) else 'FAIL'}]\n" - if config['log'] != None: - with open(config['log'], 'a') as file: + if log_path is not None: + with open(log_path, 'a') as file: file.write(logline) - if config['stdout']: + if not no_stdout: print(logline) -def printHelp() -> None: - """Prints the help menu""" - - print( - """ - If no argument is passed then de defaults are assumed. - - --config Path to a config file in JSON format. - To set a command line argument, use it as a key and set its value. - Config is nor used unless explicitly set. - - --log Path to a the file where results should be appended to. - Created the file if it does not already exist. - Default: ./connection.log - - --host IP or hostname of a server to query. - Default: 1.1.1.1 - - --timeout Set the timeout in seconds to use for the connection test - Default: 2 - - --outages Print the outages to stdout. - Set the lenght in minutes where a connection loss is condidered an outage - This option can only be used with --log. - Default: 3 - - --stdout Return the resulting logline in the terminal. - Default Behaviour: Do not print to stdout. - - --help Print this menu - """ - ) - - -def loadConfig() -> tuple[dict, str]: - """Load and validate the config and return it as a dict together with the execution mode""" - - argv = sys.argv - - config: dict = {} - buffer = '' - mode = 'log' - - # parse arguments - for arg in argv[1:]: - if arg.startswith('--'): - buffer = arg.removeprefix('--') - config[buffer] = [] - else: - config[buffer].append(arg) - - # print help if requested - if 'help' in config: - printHelp() - quit() - - ## Validate Arguments ## - - # right arguments - valid_parameters = {'config', 'log', 'host', - 'timeout', 'outages', 'stdout', 'help'} - if (unknown_parameters := config.keys() - valid_parameters) != set(): - print(f"[ERROR] Unknown parameters: {unknown_parameters}") - printHelp() - quit() - - # number of arguments - maximum_arguments = { - 'config': 1, - 'log': 1, - 'host': 1, - 'timeout': 1, - 'outages': 1, - 'stdout': 0, - 'help': 0 - } - - for key in config: - if len(config[key]) > maximum_arguments[key]: - print( - f"[ERROR] Too many arguments for '{key}'. Expected 0{' or 1' if maximum_arguments[key] == 1 else ''}. Got: {len(config[key])}") - printHelp() - quit() - - # check that outages is only used with --log - if 'outages' in config: - mode = 'outages' - if config.keys() - {'outages', 'log'} != set(): - print( - f"[ERROR] --outages can only be used alone or with --log") - printHelp() - quit() - - # After that check has passed remove the list - for key in config: - config[key] = config[key][0] if len(config[key]) == 1 else None - - # set stdout - config['stdout'] = 'stdout' in config - - # if config is passed then load it - if 'config' in config: - try: - config_file = './config.json' if config['config'] == None else config['config'] - with open(config_file, 'r') as file: - # this gives the stdout toggle behaviour - config_file = json.load(file) - - # merge config_file and config - # this also subtly overrites no-stdout to whatever the config file says - for key in config_file.keys() & config.keys(): - if key == 'stdout': - continue - if config[key] == None: - config[key] = config_file[key] - - config_file.update(config) - config = config_file - - except FileNotFoundError: - print(f"[ERROR] Config file not found: {config['config']}") - printHelp() - quit() - - # load defaults, if not set - defaults = { - 'log': './connection.log', - 'host': '1.1.1.1', - 'timeout': 2, - 'outages': 3, - 'stdout': False, - 'help': None - } - for key in defaults: - if key == 'log': - if config['stdout'] and 'log' not in config: - config['log'] = None - continue - - if (key not in config) or (key in config and config[key] == None): - config[key] = defaults[key] - - # timeout - try: - config['timeout'] = int(config['timeout']) - except ValueError: - print( - f"[ERROR] Invalid type for 'timeout'. Expected int. Got: {type(config['timeout'])}") - printHelp() - quit() - - if config['timeout'] <= 0: - print(f"[ERROR] 'timeout' needs to be larger than 0") - printHelp() - quit() - - # outages - try: - config['outages'] = int(config['outages']) - except ValueError: - print( - f"[ERROR] Invalid type for 'outages'. Expected int. Got: {type(config['outages'])}") - printHelp() - quit() - - if config['outages'] < 0: - print(f"[ERROR] 'outages' needs to be larger than 0") - printHelp() - quit() - - return config, mode - - def parseArgs(args: list[str]): import argparse @@ -264,27 +91,12 @@ def parseArgs(args: list[str]): subparsers = parser.add_subparsers() - parser_outages = subparsers.add_parser( - 'outages', help='Print outages', formatter_class=argparse.ArgumentDefaultsHelpFormatter - ) - parser_outages.add_argument( - 'log_path', type=str, default='./connection.log', - help='Path to a file with connection logs.' - ) - parser_outages.add_argument( - '--time', type=int, default=3, - help='Minimum duration for a connection loss to be considered an outage.' - ) - + # Arguments for the log command parser_log = subparsers.add_parser( 'log', help='Log the connection status.', formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser_log.add_argument( - '--config', type=str, default='./config.json', - help='Path to a config file in JSON format.' - ) - parser_log.add_argument( - '--path', type=str, default='./connection.json', + '--path', type=str, default=None, help='Path to a the file where results should be appended to. Creates the file if it does not exist.' ) parser_log.add_argument( @@ -300,7 +112,21 @@ def parseArgs(args: list[str]): help='A flag that disables printing to stdout.' ) - parser.parse_args(args) + # Arguments for the outages command + parser_outages = subparsers.add_parser( + 'outages', help='Print outages', formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser_outages.add_argument( + '--log-path', type=str, default='./connection.log', + help='Path to a file with connection logs.' + ) + parser_outages.add_argument( + '--time', type=int, default=3, + help='Minimum duration for a connection loss to be considered an outage.' + ) + + print(parser.parse_args(args)) + def main(): from sys import argv