diff --git a/src/aslm/log_files/log_functions.py b/src/aslm/log_files/log_functions.py index d6e9e323d..6f24e1eaa 100644 --- a/src/aslm/log_files/log_functions.py +++ b/src/aslm/log_files/log_functions.py @@ -1,24 +1,80 @@ +from email.mime import base import logging.config import logging.handlers import yaml from pathlib import Path +def update_nested_dict(d, find_func, apply_func): + """ + Loops through a nested dictionary and if find_func() conditions are met, + run apply_func on that key. + + TODO: This is highly general and doesn't belong here. + TODO: It might be nice to make this non-recursive. + + Parameters + ---------- + find_func : func + Accepts key, value pair and matches a condition based on these. Returns bool. + apply_func : func + Accepts a value returns the new value. + + Returns + ------- + d2 : dict + An version of d, updated according to the passed functions. + """ + d2 = {} + for k, v in d.items(): + if find_func(k, v): + d2[k] = apply_func(v) + else: + d2[k] = v + if isinstance(v, dict): + d2[k] = update_nested_dict(v, find_func, apply_func) + return d2 + +def find_filename(k, v): + """ + Check that we've met the condition dictionary key == 'filename' + """ + if k == 'filename': + return True + return False def log_setup(fname): + """ + Initialize a logger from a YAML file containing information in the Python logging + dictionary format + (see https://docs.python.org/3/library/logging.config.html#logging-config-dictschema). + + Parameters + ---------- + fname : str + Path to file to be loaded. Relative to the location of the folder containing this file. + """ + + # the path to fname is set relative to the location of the folder containing this file (log_functions.py) base_directory = Path(__file__).resolve().parent logging_path = Path.joinpath(base_directory, fname) + + # Function to map filename to base_directory/filename in the dictionary + def update_filename(v): + return Path.joinpath(base_directory, v) + with open(logging_path, 'r') as f: try: config_data = yaml.load(f.read(), Loader=yaml.FullLoader) - logging.config.dictConfig(config_data) # Configures our loggers from logging.yml + # Force all log files to be created relative to base_directory + config_data2 = update_nested_dict(config_data, find_filename, update_filename) + logging.config.dictConfig(config_data2) # Configures our loggers from updated logging.yml except yaml.YAMLError as yaml_error: print(yaml_error) - def main_process_listener(queue): - ''' + """ This function will listen for new logs put in queue from sub processes, it will then log via the main process. - ''' + """ while True: try: record = queue.get() diff --git a/src/aslm/log_files/logging.yml b/src/aslm/log_files/logging.yml index f35d770fa..957324c27 100644 --- a/src/aslm/log_files/logging.yml +++ b/src/aslm/log_files/logging.yml @@ -20,21 +20,21 @@ handlers: class: logging.FileHandler level: INFO formatter: base - filename: log_files/view_controller_info.log + filename: view_controller_info.log filters: [not_performance] mode: w vc_debug: class: logging.FileHandler level: DEBUG formatter: base - filename: log_files/view_controller_debug.log + filename: view_controller_debug.log filters: [not_performance] mode: w performance: class: logging.FileHandler level: DEBUG formatter: base - filename: log_files/performance.log + filename: performance.log filters: [performance_specs] mode: w loggers: diff --git a/src/aslm/log_files/model_logging.yml b/src/aslm/log_files/model_logging.yml index 61496b55b..5e43c2986 100644 --- a/src/aslm/log_files/model_logging.yml +++ b/src/aslm/log_files/model_logging.yml @@ -20,21 +20,21 @@ handlers: class: logging.FileHandler level: INFO formatter: base - filename: log_files/model_info.log + filename: model_info.log filters: [not_performance] mode: w model_debug: class: logging.FileHandler level: DEBUG formatter: base - filename: log_files/model_debug.log + filename: model_debug.log filters: [not_performance] mode: w model_performance: class: logging.FileHandler level: DEBUG formatter: base - filename: log_files/model_performance.log + filename: model_performance.log filters: [performance_specs] mode: w loggers: diff --git a/src/aslm/main.py b/src/aslm/main.py index 1e8cfd2f1..400cc6d7d 100644 --- a/src/aslm/main.py +++ b/src/aslm/main.py @@ -79,27 +79,20 @@ def main(): # Parse command line arguments parser = argparse.ArgumentParser(description='Multiscale Microscope Command Line Arguments') input_args = parser.add_argument_group('Input Arguments') - input_args.add_argument('--verbose', + input_args.add_argument('-v', '--verbose', required=False, default=False, action='store_true', help='Enables the software to operate in a verbose mode. Warning: Excessively verbose.') - input_args.add_argument('--synthetic_hardware', + input_args.add_argument('-sh', '--synthetic_hardware', required=False, default=False, action='store_true', help='Synthetic Hardware - ' 'Allows launching of the software without the physical devices attached.') - input_args.add_argument('--sh', - required=False, - default=False, - action='store_true', - help='Synthetic Hardware - ' - 'Allows launching of the software without the physical devices attached.') - - input_args.add_argument('--debug', + input_args.add_argument('-d', '--debug', required=False, default=False, action='store_true',