Python 如何让logging decorator记录它所在的文件名';是否使用了,而不是定义在何处?
我使用Python 如何让logging decorator记录它所在的文件名';是否使用了,而不是定义在何处?,python,logging,Python,Logging,我使用日志记录模块和文件名格式来捕获代码的日志输出。这很好,因为现在我总是知道消息是从哪个文件发送的。但是,我有一个缩进日志装饰器,我希望实际记录使用它的文件名,而不是定义装饰器的模块。这可能吗 下面是一个简短的例子,说明它现在正在做什么: test.py 日志输出 现在,我希望所有三条消息都包含test.py如下所示: 期望输出 log.py 通过复制标准库的日志模块使用的一些代码检查,我能够自动生成文件名和开始/结束消息。我删除了手册的开始和结束消息,认为这更符合您的意图。我还从日志格式中删
日志记录
模块和文件名
格式来捕获代码的日志输出。这很好,因为现在我总是知道消息是从哪个文件发送的。但是,我有一个缩进日志装饰器,我希望实际记录使用它的文件名,而不是定义装饰器的模块。这可能吗
下面是一个简短的例子,说明它现在正在做什么:
test.py
日志输出
现在,我希望所有三条消息都包含test.py
如下所示:
期望输出
log.py
通过复制标准库的日志模块使用的一些代码检查,我能够自动生成文件名和开始/结束消息。我删除了手册的开始和结束消息,认为这更符合您的意图。我还从日志格式中删除了文件名,并将其添加到缩进装饰器记录的文本中
def indented():
def indent_decorator(func):
@wraps(func)
def func_wrapper(*args, **kwargs):
filename = os.path.basename(func.__code__.co_filename)
logger.info(filename + ': begin ' + func.__name__)
with indent_logging():
output = func(*args, **kwargs)
logger.info(filename + ': end ' + func.__name__)
return output
return func_wrapper
return indent_decorator
这是日志输出
2018-12-31 08:14:25.536 [ INFO ] test.py: begin my_func
2018-12-31 08:14:25.536 [ INFO ] ---- Look, a message!
2018-12-31 08:14:25.536 [ INFO ] test.py: end my_func
我不知道我们能在多大程度上依赖于代码在python的未来版本中保持不变,但这在3.6.5中对我很有用
我怀疑它应该进一步简化,这样您就不必在装饰器上添加paren,这样可能会在以后进行编辑。我注意到,在c:\Python36\Lib\logging\u init\uupy.py中,它通过直接检查“findCaller”中的堆栈来获取文件名,并发现第一件不在该文件中的东西。更改日志模块本身是正确的,所以我现在被困在那里,正要睡觉。通过适配器的调用发生在log.py中,但它仍然会找到test.py。可能需要定义自己的格式变量并额外传递它。顺便说一句,我发现在调试时使用stream=sys.stdout更容易
2018-07-27 13:27:15.541 [ INFO ] test.py: Here I start my method...
2018-07-27 13:27:15.541 [ INFO ] test.py: ---- Look, a message!
2018-07-27 13:27:15.541 [ INFO ] test.py: And here it ends
import logging
from contextlib import contextmanager
from functools import wraps
class IndentationAdapter(logging.LoggerAdapter):
def __init__(self, logger, extra):
super().__init__(logger, extra)
self._indent = 0
def indent(self):
self._indent += 4
def dedent(self):
self._indent -= 4
def process(self, msg, kwargs):
if self._indent > 0:
return '{i} {m}'.format(i='-'*self._indent, m=msg), kwargs
else:
return msg, kwargs
logger = IndentationAdapter(logging.getLogger(), {})
@contextmanager
def indent_logging():
logger.indent()
try:
yield
finally:
logger.dedent()
def indented(begin_message, end_message):
def indent_decorator(func):
@wraps(func)
def func_wrapper(*args, **kwargs):
logger.info(begin_message)
with indent_logging():
output = func(*args, **kwargs)
logger.info(end_message)
return output
return func_wrapper
return indent_decorator
def indented():
def indent_decorator(func):
@wraps(func)
def func_wrapper(*args, **kwargs):
filename = os.path.basename(func.__code__.co_filename)
logger.info(filename + ': begin ' + func.__name__)
with indent_logging():
output = func(*args, **kwargs)
logger.info(filename + ': end ' + func.__name__)
return output
return func_wrapper
return indent_decorator
2018-12-31 08:14:25.536 [ INFO ] test.py: begin my_func
2018-12-31 08:14:25.536 [ INFO ] ---- Look, a message!
2018-12-31 08:14:25.536 [ INFO ] test.py: end my_func