在 Python 中跨多个模块的每个对象日志记录

我有一个 Python 代码,它实现了一个用于处理独立数据集的类。对于每个数据集,我从类中实例化一个对象,该对象处理数据集。我想实现一个日志记录功能,在控制台和与每个数据集一起存储的日志文件中显示日志消息。


我在模块级别实现了一个根记录器,并在创建每个对象时实现了一个带有 FileHandler 的特定记录器。它可以记录课堂内部发生的一些信息,但我也在使用另一个工具箱模块,那里发生的事情只记录在控制台中,而不是记录在日志文件中。


为了说明这个问题,我实现了一个演示模块:


├──log

│  ├── __init__.py

│  ├── my_object.py

│  ├── toolbox.py

内容__init__.py:


import logging


logging.basicConfig(format='%(name)12s - %(levelname)5s - %(message)s')

_log = logging.getLogger(__name__)

_log.setLevel(logging.DEBUG)

内容my_object.py:


import logging

from . import toolbox


class MyObject():

    def __init__(self, name):

        self._name = name


        # configure logging

        logger = logging.getLogger(name)

        logger.setLevel(logging.DEBUG)

        if logger.hasHandlers():

            for hdlr in logger.handlers:

                logger.removeHandler(hdlr)


        handler = logging.FileHandler('/home/user/Desktop/test/{}.log'.format(name), mode='w', encoding='utf-8')

        formatter = logging.Formatter('%(name)12s - %(levelname)5s - %(message)s')

        handler.setFormatter(formatter)

        logger.addHandler(handler)


        self._logger = logger



    def do_something(self):

        self._logger.info('{} is doing something'.format(self._name))


        toolbox.use_tool(self._name)

内容toolbox.py:


import logging


_log = logging.getLogger(__name__)



def use_tool(name):

    _log.info('Using some tool for {}'.format(name))

然后,我运行这个:


import log

from log.my_object import MyObject


obj = MyObject('object1')

obj.do_something()

这是我在控制台中得到的:


     object1 -  INFO - object1 is doing something

 log.toolbox -  INFO - Using some tool for object1

这是我在/home/user/Desktop/test/object1.log文件中得到的:


     object1 -  INFO - object1 is doing something

如何让 log.toolbox 也显示在object1.log文件中?


慕码人8056858
浏览 163回答 1
1回答

千巷猫影

罪魁祸首在于你如何调用getLogger函数。你有两次这样做:logger = logging.getLogger(name)里面my_object.py_log = logging.getLogger(__name__)里面toolbox.py如果您比较这些调用返回的对象,它们是 2 个独立的对象(您可以通过 打印它们的地址print(id(obj)))。这就是为什么logger从不调用工具箱内的行 - 那里有一个不同的记录器(_log)!要修复您的错误,只需为您的记录器提供相同的名称 - 例如“全局”:logger = logging.getLogger("global")_log = logging.getLogger("global")该文件的输出现在如下:global -  INFO - object1 is doing somethingglobal -  INFO - Using some tool for object1在您的具体示例中,您可以将代码调整toolbox.py为:import loggingdef use_tool(name):    _log = logging.getLogger(name)    _log.info('Using some tool for {}'.format(name))并将记录器留在里面my_object.py(logger = logging.getLogger(name))。如果您随后在 中执行以下操作main.py:obj = MyObject('object1')obj2 = MyObject('object2')obj.do_something()obj2.do_something()你最终会得到 2 个日志文件:对象1.logobject1 -  INFO - object1 is doing somethingobject1 -  INFO - Using some tool for object1对象2.logobject2 -  INFO - object2 is doing somethingobject2 -  INFO - Using some tool for object2
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python