用户在使用 Python 进行多模块日志记录时遇到了问题。在不同的模块中分别编写了类和函数,并使用 logging 库进行日志记录,但只有根日志器(root logger)的日志被写入,而其他模块的日志无法正常输出。
以下是一个极简示例,其中包含了多个模块 a.py、b.py、ab.py 以及主程序 main_one.py:
# a.py
import logging
logger = logging.getLogger(__name__)
class A(object):
def __init__(self):
logger.debug("Instance of A")
# b.py
import logging
logger = logging.getLogger(__name__)
class B(object):
def __init__(self):
logger.debug("Instance of B")
# ab.py
import a
import b
import logging
logger = logging.getLogger(__name__)
class AB(a.A, b.B):
def __init__(self):
logger.debug("Instance of AB")
a.A.__init__(self)
b.B.__init__(self)
# main_one.py
import sys
import ab
import logging
import logging.handlers
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(stream=sys.stderr)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(name)s: %(message)s'))
logger.addHandler(handler)
logger.warning("The trouble starts")
ab = ab.AB()
用户已经尝试了多种方法,例如在每个类中使用单独的日志器,但仍然无法解决问题。
解决方案
- 确保模块层次结构合理
确保模块层次结构合理,以便 name 属性能够正确反映模块的位置。例如,如果将模块放在不同的目录中,则 name 将是一个带有句点的分层值。
以下是一个示例,其中模块层次结构组织良好:
main_one.py
lib/
__init__.py
ab.py
basic/
__init__.py
a.py
b.py
- 在所有模块中使用相同的日志器名称
在所有模块中使用相同的日志器名称,以便日志能够正确地聚合到一起。在示例中,可以在 main_one.py 中使用以下代码来创建日志器:
logger = logging.getLogger('daniel_lib')
- 将日志器添加到根日志器
将日志器添加到根日志器,以便日志能够被正确地输出。在示例中,可以在 main_one.py 中使用以下代码来将日志器添加到根日志器:
logging.getLogger().addHandler(handler)
- 设置日志级别
设置日志级别,以便能够控制哪些日志被输出。在示例中,可以将日志级别设置为 DEBUG,以便能够输出所有日志:
logger.setLevel(logging.DEBUG)
- 测试代码
在做出这些改动之后,就可以测试代码并查看日志输出是否正确。如果日志输出正确,则问题就已解决。
以下是一些代码示例,演示了如何实现上述解决方案:
# main_one.py
import sys
import ab
import logging
import logging.handlers
logger = logging.getLogger('daniel_lib')
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(stream=sys.stderr)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(name)s: %(message)s'))
logger.addHandler(handler)
logging.getLogger().addHandler(handler)
logger.warning("The trouble starts")
ab = ab.AB()
# a.py
import logging
logger = logging.getLogger('daniel_lib')
class A(object):
def __init__(self):
logger.debug("Instance of A")
# b.py
import logging
logger = logging.getLogger('daniel_lib')
class B(object):
def __init__(self):
logger.debug("Instance of B")
# ab.py
import a
import b
import logging
logger = logging.getLogger('daniel_lib')
class AB(a.A, b.B):
def __init__(self):
logger.debug("Instance of AB")
a.A.__init__(self)
b.B.__init__(self)
通过这些修改,现在可以正常地输出日志,并能够看到来自不同模块的日志。