log: Make the log_exception support a per instance logger.
authorMatthijs Kooijman <matthijs@stdin.nl>
Sat, 7 Aug 2010 19:09:20 +0000 (21:09 +0200)
committerMatthijs Kooijman <matthijs@stdin.nl>
Sat, 7 Aug 2010 19:09:20 +0000 (21:09 +0200)
Previously, the logger to use was always passed to the decorator
directly, thus it must be known at class-definition time. Now, the
decorator supports not being passed a logger, in which case it will
assume the decorated function is a method on an object that has a "log"
attribute.

src/lib/backupninja/log.py

index 86a31813e50e5f723d1cec9df8fc787ba891b471..6f25f7db006dd0fda8990d4f667778c5f74a4c04 100644 (file)
@@ -38,21 +38,38 @@ def setup_logging(options):
     logging.basicConfig(level=level)
     log.debug("Initialized logging configuration")
 
-def log_exception(log, msg="%s"):
+def log_exception(log=None, msg="%s"):
     """
     This is a decorator that catches an exception, logs the exception
-    and a backtrace and then swallows it. log is the Logging instance to
-    log to (using the "error" level for the message, and "debug" for the
-    backtrace), msg is the message to log (which must contain a %s into
-    which the exception message is interpolated).
+    and a backtrace and then swallows it.  The exception is logged using
+    the "error" level for the message, and "debug" for the backtrace.
+
+    log is the Logger instance to log to. If this is not present, the
+    decorated function should be a method of an object that contains a
+    "log" attribute that contains a Logger instance.
+
+    msg is the message to log (which must contain a %s into which the
+    exception message is interpolated).
+
     """
     def decorator(f):
         def inner(*args, **kwargs):
             try:
                 f(*args, **kwargs)
             except Exception, e:
-                log.error(msg, e)
+                # Find out which logger to use. We create a new variabel
+                # logger here, since it seems to be impossible to assign
+                # the log variable from the log_exception scope.
+                if log is None:
+                    # No log is passed. Get the self argument (args[0]) and
+                    # get is "log" attribute.
+                    logger = args[0].log
+                else:
+                    # Use the passed log
+                    logger = log
+
+                logger.error(msg, e)
                 import traceback
-                log.debug(traceback.format_exc())
+                logger.debug(traceback.format_exc())
         return inner
     return decorator