From db3bd565625436324811e3c8c361c67621bf4803 Mon Sep 17 00:00:00 2001 From: Markus Wieczorek <wieczoma@gitlab.informatik.hu-berlin.de> Date: Wed, 11 Mar 2020 16:03:28 +0100 Subject: [PATCH] added log_analyzer --- src/test/log_analyzer/log_analyzer.py | 172 ++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 src/test/log_analyzer/log_analyzer.py diff --git a/src/test/log_analyzer/log_analyzer.py b/src/test/log_analyzer/log_analyzer.py new file mode 100644 index 0000000..20bfdd2 --- /dev/null +++ b/src/test/log_analyzer/log_analyzer.py @@ -0,0 +1,172 @@ +import glob +import logging +import argparse +from configobj import ConfigObj +from file_read_backwards import FileReadBackwards +from decimal import Decimal +from logging.handlers import TimedRotatingFileHandler + + +def setup_logging(): + """ + Sets up logging so that log files are rotated daily. + :return: nothing + """ + log_handler = TimedRotatingFileHandler("log_analyzer.log", when="midnight") + log_formatter = logging.Formatter('%(asctime)s '':: %(levelname)s '':: %(message)s') + log_handler.setFormatter(log_formatter) + logger = logging.getLogger() + logger.addHandler(log_handler) + logger.setLevel(logging.INFO) + + +def setup_argparse(): + + """ + Sets up argparse so that testcase and log file location are required parameters + :return: parser object + """ + + parser = argparse.ArgumentParser(description="Was weiss ich...") + parser.add_argument("-t", type=str, required=True, help="testcase location relative to repo location") + parser.add_argument("-l", type=str, required=True, help="log file location relative to repo location") + return parser.parse_args() + + +def get_testcases(path): + + """ + :param path: path passed as argument + :return: returns a list of *.ini files located in all subdirs + """ + testcases = [f for f in glob.glob(path + "**/*.ini", recursive=True)] + + return testcases + + +def get_config(config_path): + + """ + :param config_path: needs to be passes as argument + :return: returns a config object + + time = config['time'] + obj1 = config['objectId1'] + obj2 = config['objectId2'] + rangeleftborder = config['rangeLeftBorder'] + rangerightborder = config['rangeRightBorder'] + timeout = config['timeout'] + + """ + + return ConfigObj(config_path) + + +def check_logfile_for_collision(logfile): + + """ + Reads logfile from end to start and checks if last line contains a collision + :param logfile: + :return: True if collision was found + """ + + with FileReadBackwards(logfile) as file: + for line in file: + if ("Collision!") in line: + return True + + +def get_log(log_dir, logname, config): + + """ + Currently does conclusiveness checks + ToDo: Move these checks to separate function + ToDo: Distanz checken + :param log_dir: location of log files + :param logname: corresponds to the name of the testcase file + :param config: config object where safety_distances are stored + :return: currently nothing. + """ + + logfiles = [f for f in glob.glob(log_dir + logname + "lm.log")] + + for l in logfiles: + logging.debug("Matching logs %s", l) + location = l.find("ACT") + + if check_logfile_for_collision(l): + logging.info("Testcase %s: red", l[location: location + 5]) + logging.warning("Found collision for testcase %s", l[location:location + 5]) + break + + safety_distance = get_safety_distance(l) + + if not check_safety_distance(safety_distance, config): + logging.info("Testcase %s yellow", l[location:location + 5]) + + else: # if we are here, we did there was no collision and safety_distance is within limits + if not check_distance(config,l): + logging.info("Testcase %s: red", l[location: location + 5]) + logging.warning("Found distance does not match! %s", l[location:location + 5]) + else: + logging.info("testcase %s: green", l[location: location + 5]) + + +def get_safety_distance(logfile): + """ + Gets safety_distance from a logfile and returns it + :param logfile: + :return: safety_distance as string + """ + counter = 0 + with FileReadBackwards(logfile) as file: + for line in file: + counter += 1 + if counter == 3: + return line[29:] + + +def check_distance(config, logfile): + counter = 0 + with FileReadBackwards(logfile) as file: + for line in file: + counter += 1 + if counter == 2: + distance = line[50:] + if Decimal(distance)<=Decimal(config['rangeLeftBorder']) or Decimal(distance)>=Decimal(config['rangeRightBorder']): + return False + else: + return True + + +def check_safety_distance(safety_distance, config): + """ + Checks if safety_distance is within the specified range + :param safety_distance: safety_distance found in log files + :param config: safety_distance as defined in the config files + :return: False if these do not match, True otherwise + """ + if Decimal(safety_distance) <= Decimal(config['rangeLeftBorder']) or Decimal(safety_distance) >= Decimal(config['rangeRightBorder']): + return False + else: + return True + + +def main(): + args = setup_argparse() + setup_logging() + + # example run as follows: + # python main.py -t config/ -l log/ + + testcases = get_testcases(args.t) + + for testcase in testcases: + config = get_config(testcase) + location = testcase.find("ACT") + get_log(args.l, testcase[location:location + 8] + "0_", config) + logging.debug("got config for %s", testcase) + + +if __name__ == '__main__': + main() \ No newline at end of file -- GitLab