diff logging_module.py @ 0:3830d29fca6a draft

Uploaded
author jaredgk
date Mon, 15 Oct 2018 18:15:47 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/logging_module.py	Mon Oct 15 18:15:47 2018 -0400
@@ -0,0 +1,97 @@
+import sys
+import logging
+
+
+
+def initLogger(filename='pipeline.log', filelevel='INFO',
+               streamlevel='WARNING', resetlog=True):
+    """General logger initialization for PPP functions.
+
+    Messages from WARNING level and higher will be logged to file and to
+    stderr. By default, INFO level will also be written to logfile. Both
+    levels are flexible.
+
+    Level groupings:
+        ERROR: Error messages should be generated by an exception call
+        WARNING: Non-terminal behavior that may be unusual (i.e. lists
+            with no values, blank strings)
+        INFO: Every major (user-facing) function should have the following:
+            -Message for function start
+            -List of input arguments and options
+            -Basic sanity checks (dimensions of input data)
+            -Statements before or after major function calls
+            -Message for function end
+        DEBUG: Mainly for developer use/debugging. Generate logs for
+            sub-functions that match INFO level for major functions.
+            Possible care should be used if there are lots of loops called.
+
+    Use: Call with either the individual function (in __name__=="__main__"
+    statement) or in pipeline file.
+
+    Parameters
+    ----------
+    filename : str ("pipeline.log")
+        Name of file that log will be written to
+
+    filelevel : {'INFO','DEBUG','WARNING','ERROR'}
+        Set minimum level of log messages that are written to log file.
+        Note that this acts as a de facto minumum for 'streamlevel' as well.
+
+    streamlevel : {'WARNING','DEBUG','INFO','ERROR'}
+        Set minimum level of log messages that are output to stream.
+
+    resetlog : bool (True)
+        If true, will overwrite logfile when opening. Set to false if log is
+        being initialized multiple times
+
+    Returns
+    -------
+    None
+
+    Exceptions
+    ----------
+    If filelevel or streamlevel are not a valid logging level
+
+    """
+    log_levels = ['DEBUG','INFO','WARNING','ERROR']
+    if filelevel is not None and filelevel.upper() not in log_levels:
+        raise Exception('filelevel value %s is not a valid level' %
+                         filelevel)
+    if streamlevel is not None and streamlevel.upper() not in log_levels:
+        raise Exception('streamlevel value %s is not a valid level' %
+                         streamlevel)
+    fmt_def = "%(asctime)s - %(funcName)s - %(levelname)s: %(message)s"
+    fmt_notime = "%(funcName)s - %(levelname)s: %(message)s"
+    fmtr = logging.Formatter(fmt=fmt_def)
+    fmtr_notime = logging.Formatter(fmt=fmt_notime)
+    filelogger = logging.getLogger()
+    filelogger.setLevel('INFO')
+    if streamlevel is not None:
+        s_handler = logging.StreamHandler()
+        s_handler.setFormatter(fmtr_notime)
+        s_handler.setLevel(streamlevel)
+        filelogger.addHandler(s_handler)
+    logmode = 'a'
+    if resetlog:
+        logmode = 'w'
+    if filelevel is not None:
+        f_handler = logging.FileHandler(filename,mode=logmode)
+        f_handler.setFormatter(fmtr)
+        f_handler.setLevel(filelevel)
+        #filelogger.setLevel(filelevel)
+        filelogger.addHandler(f_handler)
+    #Formats exception messages to be sent to appropriate loggers
+    def exp_handler(etype,val,tb):
+        logging.error("%s" % (val), exc_info=(etype,val,tb))
+
+    sys.excepthook = exp_handler
+
+
+def logArgs(args, func_name=None, print_nones=False):
+    header = "Arguments"
+    if func_name is not None:
+        header+=" for"+func_name
+    for arg in vars(args):
+        val = vars(args)[arg]
+        if val is not None or print_nones:
+            logging.info('Argument %s: %s' % (arg,val))