aboutsummaryrefslogtreecommitdiff
path: root/gn3/utility/logger.py
diff options
context:
space:
mode:
Diffstat (limited to 'gn3/utility/logger.py')
-rw-r--r--gn3/utility/logger.py163
1 files changed, 163 insertions, 0 deletions
diff --git a/gn3/utility/logger.py b/gn3/utility/logger.py
new file mode 100644
index 0000000..4245a02
--- /dev/null
+++ b/gn3/utility/logger.py
@@ -0,0 +1,163 @@
+"""
+# GeneNetwork logger
+#
+# The standard python logging module is very good. This logger adds a
+# few facilities on top of that. Main one being that it picks up
+# settings for log levels (global and by module) and (potentially)
+# offers some fine grained log levels for the standard levels.
+#
+# All behaviour is defined here. Global settings (defined in
+# default_settings.py).
+#
+# To use logging and settings put this at the top of a module:
+#
+# import utility.logger
+# logger = utility.logger.getLogger(__name__ )
+#
+# To override global behaviour set the LOG_LEVEL in default_settings.py
+# or use an environment variable, e.g.
+#
+# env LOG_LEVEL=INFO ./bin/genenetwork2
+#
+# To override log level for a module replace that with, for example,
+#
+# import logging
+# import utility.logger
+# logger = utility.logger.getLogger(__name__,level=logging.DEBUG)
+#
+# We'll add more overrides soon.
+"""
+# todo incomplete file
+
+# pylint: disable-all
+import logging
+import datetime
+from inspect import isfunction
+from inspect import stack
+
+from pprint import pformat as pf
+
+
+# from utility.tools import LOG_LEVEL, LOG_LEVEL_DEBUG, LOG_SQL
+
+LOG_SQL = True
+
+
+class GNLogger:
+ """A logger class with some additional functionality, such as
+ multiple parameter logging, SQL logging, timing, colors, and lazy
+ functions.
+
+ """
+
+ def __init__(self, name):
+ self.logger = logging.getLogger(name)
+
+ def setLevel(self, value):
+ """Set the undelying log level"""
+ self.logger.setLevel(value)
+
+ def debug(self, *args):
+ """Call logging.debug for multiple args. Use (lazy) debugf and
+level=num to filter on LOG_LEVEL_DEBUG.
+
+ """
+ self.collect(self.logger.debug, *args)
+
+ def debug20(self, *args):
+ """Call logging.debug for multiple args. Use level=num to filter on
+LOG_LEVEL_DEBUG (NYI).
+
+ """
+ if level <= LOG_LEVEL_DEBUG:
+ if self.logger.getEffectiveLevel() < 20:
+ self.collect(self.logger.debug, *args)
+
+ def info(self, *args):
+ """Call logging.info for multiple args"""
+ self.collect(self.logger.info, *args)
+
+ def warning(self, *args):
+ """Call logging.warning for multiple args"""
+ self.collect(self.logger.warning, *args)
+ # self.logger.warning(self.collect(*args))
+
+ def error(self, *args):
+ """Call logging.error for multiple args"""
+ now = datetime.datetime.utcnow()
+ time_str = now.strftime('%H:%M:%S UTC %Y%m%d')
+ l = [time_str]+list(args)
+ self.collect(self.logger.error, *l)
+
+ def infof(self, *args):
+ """Call logging.info for multiple args lazily"""
+ # only evaluate function when logging
+ if self.logger.getEffectiveLevel() < 30:
+ self.collectf(self.logger.debug, *args)
+
+ def debugf(self, level=0, *args):
+ """Call logging.debug for multiple args lazily and handle
+ LOG_LEVEL_DEBUG correctly
+
+ """
+ # only evaluate function when logging
+ if level <= LOG_LEVEL_DEBUG:
+ if self.logger.getEffectiveLevel() < 20:
+ self.collectf(self.logger.debug, *args)
+
+ def sql(self, sqlcommand, fun=None):
+ """Log SQL command, optionally invoking a timed fun"""
+ if LOG_SQL:
+ caller = stack()[1][3]
+ if caller in ['fetchone', 'fetch1', 'fetchall']:
+ caller = stack()[2][3]
+ self.info(caller, sqlcommand)
+ if fun:
+ result = fun(sqlcommand)
+ if LOG_SQL:
+ self.info(result)
+ return result
+
+ def collect(self, fun, *args):
+ """Collect arguments and use fun to output"""
+ out = "."+stack()[2][3]
+ for a in args:
+ if len(out) > 1:
+ out += ": "
+ if isinstance(a, str):
+ out = out + a
+ else:
+ out = out + pf(a, width=160)
+ fun(out)
+
+ def collectf(self, fun, *args):
+ """Collect arguments and use fun to output one by one"""
+ out = "."+stack()[2][3]
+ for a in args:
+ if len(out) > 1:
+ out += ": "
+ if isfunction(a):
+ out += a()
+ else:
+ if isinstance(a, str):
+ out = out + a
+ else:
+ out = out + pf(a, width=160)
+ fun(out)
+
+# Get the module logger. You can override log levels at the
+# module level
+
+
+def getLogger(name, level=None):
+ """method to get logger"""
+ gnlogger = GNLogger(name)
+ _logger = gnlogger.logger
+
+ # if level:
+ # logger.setLevel(level)
+ # else:
+ # logger.setLevel(LOG_LEVEL)
+
+ # logger.info("Log level of "+name+" set to "+logging.getLevelName(logger.getEffectiveLevel()))
+ return gnlogger