|
Lines 34-58
Link Here
|
| 34 |
|
34 |
|
| 35 |
example: |
35 |
example: |
| 36 |
|
36 |
|
| 37 |
>>> import univention.debug as ud |
37 |
>>> f = init('stdout', NO_FLUSH, FUNCTION) #doctest: +ELLIPSIS |
| 38 |
>>> ud.init("stdout", ud.NO_FLUSH, ud.FUNCTION) #doctest: +ELLIPSIS |
|
|
| 39 |
... ... DEBUG_INIT |
38 |
... ... DEBUG_INIT |
| 40 |
>>> ud.set_level(ud.LISTENER, ud.ERROR) |
39 |
>>> set_level(LISTENER, ERROR) |
| 41 |
>>> ud.debug(ud.LISTENER, ud.ERROR, 'Fatal error: var=%s' % 42) #doctest: +ELLIPSIS |
|
|
| 42 |
... ... LISTENER ( ERROR ) : Fatal error: var=42 |
| 43 |
""" |
40 |
""" |
| 44 |
|
41 |
|
| 45 |
import _debug |
42 |
from __future__ import absolute_import |
| 46 |
from _debug import * |
43 |
from sys import exc_info |
|
|
44 |
from functools import wraps |
| 45 |
from itertools import chain |
| 46 |
from warnings import warn |
| 47 |
from univention import _debug |
| 48 |
from univention._debug import * # noqa F403 |
| 47 |
|
49 |
|
| 48 |
|
50 |
|
| 49 |
def debug(id, level, ustring, utf8=True): |
51 |
def debug(id, level, ustring, utf8=True): |
|
|
52 |
""" |
| 53 |
Log message 'ustring' of severity 'level' to facility 'id'. |
| 54 |
|
| 55 |
:param int id: ID of the category, e.g. MAIN, LDAP, USERS, ... |
| 56 |
:param int level: Level of logging, e.g. ERROR, WARN, PROCESS, INFO, ALL |
| 57 |
:param str ustring: The message to log. |
| 58 |
:param bool utf8: Assume the message is UTF-8 encoded. |
| 59 |
|
| 60 |
>>> debug(LISTENER, ERROR, 'Fatal error: var=%s' % 42) #doctest: +ELLIPSIS |
| 61 |
... ... LISTENER ( ERROR ) : Fatal error: var=42 |
| 62 |
""" |
| 50 |
_debug.debug(id, level, ustring) |
63 |
_debug.debug(id, level, ustring) |
| 51 |
|
64 |
|
| 52 |
|
65 |
|
| 53 |
class function: |
66 |
class function: |
|
|
67 |
""" |
| 68 |
Log function call begin and end. |
| 69 |
|
| 70 |
Deprecated in favor of :py:class:`trace`. |
| 71 |
|
| 72 |
>>> def my_func(agr1, agr2=None): |
| 73 |
... _d = function('my_func(...)') |
| 74 |
... return 'yes' |
| 75 |
>>> my_func(42) |
| 76 |
'yes' |
| 77 |
""" |
| 54 |
|
78 |
|
| 55 |
def __init__(self, text, utf8=True): |
79 |
def __init__(self, text, utf8=True): |
|
|
80 |
warn('univention.debug.function is deprecated and will be removed with UCS-5', PendingDeprecationWarning) |
| 56 |
self.text = text |
81 |
self.text = text |
| 57 |
_debug.begin(self.text) |
82 |
_debug.begin(self.text) |
| 58 |
|
83 |
|
|
Lines 60-65
class function:
Link Here
|
| 60 |
_debug.end(self.text) |
85 |
_debug.end(self.text) |
| 61 |
|
86 |
|
| 62 |
|
87 |
|
|
|
88 |
def trace(with_args=True, with_return=False, repr=object.__repr__): |
| 89 |
""" |
| 90 |
Log function call, optional with arguments and result. |
| 91 |
|
| 92 |
:param bool with_args: Log function arguments. |
| 93 |
:param bool with_return: Log function result. |
| 94 |
:param repr: Function accepting a single object and returing a string representation for the given object. Defaults to :py:func:`object.__repr__`, alternative :py:func:`repr`. |
| 95 |
|
| 96 |
>>> @trace(with_args=True, with_return=True) |
| 97 |
... def my_func(arg1, arg2=None): |
| 98 |
... return 'yes' |
| 99 |
>>> my_func(42) |
| 100 |
'yes' |
| 101 |
>>> class MyClass(object): |
| 102 |
... @trace(with_args=True, with_return=True, repr=repr) |
| 103 |
... def my_meth(self, arg1, arg2=None): |
| 104 |
... return 'yes' |
| 105 |
>>> MyClass().my_meth(42) |
| 106 |
'yes' |
| 107 |
>>> @trace() |
| 108 |
... def my_bug(): |
| 109 |
... 1 / 0 |
| 110 |
>>> my_bug() |
| 111 |
Traceback (most recent call last): |
| 112 |
... |
| 113 |
ZeroDivisionError: integer division or modulo by zero |
| 114 |
""" |
| 115 |
def decorator(f): |
| 116 |
@wraps(f) |
| 117 |
def wrapper(*args, **kwargs): |
| 118 |
fname = '%s.%s' % (f.__module__, f.__name__) |
| 119 |
_args = ', '.join( |
| 120 |
chain( |
| 121 |
(repr(arg) for arg in args), |
| 122 |
('%s=%s' % (k, repr(v)) for (k, v) in kwargs.iteritems()), |
| 123 |
) |
| 124 |
) if with_args else '...' |
| 125 |
|
| 126 |
_debug.begin('%s(%s): ...' % (fname, _args)) |
| 127 |
try: |
| 128 |
ret = f(*args, **kwargs) |
| 129 |
except: |
| 130 |
try: |
| 131 |
(exctype, value) = exc_info()[:2] |
| 132 |
_debug.end('%s(...): %s(%s)' % (fname, exctype, value)) |
| 133 |
finally: |
| 134 |
exctype = value = None |
| 135 |
raise |
| 136 |
else: |
| 137 |
_debug.end('%s(...): %s' % (fname, repr(ret) if with_return else '...')) |
| 138 |
return ret |
| 139 |
|
| 140 |
return wrapper |
| 141 |
|
| 142 |
return decorator |
| 143 |
|
| 144 |
|
| 63 |
if __name__ == '__main__': |
145 |
if __name__ == '__main__': |
| 64 |
import doctest |
146 |
import doctest |
| 65 |
doctest.testmod() |
147 |
doctest.testmod() |
| 66 |
- |
|
|