Back to index

plone3  3.1.7
debug.py
Go to the documentation of this file.
00001 import inspect
00002 import os
00003 import sys
00004 import traceback
00005 import pprint
00006 from types import StringType
00007 import warnings
00008 import logging
00009 
00010 from Products.Archetypes.config import DEBUG
00011 
00012 
00013 logger = logging.getLogger('Archetypes')
00014 
00015 class SafeFileWrapper:
00016     def __init__(self, fp):
00017         self.fp = fp
00018 
00019     def write(self, msg):
00020         """If for some reason we can't log, just deal with it"""
00021         try:
00022             self.fp.write(msg)
00023         except IOError, E:
00024             pass
00025 
00026     def close(self):
00027         self.fp.close()
00028 
00029     def __getattr__(self, key):
00030         return getattr(self.fp, key)
00031 
00032 
00033 class Log:
00034     closeable = 0
00035     fp = None
00036 
00037     def __init__(self, target=sys.stderr):
00038         self.target = target
00039         self._open()
00040 
00041     def _open(self):
00042         if self.fp is not None and not self.fp.closed:
00043             return self.fp
00044 
00045         if type(self.target) is StringType:
00046             fp = open(self.target, "a+")
00047             self.closeable = 1
00048         else:
00049             fp = self.target
00050 
00051         self.fp = SafeFileWrapper(fp)
00052 
00053 
00054     def _close(self):
00055         if self.closeable:
00056             self.fp.close()
00057 
00058     def munge_message(self, msg, **kwargs):
00059         """Override this to messge with the message for subclasses"""
00060         return msg
00061 
00062     def log(self, msg, *args, **kwargs):
00063         self._open()
00064         self.fp.write("%s\n" % (self.munge_message(msg, **kwargs)))
00065         for arg in args:
00066             self.fp.write("%s\n" % pprint.pformat(arg))
00067         self._close()
00068 
00069     def log_exc(self, msg=None, *args, **kwargs):
00070         self.log(''.join(traceback.format_exception(*sys.exc_info())), offset=1)
00071         if msg: self.log(msg, collapse=0, deep=0, *args, **kwargs)
00072 
00073 
00074     def __call__(self, msg):
00075         self.log(msg)
00076 
00077 
00078 class NullLog(Log):
00079     def __init__(self, target):
00080         pass
00081     def log(self, msg, **kwargs): pass
00082 
00083 class ClassLog(Log):
00084     last_frame_msg = None
00085 
00086     def _process_frame(self, frame):
00087         path = frame[1] or '<string>'
00088         index = path.find("Products")
00089         if index != -1:
00090             path = path[index:]
00091 
00092         frame = "%s[%s]:%s\n" % (path, frame[2], frame[3])
00093 
00094         return frame
00095 
00096     def generateFrames(self, start=None, end=None):
00097         try: 
00098             return inspect.stack()[start:end]
00099         except IndexError:
00100             # NOTE: this is required for OS-X Tiger somehow
00101             return []
00102         except TypeError:
00103             # NOTE: this is required for psyco compatibility
00104             #       since inspect.stack is broken after psyco is imported
00105             return []
00106 
00107     def munge_message(self, msg, **kwargs):
00108         deep = kwargs.get("deep", 1)
00109         collapse = kwargs.get("collapse", 1)
00110         offset   = kwargs.get("offset", 0) + 3
00111 
00112         frame = ''
00113         try:
00114             frames = self.generateFrames(offset, offset+deep)
00115             res = []
00116             for f in frames:
00117                 res.insert(0, self._process_frame(f))
00118             frame = ''.join(res)
00119         finally:
00120             try:
00121                 del frames
00122             except:
00123                 pass
00124 
00125         if collapse == 1:
00126             if frame == self.last_frame_msg:
00127                 frame = ''
00128             else:
00129                 self.last_frame_msg = frame
00130 
00131         msg = "%s%s" %(frame, msg)
00132         return msg
00133 
00134 
00135 class ZPTLogger(ClassLog):
00136     def generateFrames(self, start=None, end=None):
00137         frames = inspect.stack()
00138         for f in frames:
00139             # We want to look for either <script...
00140             # or <template...
00141             print f
00142         return frames
00143 
00144 class ZLogger(ClassLog):
00145     def log(self, msg, *args, **kwargs):
00146         level = kwargs.get('level', logging.INFO)
00147         msg = "%s\n" % (self.munge_message(msg, **kwargs))
00148         for arg in args:
00149             msg += "%s\n" % pprint.pformat(arg)
00150         logger.log(level, msg)
00151 
00152     def log_exc(self, msg=None, *args, **kwargs):
00153         logger.exception(msg)
00154 
00155 def warn(msg, level=3):
00156     # level is the stack level
00157     #   1: the line below
00158     #   2: the line calling this function
00159     #   3: the line calling the function that
00160     #      called this function
00161     if DEBUG:
00162         warnings.warn(msg, UserWarning, level)
00163 
00164 def deprecated(msg, level=3):
00165     # level is the stack level
00166     #   1: the line below
00167     #   2: the line calling this function
00168     #   3: the line calling the function that
00169     #      called this function
00170     if DEBUG:
00171         warnings.warn(msg, DeprecationWarning, level)
00172 
00173 _default_logger = ClassLog()
00174 _zlogger = ZLogger()
00175 
00176 log = zlog = _zlogger.log
00177 log_exc    = _zlogger.log_exc