我的项目在根包下嵌套了一个子包,如下所示:
mypackage/
__init__.py
topmodule.py
subpackage/
__init__.py
nested.py
我的目标是使记录记录的格式如下:
mypackage/topmodule.py:123: First log message
mypackage/subpackage/nested.py:456: Second log message
以便在我的终端中单击路径。
我尝试了以下格式。
'%(modulename).pys:%(lineno): %(message)s'
不可点击(点必须为斜线):
mypackage.topmodule.py:123: First log message
mypackage.subpackage.nested.py:456: Second log message
'mypackage/%(filename)s:%(lineno): %(message)s'
不适用于子软件包:
mypackage/topmodule.py:123: First log message
mypackage/nested.py:456: Second log message
'%(pathname)s:%(lineno): %(message)s'
产生可单击的路径,但是它们的时间太长,以至于切断了我的其余日志记录:
/Users/jacebrowning/Documents/mypackage/topmodule.py:123: First log message
/Users/jacebrowning/Documents/mypackage/subpackage/nested.py:456: Second log message
是否可以传递给logging.basicConfig(format='???')
的日志记录模式来生成所需的日志记录?
答案 0 :(得分:4)
您必须进行其他处理才能在此处获得所需的路径。
您可以执行这样的处理,并通过创建custom filter将其他信息添加到日志记录中,包括您自己程序包的“本地”路径。
过滤器实际上并没有必须进行过滤,但是它们确实可以访问所有日志记录,因此它们是一种更新缺少信息的记录的好方法。只要确保完成后返回True
:
import logging
import os
import sys
class PackagePathFilter(logging.Filter):
def filter(self, record):
pathname = record.pathname
record.relativepath = None
abs_sys_paths = map(os.path.abspath, sys.path)
for path in sorted(abs_sys_paths, key=len, reverse=True): # longer paths first
if not path.endswith(os.sep):
path += os.sep
if pathname.startswith(path):
record.relativepath = os.path.relpath(pathname, path)
break
return True
这将在日志记录中找到sys.path
条目,该条目是pathname
的父目录,并在日志记录中添加一个新的relativepath
条目。然后,您可以使用%(relativepath)s
将其包括在日志中。
将过滤器添加到您使用自定义格式化程序配置的任何处理程序:
handler.addFilter(PackagePathFilter())
,并与'%(relativepath)s:%(lineno)s: %(message)s'
一起作为日志消息的格式,如下所示:
mypackage/topmodule.py:123: First log message
mypackage/subpackage/nested.py:456: Second log message
(实际输出,除了我改变了它的行号)。