Author: reinhard
Date: 2007-07-16 16:48:40 -0500 (Mon, 16 Jul 2007)
New Revision: 9760
Modified:
trunk/gnue-common/src/base/log.py
Log:
Added function logging decorator.
issue123 in-progress
Modified: trunk/gnue-common/src/base/log.py
===================================================================
--- trunk/gnue-common/src/base/log.py 2007-07-13 22:22:52 UTC (rev 9759)
+++ trunk/gnue-common/src/base/log.py 2007-07-16 21:48:40 UTC (rev 9760)
@@ -35,12 +35,11 @@
from gnue.common.base import utils
-__all__ = ['debug', 'info', 'warning', 'deprecated', 'error', 'critical',
- 'exception', 'debug_n', 'info_n', 'warning_n', 'deprecated_n',
- 'error_n', 'critical_n', 'exception_n']
+__all__ = ['logged_f', 'debug', 'info', 'warning', 'deprecated', 'error',
+ 'critical', 'exception', 'debug_n', 'info_n', 'warning_n',
+ 'deprecated_n', 'error_n', 'critical_n', 'exception_n']
# TODO:
-# - function for enter() and leave(), maybe as decorator?
# - function to declare function as deprecated, maybe as decorator?
# - Exception hook
# - allow for __gnue_logger__ module global variable to use as a logger name
@@ -49,6 +48,105 @@
# -----------------------------------------------------------------------------
+# Log function entry and exit
+# -----------------------------------------------------------------------------
+
+def logged_f(func):
+ """
+ Decorator to activate logging for a function.
+
+ If this decorator is applied to a function, every call to that function is
+ logged on C{DEBUG} level.
+
+ Usage with Python 2.4 or later::
+ @logged_f
+ myfunction(self, foo, bar):
+ :
+
+ Usage with Python 2.3::
+ myfunction(self, foo, bar):
+ :
+ myfunction=logged_f(myfunction)
+ """
+ def new_f(*args, **kwargs):
+ name = func.func_globals['__name__']
+ __enter(name, func)
+ result = func(*args, **kwargs)
+ __leave(name, func, result)
+ return result
+ return new_f
+
+# -----------------------------------------------------------------------------
+
+def __enter(name, func):
+
+ # Get the caller's frame
+ frame = inspect.currentframe().f_back
+ while not frame.f_code.co_name == 'new_f':
+ frame = frame.f_back
+
+ try:
+ fname = __func_name(func, frame)
+
+ args = frame.f_locals['args']
+ kwargs = frame.f_locals['kwargs']
+
+ params = []
+ # Arguments
+ params.extend([repr(item) for item in args])
+ # Keyword arguments
+ params.extend(["%s=%r" % (k, v) for (k, v) in kwargs.items()])
+
+ msg = "Calling function %s(%s)" % (fname, ", ".join(params))
+
+ finally:
+ # Frame object has to be deleted manually.
+ del frame
+
+ debug_n(name, msg)
+ return True
+
+# -----------------------------------------------------------------------------
+
+def __leave(name, func, result):
+
+ # Get the caller's frame
+ frame = inspect.currentframe().f_back
+ while not frame.f_code.co_name == 'new_f':
+ frame = frame.f_back
+
+ try:
+ msg = "Returning from function " + __func_name(func, frame) + "() -> " \
+ + repr(result)
+ finally:
+ # Frame object has to be deleted manually.
+ del frame
+
+ debug_n(name, msg)
+ return True
+
+# -----------------------------------------------------------------------------
+
+def __func_name(func, frame):
+ # It seems like there is no way to find out the name of the class that
+ # defined a method. To print out the class name in the log, we need to
+ # inspect the 'self' parameter.
+ fname = func.__name__
+ code = func.func_code
+ if code.co_argcount > 0 and code.co_names[0] == 'self':
+ klass = frame.f_locals['args'][0].__class__
+ if isinstance(klass, str):
+ # Old stle class
+ fname = klass + '.' + fname
+ else:
+ # New style class
+ fname = klass.__module__ + '.' + klass.__name__ + '.' + fname
+ else:
+ fname = func.func_globals['__name__'] + '.' + fname
+ return fname
+
+
+# -----------------------------------------------------------------------------
# Log to the logger named after the calling module
# -----------------------------------------------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.