[gnue] r9758 - in trunk/gnue-common/src: . apps base

[email protected]
Newsgroups gmane.comp.cms.gnue.cvs
Message-ID <[email protected]>
Author: reinhard
Date: 2007-07-12 18:08:03 -0500 (Thu, 12 Jul 2007)
New Revision: 9758

Added:
   trunk/gnue-common/src/base/
   trunk/gnue-common/src/base/__init__.py
   trunk/gnue-common/src/base/log.py
Modified:
   trunk/gnue-common/src/apps/GDebug.py
Log:
Started switch to Python standard logging module.

issue123 in-progress


Modified: trunk/gnue-common/src/apps/GDebug.py
===================================================================
--- trunk/gnue-common/src/apps/GDebug.py	2007-07-12 17:04:23 UTC (rev 9757)
+++ trunk/gnue-common/src/apps/GDebug.py	2007-07-12 23:08:03 UTC (rev 9758)
@@ -39,60 +39,17 @@
 import traceback
 import types
 
+from gnue.common.base import log
 
+
 # -----------------------------------------------------------------------------
 # Internal global variables
 # -----------------------------------------------------------------------------
 
-_fh = sys.__stderr__                    # Filehandle to write debug msgs to
 _DEBUG_LEVELS = []                      # Debug levels requested
-_DEBUGGER = None                        # Interactive debugger
 
 
 # =============================================================================
-# Support for redirecting error messages to a file
-# =============================================================================
-
-# -----------------------------------------------------------------------------
-# Class to catch the stderr stream
-# -----------------------------------------------------------------------------
-
-class __stderrcatcher:
-  """
-  Output stream for error message.
-
-  sys.stderr is redirected to this class. It prepends "DB000: " in front of
-  each line and writes everything to the debug file or stderr.
-  """
-
-  def __init__ (self, filehandle):
-    self.filehandle = filehandle
-
-  def write (self, str):
-    lines = string.split (str, "\n")
-    while len(lines) and lines [-1] == "":             # remove empty lines at the end
-      del (lines [-1])
-    self.filehandle.write (string.join (["DB000: " + s for s in lines], "\n"))
-    self.filehandle.write ("\n")
-    self.filehandle.flush ()
-
-  def writelines (self, list):
-    for line in list:
-      self.write (str)
-
-
-# -----------------------------------------------------------------------------
-# redirect stderr and all debugging output to the given filehandle
-# -----------------------------------------------------------------------------
-
-def __catchStderr (filehandle):
-
-  global _fh
-  _fh = filehandle
-  sys.stderr = __stderrcatcher (filehandle)
-
-
-# =============================================================================
 # Support for debugging messages
 # =============================================================================
 
@@ -100,7 +57,7 @@
 # Placeholders for gDebug/gEnter/gLeave if no debug output is desired at all
 # -----------------------------------------------------------------------------
 
-def __noDebug (level, message, dropToDebugger = False):
+def __noDebug (level, message):
   return True
   
 
@@ -117,87 +74,22 @@
 
 
 # -----------------------------------------------------------------------------
-# Set the debugger
-# -----------------------------------------------------------------------------
-
-def setDebugger (debugger):
-  """
-  This function informs the debug system about the use of Python's interactive
-  debugger. If this is called, subsequent calls to gDebug with the parameter
-  dropToDebugger set will switch the interactive debugger to trace mode.
-  """
-
-  global _DEBUGGER
-  _DEBUGGER = debugger
-
-
-# -----------------------------------------------------------------------------
-# Dump a message to the debug-output
-# -----------------------------------------------------------------------------
-
-def __dumpMessage (level, filename, message, dropToDebugger = False):
-  """
-  Write a message to the debug-output.
-
-  @param level: the debug-level the message will be logged in
-  @param filename: the filename the message originated from
-  @param message: the message to be logged
-  @param dropToDebugger: if set to True, Python's interactive debugger will be
-    switched to trace mode. This requires that setDebugger has been called
-    before.
-  """
-
-  global _fh, _DEBUGGER
-
-  s = time.time ()
-  msecs = (s - long (s)) * 1000
-  t = time.strftime ('%Y-%m-%d %H:%M:%S', time.localtime (s))
-  stamp = "%s.%03d" % (t, msecs)
-
-  lines = "%s" % message
-  for line in lines.splitlines ():
-    _fh.write ("DB%03d: %s %s%s%s" % (level, stamp, filename, line, os.linesep))
-    _fh.flush ()
-
-  if dropToDebugger and _DEBUGGER:
-    _DEBUGGER.set_trace ()
-
-
-# -----------------------------------------------------------------------------
 # Write debug message
 # -----------------------------------------------------------------------------
 
-def gDebug (level, message, dropToDebugger = False):
+def gDebug (level, message):
   """
   Write a message to the debug-output. This function is available in the
   global namespace.
 
   @param level: the debug-level the message will be logged in
   @param message: the message to be logged
-  @param dropToDebugger: if set to True, Python's interactive debugger will be
-    switched to trace mode. This requires that setDebugger has been called
-    before.
   @return: Always true so it can be filtered out via assert
   """
 
-  if level in _DEBUG_LEVELS :
+  if level in _DEBUG_LEVELS:
+    log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
 
-    # Just to be sure...
-    if isinstance (message, types.UnicodeType):
-      message = message.encode ('utf-8')
-
-    # Find out the file from where we were called
-    caller = traceback.extract_stack()[-2]
-    try:
-      if caller[0][-3:] == '.py':
-        file = "[%s:%s] " % (string.split(caller[0][:-3],'/')[-1], caller[1])
-      else:
-        file = "[%s:%s] " % (string.split(caller[0],'/')[-1], caller[1])
-    except:
-      file = ""
-
-    __dumpMessage (level, file, message, dropToDebugger)
-
   return True
 
 # -----------------------------------------------------------------------------
@@ -247,16 +139,8 @@
     message  = "Entering function %s (%s)" % (funcName,
                                               string.join (params, ", "))
 
-    path = frame.f_code.co_filename
-    if path [-3:] == '.py':
-      path = string.split (path [:-3], '/') [-1]
-    else:
-      path = string.split (path, '/') [-1]
+    log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
 
-    filename = "[%s:%s] " % (path, frame.f_code.co_firstlineno)
-
-    __dumpMessage (level, filename, message)
-
   finally:
     # Make sure to release the reference to the frame object. This keeps
     # garbage collection doing a fine job :)
@@ -301,23 +185,16 @@
     resStr  = len (result) and ' == %s' % repr (result [0]) or ''
     message = "Leaving function %s (%s)%s" % (fName, hId, resStr)
 
-    path = frame.f_code.co_filename
-    if path [-3:] == '.py':
-      path = string.split (path [:-3], '/') [-1]
-    else:
-      path = string.split (path, '/') [-1]
+    log.debug_n(inspect.stack()[1][0].f_globals['__name__'], message)
 
-    filename = "[%s:%s] " % (path, frame.f_code.co_firstlineno)
-
-    __dumpMessage (level, filename, message)
-
   finally:
     # Make sure to release the reference to the frame object. This keeps
     # garbage collection doing a fine job :)
     del frame
-    return True
 
+  return True
 
+
 # -----------------------------------------------------------------------------
 # Set debug levels to use and initialize debugging
 # -----------------------------------------------------------------------------
@@ -350,46 +227,13 @@
     __builtin__.__dict__ ['gEnter'] = gEnter
     __builtin__.__dict__ ['gLeave'] = gLeave
 
-  # Redirect debugging and error output to a file if requested
-  if (file):
-    __catchStderr (open (file, 'a'))
-  else:
-    __catchStderr (sys.__stderr__)
 
-
 # -----------------------------------------------------------------------------
 # Deprecated, for compatibility
 # -----------------------------------------------------------------------------
 
-def printMesg (level, message, dropToDebugger = False):
+def printMesg (level, message):
   """
   This function is deprecated - use gDebug instead
   """
-  __builtin__.__dict__ ['gDebug'] (level, message, dropToDebugger)
-
-
-# -----------------------------------------------------------------------------
-# FIXME: is it save to remove the following stuff?
-# -----------------------------------------------------------------------------
-
-class GETrace(Exception):
-    #
-    #Exception class representing a debug message
-    #not yet used for anything and probably won't be :)
-    #
-    def __init__(self, level=0, message="Trace Message"):
-        Exception.__init__(self)
-        self.level = level
-        self.message = message
-
-def handleException(exc_info):
-    #
-    # Not used at present
-    #
-    type, exception, traceback = exc_info
-    if (isinstance(exception, GETrace) ):
-        printMesg( exception.level, exception.message)
-    elif (not isinstance(exception, SystemExit)):
-        strings = traceback.format_exception(type, exception, traceback)
-        text = string.join(strings, '')
-        printMesg(0, text)
+  __builtin__.__dict__ ['gDebug'] (level, message)


Property changes on: trunk/gnue-common/src/base
___________________________________________________________________
Name: svn:ignore
   + *.pyc


Added: trunk/gnue-common/src/base/__init__.py
===================================================================
--- trunk/gnue-common/src/base/__init__.py	2007-07-12 17:04:23 UTC (rev 9757)
+++ trunk/gnue-common/src/base/__init__.py	2007-07-12 23:08:03 UTC (rev 9758)
@@ -0,0 +1,27 @@
+# GNU Enterprise Common Library - Base Modules
+#
+# Copyright 2001-2007 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+"""
+The base package contains a number of modules providing very basic functions
+that are used all over the GNU Enterprise tools.
+"""


Property changes on: trunk/gnue-common/src/base/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: trunk/gnue-common/src/base/log.py
===================================================================
--- trunk/gnue-common/src/base/log.py	2007-07-12 17:04:23 UTC (rev 9757)
+++ trunk/gnue-common/src/base/log.py	2007-07-12 23:08:03 UTC (rev 9758)
@@ -0,0 +1,243 @@
+# GNU Enterprise Common Library - Logging support
+#
+# Copyright 2001-2007 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+# We use * and ** magic on purpose.
+# pylint: disable-msg=W0142
+
+"""
+The logging module extends the standard logging module with some convenience
+functions related to the logging schema used in GNU Enterprise.
+"""
+
+import inspect
+import logging
+
+__all__ = ['debug', 'info', 'warning', 'deprecated', 'error', 'critical',
+        'exception', 'debug_n', 'info_n', 'warning_n', 'deprecated_n',
+        'error_n', 'critical_n', 'exception_n']
+
+
+# TODO:
+# - Read debug config
+# - function for enter() and leave(), maybe as decorator?
+# - function to declare function as deprecated, maybe as decorator?
+# - Exception hook
+
+# -----------------------------------------------------------------------------
+# Log to the logger named after the calling module
+# -----------------------------------------------------------------------------
+
+def debug(msg, *args, **kwargs):
+    """
+    Write a debug message to the logger named after the calling module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return debug_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def info(msg, *args, **kwargs):
+    """
+    Write an info message to the logger named after the calling module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return info_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def warning(msg, *args, **kwargs):
+    """
+    Write a warning message to the logger named after the calling module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return warning_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def deprecated(msg, *args, **kwargs):
+    """
+    Write a deprecation warning message to the logger named after the calling
+    module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return deprecated_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def error(msg, *args, **kwargs):
+    """
+    Write an error message to the logger named after the calling module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return error_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def critical(msg, *args, **kwargs):
+    """
+    Write a critical error message to the logger named after the calling module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return critical_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def exception(msg, *args, **kwargs):
+    """
+    Log an exception to the logger named after the calling module.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    return exception_n(__caller(), msg, *args, **kwargs)
+
+# -----------------------------------------------------------------------------
+
+def __caller():
+    return inspect.stack()[2][0].f_globals['__name__']
+
+
+# -----------------------------------------------------------------------------
+# Log to a certain logger
+# -----------------------------------------------------------------------------
+
+def debug_n(name, msg, *args, **kwargs):
+    """
+    Write a debug message to the logger defined through the C{name} parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).debug(msg, *args, **kwargs)
+    return True
+
+# -----------------------------------------------------------------------------
+
+def info_n(name, msg, *args, **kwargs):
+    """
+    Write an info message to the logger defined through the C{name} parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).info(msg, *args, **kwargs)
+    return True
+
+# -----------------------------------------------------------------------------
+
+def warning_n(name, msg, *args, **kwargs):
+    """
+    Write a warning message to the logger defined through the C{name} parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).warning(msg, *args, **kwargs)
+    return True
+
+# -----------------------------------------------------------------------------
+
+def deprecated_n(name, msg, *args, **kwargs):
+    """
+    Write a deprecation warning message to the logger defined through the
+    C{name} parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).log(31, msg, *args, **kwargs)
+    return True
+
+# -----------------------------------------------------------------------------
+
+def error_n(name, msg, *args, **kwargs):
+    """
+    Write an error message to the logger defined through the C{name} parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).error(msg, *args, **kwargs)
+    return True
+
+# -----------------------------------------------------------------------------
+
+def critical_n(name, msg, *args, **kwargs):
+    """
+    Write a critical error message to the logger defined through the C{name}
+    parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).critical(msg, *args, **kwargs)
+    return True
+
+# -----------------------------------------------------------------------------
+
+def exception_n(name, msg, *args, **kwargs):
+    """
+    Log an exception to the logger defined through the C{name} parameter.
+
+    @return: always True, so the call can be prefixed with assert.
+    """
+    logging.getLogger(name).exception(msg, *args, **kwargs)
+    return True
+
+
+# -----------------------------------------------------------------------------
+# Derivate from standard Logger to output correct caller information
+# -----------------------------------------------------------------------------
+
+class Logger(logging.Logger):
+    """
+    Derivated Logger class to make sure the correct file name is used instead
+    of "log.py", which is the file actually calling the logger functions.
+    """
+
+    def findCaller(self):
+        """
+        Find the stack frame of the caller so that we can note the source
+        file name, line number and function name.
+        """
+        frame = inspect.currentframe().f_back
+        while hasattr(frame, 'f_code'):
+            if frame.f_globals['__name__'] not in [logging.__name__, __name__,
+                    # FIXME: Remove after GDebug has been removed!
+                    'gnue.common.apps.GDebug']:
+                code = frame.f_code
+                return (code.co_filename, frame.f_lineno, code.co_name)
+            frame = frame.f_back
+        return ("(unknown file)", 0, "(unknown function)")
+
+# -----------------------------------------------------------------------------
+# Module initialization
+# -----------------------------------------------------------------------------
+
+# Use our own Logger class.
+logging.setLoggerClass(Logger)
+
+# Configure logging to a very basic default behaviour to start with.
+logging.basicConfig(level=10)
+
+# Add level for deprecation warnings.
+logging.addLevelName(31, 'DEPRECATED')


Property changes on: trunk/gnue-common/src/base/log.py
___________________________________________________________________
Name: svn:keywords
   + Id
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.