From acd92b3e50b6bd05dcce0419436b58076c14058c Mon Sep 17 00:00:00 2001 From: 2Shirt <2xShirt@gmail.com> Date: Sun, 7 Jul 2019 22:09:22 -0600 Subject: [PATCH] Added logging functions * Logging is always initialized if importing the whole package * Support switching to DEBUG mode * Support changing the log dir (and optionally log name) --- scripts/wk/__init__.py | 5 ++ scripts/wk/cfg/__init__.py | 2 +- scripts/wk/cfg/{logging.py => log.py} | 8 +-- scripts/wk/log.py | 88 +++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 6 deletions(-) rename scripts/wk/cfg/{logging.py => log.py} (77%) create mode 100644 scripts/wk/log.py diff --git a/scripts/wk/__init__.py b/scripts/wk/__init__.py index 4a9a7586..5df657c4 100644 --- a/scripts/wk/__init__.py +++ b/scripts/wk/__init__.py @@ -8,11 +8,13 @@ from wk import exe from wk import hw from wk import io from wk import kit +from wk import log from wk import net from wk import os from wk import std from wk import sw + # Check env if sys.version_info < (3, 5): # Unsupported @@ -27,6 +29,9 @@ if sys.version_info < (3, 7): **sys.version_info, )) +# Init +log.start() + if __name__ == '__main__': print("This file is not meant to be called directly.") diff --git a/scripts/wk/cfg/__init__.py b/scripts/wk/cfg/__init__.py index f89a13bf..74adea8e 100644 --- a/scripts/wk/cfg/__init__.py +++ b/scripts/wk/cfg/__init__.py @@ -1,4 +1,4 @@ '''WizardKit: cfg module init''' -from wk.cfg import logging +from wk.cfg import log from wk.cfg import main diff --git a/scripts/wk/cfg/logging.py b/scripts/wk/cfg/log.py similarity index 77% rename from scripts/wk/cfg/logging.py rename to scripts/wk/cfg/log.py index e3501f03..925be4d3 100644 --- a/scripts/wk/cfg/logging.py +++ b/scripts/wk/cfg/log.py @@ -1,16 +1,14 @@ -'''WizardKit: Config - Logging''' +'''WizardKit: Config - Log''' # vim: sts=2 sw=2 ts=2 -import logging - DEBUG = { - 'level': logging.DEBUG, + 'level': 'DEBUG', 'format': '[%(asctime)s %(levelname)s] [%(name)s.%(funcName)s] %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S %z', } DEFAULT = { - 'level': logging.INFO, + 'level': 'INFO', 'format': '[%(asctime)s %(levelname)s] %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S %z', } diff --git a/scripts/wk/log.py b/scripts/wk/log.py new file mode 100644 index 00000000..d8bf82be --- /dev/null +++ b/scripts/wk/log.py @@ -0,0 +1,88 @@ +'''WizardKit: Log Functions''' +# vim: sts=2 sw=2 ts=2 + +import logging +import os +import pathlib +import shutil +import time + +from . import cfg + + +# STATIC VARIABLES +LOG = logging.getLogger(__name__) + + +# Functions +def enable_debug_mode(): + """Configures logging for better debugging.""" + root_logger = logging.getLogger() + for handler in root_logger.handlers: + formatter = logging.Formatter( + datefmt=cfg.log.DEBUG['datefmt'], + fmt=cfg.log.DEBUG['format'], + ) + handler.setFormatter(formatter) + root_logger.setLevel('DEBUG') + + +def update_log_path(dest_dir, dest_filename=''): + """Copies current log file to new dir and updates the root logger.""" + dest = pathlib.Path(dest_dir) + dest = dest.expanduser() + root_logger = logging.getLogger() + cur_handler = root_logger.handlers[0] + + # Safety checks + if len(root_logger.handlers) > 1: + raise NotImplementedError('update_log_path() only supports a single handler.') + if not isinstance(cur_handler, logging.FileHandler): + raise NotImplementedError('update_log_path() only supports FileHandlers.') + + # Set source + source = pathlib.Path(cur_handler.baseFilename) + source = source.resolve() + + # Copy original log to new location + if dest_filename: + dest = dest.joinpath(dest_filename) + else: + dest = dest.joinpath(source.name) + dest = dest.resolve() + os.makedirs(dest.parent, exist_ok=True) + shutil.copy(source, dest) + + # Create new cur_handler (preserving formatter settings) + new_handler = logging.FileHandler(dest, mode='a') + new_handler.setFormatter(cur_handler.formatter) + + # Replace current handler + root_logger.removeHandler(cur_handler) + root_logger.addHandler(new_handler) + + +def start(config=None): + """Configure and start logging using safe defaults.""" + log_dir = '{}/Logs/'.format(os.path.expanduser('~')) + log_path = '{}/{}_{}.log'.format( + log_dir, + cfg.main.KIT_NAME_FULL, + time.strftime('%Y-%m-%d_%H%M%z'), + ) + root_logger = logging.getLogger() + + # Safety checks + if not config: + config = cfg.log.DEFAULT + if root_logger.hasHandlers(): + raise UserWarning('Logging already started.') + + # Create log_dir + os.makedirs(log_dir, exist_ok=True) + + # Config logger + logging.basicConfig(filename=log_path, **config) + +if __name__ == '__main__': + print("This file is not meant to be called directly.")