繁体   English   中英

Python中跨多个模块的按对象记录

[英]Per-object logging across multiple modules in 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文件?

罪魁祸首是如何调用getLogger函数。 您有两次这样做:

  1. logger = logging.getLogger(name) my_object.py logger = logging.getLogger(name)
  2. _log = logging.getLogger(__name__)toolbox.py

如果比较那些调用返回的对象,则它们是2个单独的对象(您可以通过print(id(obj))打印它们的地址)。 这就是logger从不调用工具箱内的行的原因-那里有另一个记录器( _log )!

要解决您的错误,只需为您的记录器提供相同的名称-例如“ global”:

  1. logger = logging.getLogger("global")
  2. _log = logging.getLogger("global")

现在,文件的输出如下:

global -  INFO - object1 is doing something
global -  INFO - Using some tool for object1

在您的特定示例中,您可以将toolbox.py的代码调整为:

import logging


def use_tool(name):
    _log = logging.getLogger(name)
    _log.info('Using some tool for {}'.format(name))

并将记录器my_object.py保留在my_object.py中( logger = logging.getLogger(name) )。 如果然后在main.py执行以下main.py

obj = MyObject('object1')
obj2 = MyObject('object2')
obj.do_something()
obj2.do_something()

您最终将获得2个日志文件:

object1.log

object1 -  INFO - object1 is doing something
object1 -  INFO - Using some tool for object1

object2.log

object2 -  INFO - object2 is doing something
object2 -  INFO - Using some tool for object2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM