Source code for customlogging

# -*- coding: utf8 -*-
"""

****************************
``helpers/customlogging.py``
****************************

`BSD`_ © 2018-2019 Science and Technology Facilities Council & contributors

.. _BSD: _static/LICENSE

``customlogging.py`` is a helpers module provided to define and configure consistent logging. The logging
configuration is handled via ``../logging.yml`` YAML file and uses ``colorlog`` for console output.
A rolling system is used for outputting to files.

"""
import os
import sys
import yaml
import logging
import logging.config


[docs]def setup_logging(logr_settings='../logging.yml', default_level=logging.INFO): """Setup logging configuration from a YAML file Args: logr_settings (str, optional): Defines the relative location of the logging configuration file, from the root module. Default value: ``logging.yml`` default_level (logging attr, optional): Sets the default logging level. Default value: logging.INFO Returns: None """ logr_settings = os.path.abspath(os.path.join(os.path.dirname(__file__), logr_settings)) if os.path.isfile(logr_settings): with open(logr_settings, 'rt') as f: config = yaml.safe_load(f.read()) logging.config.dictConfig(config) else: logging.basicConfig(level=default_level)
logger = logging.getLogger(__name__) setup_logging(logr_settings='../logging.yml', default_level=logging.INFO)
[docs]def constant(f): """setters and getters for constants used throughout Prevents setting of existing objects. Raises a TypeError. Return: property Raises: TypeError: On setter. """ def fset(value): raise TypeError def fget(): return f() return property(fget, fset)
[docs]class LogLevelsConsts(object): """Logger level equivalent strings as constants, used to pass log level to helpers functions. Attributes: DEBUG (str): String matching DEBUG logger level. INFO (str): String matching INFO logger level. WARNING (str): String matching WARNING logger level. CRITICAL (str): String matching CRITICAL logger level. ERROR (str): String matching ERROR logger level. """ @constant def DEBUG(self): return 'DEBUG' @constant def INFO(self): return 'INFO' @constant def WARNING(self): return 'WARNING' @constant def CRITICAL(self): return 'CRITICAL' @constant def ERROR(self): return 'ERROR'
[docs]def config_logger(name, class_name=None): """Allows a logger to be set up and/or configured in all modules/module classes Args: name (str): Name of the logger. class_name (str, optional): Name of the class to which the logger is associated. Default value: None Returns: logging (obj): A configured logger object. """ if class_name is None: logr = logging.getLogger('{}' .format(name)) setup_logging(logr_settings='../logging.yml', default_level=logging.INFO) else: logr = logging.getLogger('{}.{}' .format(name, class_name)) return logr
[docs]def sect_break(logr, level=LogLevelsConsts.INFO): """Inserts a section break in the logger output. Args: logr (obj): A logger object to pass the section break to. level (attr of LogLevelsConsts obj, optional): Logger level of the section break. Default value: LogLevelsConsts.INFO Returns: None """ delimit = '*' * 80 try: if level == LogLevelsConsts.DEBUG: logr.debug(delimit) elif level == LogLevelsConsts.INFO: logr.info(delimit) elif level == LogLevelsConsts.WARNING: logr.warning(delimit) elif level == LogLevelsConsts.CRITICAL: logr.critical(delimit) elif level == LogLevelsConsts.ERROR: logr.error(delimit) else: logr.info(delimit) except AttributeError as e: logr.error('{}' .format(__name__)) logr.error('\t{}' .format(e))
[docs]def errorexit(logr): """Inserts a exit on error message in the logger output and performs a ``sys.exit(-1)`` Args: logr (obj): A logger object to pass the exit on error message to. Returns: None """ logr.error('') logr.error('Exiting...') sys.exit(-1)
[docs]def mand_missing(obj, field): """Inserts a mandatory field missing error message in the logger output and calls ``errorexit()`` Args: logr (obj): A logger object to pass the error message to. field (str): field to report in the error message. Returns: None """ obj.logger.error('Missing Mandatory Field in: {obj.settings_file}' .format(obj=obj)) obj.logger.error('{obj.category}' .format(obj=obj)) obj.logger.error(' {field}: <VALUE>' .format(field=field)) errorexit(obj.logger)
[docs]def path_missing(obj, name, path): """Inserts a path missing error message in the logger output and calls ``errorexit()`` Args: logr (obj): A logger object to pass the error message to. name (str): Name of processing element which caused the error message. path (str): Missing Path which caused the error message. Returns: None """ obj.logger.error('Processing: {name}' .format(name=name)) obj.logger.error('Path Missing on File-System: {path}' .format(path=path)) errorexit(obj.logger)
def disable_logger(log_obj, term): # svn logger DEBUG messages contain plain text passwords passed to svn and git. # To prevent the svn logger from writing DEBUG level messages in the log file disable all 'term' # related loggers: for name, logr in log_obj.logging.root.manager.loggerDict.iteritems(): if term in name: logr.disabled = True # Logging is required to be setup and configured prior to loading version modules import version as my_version rev = filter(str.isdigit, "$Rev$") # Do Not Modify this Line version = my_version.Version(0, 5, 0, svn_rev=rev, disable_svn_logging=True) __version__ = version.get_version() __str__ = my_version.about(__name__, __version__, version.revision)