|
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 |
|
|
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 |
- |
|
|