src.co_tools.get_logger
1import logging 2import os 3 4LOGGER_DIR_PATH = "../results/co_logs" # path to log directory 5co_computation_id = os.environ.get("CO_COMPUTATION_ID") 6aws_batch_job_id = os.getenv("AWS_BATCH_JOB_ID") 7# name for the log file in ../results/co_logs 8LOGGER_FILE_NAME = co_computation_id if co_computation_id else aws_batch_job_id 9ENV_LEVEL = os.environ.get("CO_LOG_LEVEL") 10DEFAULT_LEVEL = "WARNING" if not ENV_LEVEL else ENV_LEVEL.upper() 11 12""" 13Benefit to this logger is that it adds to each log entry a timestamp, 14project name, name of .py file, line number and the log level. 15[%(asctime)s - %(name)s - %(filename)s:%(lineno)s - %(levelname)s] %(message)s" 16How to use: 17import the logger -> from get_logger import LOGGER 18LOGGER.{mode}("string to log") 19How to modify log level: 20set the environment variable CO_LOG_LEVEL in the run script 21ex. export CO_LOG_LEVEL="INFO" 22""" 23 24 25def get_logger_for_string(*, logger_name: str, level: str): 26 """ 27 :description: A mapping function from strings to logging levels. 28 :param logger_name: Name of the logger handle e.g. `stream_handle`. 29 :param level: The string describing the logging level to set. 30 :return: in [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR]. 31 DEBUG: Detailed information, typically of interest only when diagnosing 32 problems. 33 INFO: Confirmation that things are working as expected. 34 WARNING: An indication that something unexpected happened, or indicative of 35 some problem in the near future (e.g. 'disk space low'). The software is 36 still working as expected. 37 ERROR: Due to a more serious problem, the software has not been able to 38 perform some function. 39 CRITICAL: A serious error, indicating that the program itself may be unable 40 to continue running. 41 The default level is WARNING, which means that only events of this level 42 and above will be tracked, unless the logging package is configured to 43 do otherwise. 44 """ 45 if level == "DEBUG": 46 return logging.DEBUG 47 elif level == "INFO": 48 return logging.INFO 49 elif level == "WARNING": 50 return logging.WARNING 51 elif level == "ERROR": 52 return logging.ERROR 53 elif level == "CRITICAL": 54 return logging.CRITICAL 55 else: 56 raise Exception( 57 f"{logger_name} logging level is not one of [DEBUG, INFO, " 58 + "WARNING, ERROR, CRITICAL]" 59 ) 60 61 62def generate_logger( 63 *, 64 name: str = LOGGER_FILE_NAME, 65 logging_level: str = DEFAULT_LEVEL, 66 format_string: str = ( 67 "[%(asctime)s - %(name)s - %(filename)s:%(lineno)s - %(levelname)s] " 68 + "%(message)s" 69 ), 70): 71 """ 72 :description: Creates a logger as desired for the global namespace without 73 polluting the global namespace. 74 :param name: The name of the logger. 75 :param logging_level: The logging level to record to the logging file. 76 :param format_string: A string to be passed to Python's logger generator 77 facility to format logging output. 78 :returns: A usable and proper Python logger. 79 """ 80 81 logging_level = get_logger_for_string(logger_name=name, level=logging_level) 82 83 logger = logging.getLogger(name) 84 logger.setLevel(logging_level) 85 86 # create console handler with a higher log level 87 88 os.makedirs(LOGGER_DIR_PATH, exist_ok=True) 89 90 file_handle = logging.FileHandler(f"{LOGGER_DIR_PATH}/{name}.log") 91 file_handle.setLevel(logging_level) 92 console_handler = logging.StreamHandler() 93 console_handler.setLevel(logging.ERROR) 94 # create formatter and add it to the handlers 95 log_format = logging.Formatter(format_string, "%Y-%m-%d %H:%M:%S") 96 file_handle.setFormatter(log_format) 97 98 logger.addHandler(file_handle) 99 logger.addHandler(console_handler) 100 101 return logger 102 103 104LOGGER = None 105 106if not LOGGER: 107 LOGGER = generate_logger()
Benefit to this logger is that it adds to each log entry a timestamp, project name, name of .py file, line number and the log level. [%(asctime)s - %(name)s - %(filename)s:%(lineno)s - %(levelname)s] %(message)s" How to use: import the logger -> from get_logger import LOGGER LOGGER.{mode}("string to log") How to modify log level: set the environment variable CO_LOG_LEVEL in the run script ex. export CO_LOG_LEVEL="INFO"
26def get_logger_for_string(*, logger_name: str, level: str): 27 """ 28 :description: A mapping function from strings to logging levels. 29 :param logger_name: Name of the logger handle e.g. `stream_handle`. 30 :param level: The string describing the logging level to set. 31 :return: in [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR]. 32 DEBUG: Detailed information, typically of interest only when diagnosing 33 problems. 34 INFO: Confirmation that things are working as expected. 35 WARNING: An indication that something unexpected happened, or indicative of 36 some problem in the near future (e.g. 'disk space low'). The software is 37 still working as expected. 38 ERROR: Due to a more serious problem, the software has not been able to 39 perform some function. 40 CRITICAL: A serious error, indicating that the program itself may be unable 41 to continue running. 42 The default level is WARNING, which means that only events of this level 43 and above will be tracked, unless the logging package is configured to 44 do otherwise. 45 """ 46 if level == "DEBUG": 47 return logging.DEBUG 48 elif level == "INFO": 49 return logging.INFO 50 elif level == "WARNING": 51 return logging.WARNING 52 elif level == "ERROR": 53 return logging.ERROR 54 elif level == "CRITICAL": 55 return logging.CRITICAL 56 else: 57 raise Exception( 58 f"{logger_name} logging level is not one of [DEBUG, INFO, " 59 + "WARNING, ERROR, CRITICAL]" 60 )
:description: A mapping function from strings to logging levels.
Parameters
- logger_name: Name of the logger handle e.g.
stream_handle
. - level: The string describing the logging level to set.
Returns
in [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR]. DEBUG: Detailed information, typically of interest only when diagnosing problems. INFO: Confirmation that things are working as expected. WARNING: An indication that something unexpected happened, or indicative of some problem in the near future (e.g. 'disk space low'). The software is still working as expected. ERROR: Due to a more serious problem, the software has not been able to perform some function. CRITICAL: A serious error, indicating that the program itself may be unable to continue running. The default level is WARNING, which means that only events of this level and above will be tracked, unless the logging package is configured to do otherwise.
63def generate_logger( 64 *, 65 name: str = LOGGER_FILE_NAME, 66 logging_level: str = DEFAULT_LEVEL, 67 format_string: str = ( 68 "[%(asctime)s - %(name)s - %(filename)s:%(lineno)s - %(levelname)s] " 69 + "%(message)s" 70 ), 71): 72 """ 73 :description: Creates a logger as desired for the global namespace without 74 polluting the global namespace. 75 :param name: The name of the logger. 76 :param logging_level: The logging level to record to the logging file. 77 :param format_string: A string to be passed to Python's logger generator 78 facility to format logging output. 79 :returns: A usable and proper Python logger. 80 """ 81 82 logging_level = get_logger_for_string(logger_name=name, level=logging_level) 83 84 logger = logging.getLogger(name) 85 logger.setLevel(logging_level) 86 87 # create console handler with a higher log level 88 89 os.makedirs(LOGGER_DIR_PATH, exist_ok=True) 90 91 file_handle = logging.FileHandler(f"{LOGGER_DIR_PATH}/{name}.log") 92 file_handle.setLevel(logging_level) 93 console_handler = logging.StreamHandler() 94 console_handler.setLevel(logging.ERROR) 95 # create formatter and add it to the handlers 96 log_format = logging.Formatter(format_string, "%Y-%m-%d %H:%M:%S") 97 file_handle.setFormatter(log_format) 98 99 logger.addHandler(file_handle) 100 logger.addHandler(console_handler) 101 102 return logger
:description: Creates a logger as desired for the global namespace without polluting the global namespace.
Parameters
- name: The name of the logger.
- logging_level: The logging level to record to the logging file.
- format_string: A string to be passed to Python's logger generator facility to format logging output. :returns: A usable and proper Python logger.