Ticket #1089: sugar-base-trace.patch
File sugar-base-trace.patch, 3.5 KB (added by sascha_silbe, 15 years ago) |
---|
-
src/sugar/logger.py
diff --git a/src/sugar/logger.py b/src/sugar/logger.py index a27a9be..2ad1717 100644
a b 20 20 STABLE. 21 21 """ 22 22 23 import __builtin__ 24 import array 25 import collections 23 26 import errno 27 import logging 24 28 import sys 25 29 import os 26 import logging 30 import repr 31 import decorator 32 33 34 # new loglevel TRACE for tracing function calls 35 # use SUGAR_LOGGER_LEVEL=trace to enable 36 TRACE=5 37 logging.addLevelName(TRACE, 'TRACE') 38 27 39 28 40 # Let's keep this self contained so that it can be easily 29 41 # pasted in external sugar service like the datastore. … … def get_logs_dir(): 38 50 _levels = { 'error' : logging.ERROR, 39 51 'warning' : logging.WARNING, 40 52 'debug' : logging.DEBUG, 41 'info' : logging.INFO } 53 'info' : logging.INFO, 54 'trace' : TRACE, 55 'all' : 0, 56 } 42 57 def set_level(level): 43 58 if level in _levels: 44 59 logging.getLogger('').setLevel(_levels[level]) … … def _except_hook(exctype, value, traceback): 61 76 sys.excepthook = sys.__excepthook__ 62 77 63 78 sys.excepthook(exctype, value, traceback) 64 79 65 80 def start(log_filename=None): 66 81 # remove existing handlers, or logging.basicConfig() won't have no effect. 67 82 root_logger = logging.getLogger('') 68 83 for handler in root_logger.handlers: 69 84 root_logger.removeHandler(handler) 70 85 71 86 class SafeLogWrapper(object): 72 87 """Small file-like wrapper to gracefully handle ENOSPC errors when 73 88 logging.""" … … def start(log_filename=None): 116 131 117 132 sys.excepthook = _except_hook 118 133 134 135 class TraceRepr(repr.Repr) : 136 137 # better handling of subclasses of basic types, e.g. for DBus 138 _types = [int, long, bool, tuple, list, array.array, set, frozenset, 139 collections.deque, dict, str] 140 def repr1(self, x, level): 141 for t in self._types : 142 if isinstance(x, t) : 143 return getattr(self, 'repr_'+t.__name__)(x, level) 144 145 return repr.Repr.repr1(self, x, level) 146 147 def repr_int(self, x, level) : 148 return __builtin__.repr(x) 149 150 def repr_bool(self, x, level) : 151 return __builtin__.repr(x) 152 153 154 def trace(logger=None, logger_name=None, skip_args=[], skip_kwargs=[], 155 maxsize_list=30, maxsize_dict=30, maxsize_string=300) : 156 157 # size-limit repr() 158 _trace_repr = TraceRepr() 159 _trace_repr.maxlist = maxsize_list 160 _trace_repr.maxdict = maxsize_dict 161 _trace_repr.maxstring = maxsize_string 162 _trace_repr.maxother = maxsize_string 163 _trace_logger = logger or logging.getLogger(logger_name) 164 165 def _trace(f, *args, **kwargs) : 166 # don't do expensive formatting if loglevel TRACE is not enabled 167 enabled = _trace_logger.isEnabledFor(TRACE) 168 if enabled : 169 params_formatted = ", ".join( 170 [_trace_repr.repr(a) 171 for (idx, a) in enumerate(args) if idx not in skip_args]+\ 172 ['%s=%s' % (k,_trace_repr.repr(v)) 173 for (k,v) in kwargs.items() if k not in skip_kwargs]) 174 175 _trace_logger.log(TRACE, "%s(%s) invoked", f.__name__, 176 params_formatted) 177 178 try : 179 res=f(*args, **kwargs) 180 except : 181 _trace_logger.exception("Exception occured in %s", f.__name__) 182 raise 183 184 if enabled : 185 _trace_logger.log(TRACE, "%s(%s) returned %s", f.__name__, 186 params_formatted, _trace_repr.repr(res)) 187 188 return res 189 190 return decorator.decorator(_trace) 191 192