1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
from itertools import chain
import inspect
import logging
import os
from openlmi.software.yumdb import errors
class DispatchingFormatter:
def __init__(self, formatters, default):
for k, formatter in formatters.items():
if isinstance(formatter, basestring):
formatters[k] = logging.Formatter(formatter)
self._formatters = formatters
if isinstance(default, basestring):
default = logging.Formatter(default)
self._default_formatter = default
def format(self, record):
formatter = self._formatters.get(record.name, self._default_formatter)
return formatter.format(record)
# *****************************************************************************
# Decorators
# *****************************************************************************
def trace_function(func):
"""
Decorator for logging entries and exits of function or method.
"""
if not inspect.ismethod(func) and not inspect.isfunction(func):
raise TypeError("func must be a function")
def _print_value(val):
"""
Used here for printing function arguments. Shortens the output
string, if that would be too long.
"""
if isinstance(val, list):
if len(val) < 2:
return str(val)
else:
return "[%s, ...]" % _print_value(val[0])
return str(val)
logger = logging.getLogger(__name__+'.trace_function')
module = func.__module__.split('.')[-1]
lineno = inspect.currentframe().f_back.f_lineno
def _wrapper(self, *args, **kwargs):
"""
Wrapper for function or method, that does the logging.
"""
if logger.isEnabledFor(logging.DEBUG):
frm = inspect.currentframe()
logargs = {
"caller_file" : os.path.basename(os.path.splitext(
frm.f_back.f_code.co_filename)[0]),
"caller_lineno" : frm.f_back.f_lineno,
"module" : module,
"func" : func.__name__,
"lineno" : lineno,
"action" : "entering",
"args" : ", ".join(chain(
(_print_value(a) for a in args),
( "%s=%s"%(k, _print_value(v))
for k, v in kwargs.items())))
}
if not logargs["args"]:
logargs["args"] = ""
else:
logargs["args"] = " with args=(%s)" % logargs["args"]
logger.debug("%(caller_file)s:%(caller_lineno)d - %(action)s"
" %(module)s:%(func)s:%(lineno)d%(args)s" , logargs)
try:
result = func(self, *args, **kwargs)
if logger.isEnabledFor(logging.DEBUG):
logargs["action"] = "exiting"
logger.debug("%(caller_file)s:%(caller_lineno)d - %(action)s"
" %(module)s:%(func)s:%(lineno)d", logargs)
except Exception as exc:
logargs['action'] = 'exiting'
logargs['error'] = str(exc)
logger.debug("%(caller_file)s:%(caller_lineno)d - %(action)s"
" %(module)s:%(func)s:%(lineno)d with error: %(error)s",
logargs)
raise
return result
return _wrapper
def setup_logging(config):
try:
logging.config.dictConfig(config)
except Exception: #pylint: disable=W0703
# logging is not set up but client expects us to work
pass
|