diff --git a/resources/logging.py b/resources/logging.py index 1003982d82c730f625c43853c727d2b1e895291a..3dfe0a7e6cb41afe717441f8c16861c07920eb6f 100644 --- a/resources/logging.py +++ b/resources/logging.py @@ -14,6 +14,10 @@ Note: Standard log priority is "NOTSET" > "DEBUG" > "INFO" > "WARNING" > "ERROR" import logging.config, os +# Statement to help library determine how to run logging. +graph_library_logger = True + + def get_logger(caller): """ Returns an instance of the logger. Always pass the __name__ attribute. @@ -21,101 +25,118 @@ def get_logger(caller): :param caller: __name__ attribute of caller. :return: Instance of logger, associated with caller's __name__. """ + # Initialize logger. + _initialize_logger_settings() + + # Return logger instance, using passed name. return logging.getLogger(caller) -# Find project_dir logging path. -project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -log_dir = os.path.join(project_dir, 'resources/logs') -if not os.path.exists(log_dir): - print('Creating logging folders.') - os.makedirs(log_dir) +def _initialize_logger_settings(debug=False): + """ + Create log directories (if not found) and initialized logging settings. + :param debug: Boolean to indicate if test log messages should also be displayed after initialization. + """ + # Determine logging path. + project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + log_dir = os.path.join(project_dir, 'resources/logs') + # Check if logging path exists. + if not os.path.exists(log_dir): + print('Creating logging folders at "{0}".'.format(log_dir)) + os.makedirs(log_dir) -# Dictionary style logging options. -LOGGING = { - 'version': 1, - 'formatters': { - # Minimal logging. Only includes message. - 'minimal': { - 'format': '%(message)s', - }, - # Simple logging. Includes message type and actual message. - 'simple': { - 'format': '[%(levelname)s] [%(filename)s %(lineno)d]: %(message)s', - }, - # Basic logging. Includes date, message type, file originated, and actual message. - 'standard': { - 'format': '%(asctime)s [%(levelname)s] [%(filename)s %(lineno)d]: %(message)s', - }, - # Verbose logging. Includes standard plus the process number and thread id. - 'verbose': { - 'format': '%(asctime)s [%(levelname)s] [%(filename)s %(lineno)d] || %(process)d %(thread)d || %(message)s', - }, - }, - 'handlers': { - # Sends log message to the void. May be useful for debugging. - 'null': { - 'class': 'logging.NullHandler', - }, - # To console. - 'console': { - 'level': 'INFO', - 'class': 'logging.StreamHandler', - 'formatter': 'simple', - }, - # Debug Level - To file. - 'file_debug': { - 'level': 'DEBUG', - 'class': 'logging.handlers.RotatingFileHandler', - 'filename': os.path.join(log_dir, 'debug.log'), - 'maxBytes': 1024*1024*10, - 'backupCount': 10, - 'formatter': 'standard', - }, - # Info Level - To file. - 'file_info': { - 'level': 'INFO', - 'class': 'logging.handlers.RotatingFileHandler', - 'filename': os.path.join(log_dir, 'info.log'), - 'maxBytes': 1024*1024*10, - 'backupCount': 10, - 'formatter': 'standard', + # Load dictionary of settings into logger. + logging.config.dictConfig(_create_logging_dict(log_dir)) + + # Optionally test that logging is working as expected. + if debug: + logger = get_logger(__name__) + logger.info('Logging initialized.') + logger.debug('Logging directory: {0}'.format(log_dir)) + + +def _create_logging_dict(log_directory): + """ + Creates dictionary-styled logging options. + :param log_directory: Directory to use for saving logs. + :return: Dictionary of logging options. + """ + # Dictionary style logging options. + return { + 'version': 1, + 'formatters': { + # Minimal logging. Only includes message. + 'minimal': { + 'format': '%(message)s', + }, + # Simple logging. Includes message type and actual message. + 'simple': { + 'format': '[%(levelname)s] [%(filename)s %(lineno)d]: %(message)s', + }, + # Basic logging. Includes date, message type, file originated, and actual message. + 'standard': { + 'format': '%(asctime)s [%(levelname)s] [%(filename)s %(lineno)d]: %(message)s', + }, + # Verbose logging. Includes standard plus the process number and thread id. + 'verbose': { + 'format': '%(asctime)s [%(levelname)s] [%(filename)s %(lineno)d] || %(process)d %(thread)d || %(message)s', + }, }, - # Warn Level - To file. - 'file_warn': { - 'level': 'WARNING', - 'class': 'logging.handlers.RotatingFileHandler', - 'filename': os.path.join(log_dir, 'warn.log'), - 'maxBytes': 1024*1024*10, - 'backupCount': 10, - 'formatter': 'verbose', + 'handlers': { + # Sends log message to the void. May be useful for debugging. + 'null': { + 'class': 'logging.NullHandler', + }, + # To console. + 'console': { + 'level': 'INFO', + 'class': 'logging.StreamHandler', + 'formatter': 'simple', + }, + # Debug Level - To file. + 'file_debug': { + 'level': 'DEBUG', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(log_directory, 'debug.log'), + 'maxBytes': 1024*1024*10, + 'backupCount': 10, + 'formatter': 'standard', + }, + # Info Level - To file. + 'file_info': { + 'level': 'INFO', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(log_directory, 'info.log'), + 'maxBytes': 1024*1024*10, + 'backupCount': 10, + 'formatter': 'standard', + }, + # Warn Level - To file. + 'file_warn': { + 'level': 'WARNING', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(log_directory, 'warn.log'), + 'maxBytes': 1024*1024*10, + 'backupCount': 10, + 'formatter': 'verbose', + }, + # Error Level - To file. + 'file_error': { + 'level': 'ERROR', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(log_directory, 'error.log'), + 'maxBytes': 1024*1024*10, + 'backupCount': 10, + 'formatter': 'verbose', + }, }, - # Error Level - To file. - 'file_error': { - 'level': 'ERROR', - 'class': 'logging.handlers.RotatingFileHandler', - 'filename': os.path.join(log_dir, 'error.log'), - 'maxBytes': 1024*1024*10, - 'backupCount': 10, - 'formatter': 'verbose', + 'loggers': { + # All basic logging. + '': { + 'handlers': ['console', 'file_debug', 'file_info', 'file_warn', 'file_error'], + 'level': 'DEBUG', + 'propagate': False, + } }, - }, - 'loggers': { - # All basic logging. - '': { - 'handlers': ['console', 'file_debug', 'file_info', 'file_warn', 'file_error'], - 'level': 'DEBUG', - 'propagate': False, - } - }, -} - - -# Load dictionary of settings into logger. -logging.config.dictConfig(LOGGING) - -# Test logging. -logger = get_logger(__name__) -logger.info('Logging initialized.') -logger.debug('Logging directory: {0}'.format(log_dir)) + }