あるクラスで呼び出しが行われたときにデバッグ情報をログに記録したい。ログに記録されるデータは次のとおりです。
- 関数名
- 関数が呼び出された場所のスタックトレース
- 関数の実行にかかった時間
- 関数に渡されるargsとkwargs
ラッパーをかなり汎用的にしたいと思います。同時に、ラッピングは実行時に実行する必要があります。情報をログに記録し、呼び出しを元のインスタンスに委任する次のラッパークラスを作成しました。
import datetime
import traceback
from functools import partial
from logging_module import db_log
class BaseWrapper(object):
def __init__(self, item):
self._item = item
def __getattr__(self, attr):
return getattr(self._item, attr)
class DBLogWrapper(BaseWrapper):
@staticmethod
def _time_method(method):
name = "{0}.{1}.{2}".format(
method.im_class.__module__,
method.im_class.__name__,
method.__name__
)
def timed_method(self, *args, **kwargs):
begin = datetime.datetime.now()
return_val = method.im_func(self, *args, **kwargs)
end = datetime.datetime.now()
trace = traceback.format_stack()
db_log(
name,
begin,
end,
info={
'args': args,
'kwargs': kwargs,
'trace': trace
}
)
return return_val
return timed_method
def __init__(self, item, methods):
super(DBLogWrapper, self).__init__(item)
for method in methods:
class_method = getattr(item, method)
wrapped_method = DBLogWrapper._time_method(class_method)
wrapped_method = partial(wrapped_method, self._item)
setattr(self, method, wrapped_method)
使用例:
class MyClass(object):
def hello(self, greeting):
print greeting
def goodbye(self):
print 'Good Bye'
a = MyClass()
if DEBUG:
a = DBLogWrapper(a, ['hello'])
a.hello()
a.goodbye()
この場合、への呼び出しhello
はログに記録されますが、への呼び出しは記録されgoodbye
ません。
ただし、これは単純なはずのタスクにはやり過ぎのようです。上記のコードを改善する方法、またはそれを実行するためのまったく異なる方法についての提案を探しています。