使用日志中的模块名登录多个类

2024-04-18 07:11:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用日志模块,而不是打印调试信息和文档。 目标是在控制台上以调试级别打印并记录到具有信息级别的文件。

我阅读了很多关于日志模块的文档、菜谱和其他教程,但不知道如何才能按照我想要的方式使用它。(我在Python上)

我想知道在我的日志文件中写入日志的模块的名称。

文档中说我应该使用logger = logging.getLogger(__name__),但是如何声明在其他模块/包中的类中使用的记录器,以便它们使用与主记录器相同的处理程序?为了识别父类,我可以使用logger = logging.getLogger(parent.child)但是我在哪里知道,谁调用了类/方法?`

下面的例子显示了我的问题,如果我运行这个命令,输出将只有__main__登录,而忽略Class登录

这是我的main文件:

# main.py

import logging
from module import Class

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# create file handler which logs info messages
fh = logging.FileHandler('foo.log', 'w', 'utf-8')
fh.setLevel(logging.INFO)

# create console handler with a debug log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# creating a formatter
formatter = logging.Formatter('- %(name)s - %(levelname)-8s: %(message)s')

# setting handler format
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)

if __name__ == '__main__':
    logger.info('Script starts')
    logger.info('calling class Class')
    c = Class()
    logger.info('calling c.do_something()')
    c.do_something()
    logger.info('calling c.try_something()')
    c.try_something()

模块:

# module.py

imnport logging

class Class:
    def __init__(self):
        self.logger = logging.getLogger(__name__) # What do I have to enter here?
        self.logger.info('creating an instance of Class')
        self.dict = {'a':'A'}
    def do_something(self):
        self.logger.debug('doing something')
        a = 1 + 1
        self.logger.debug('done doing something')
    def try_something(self):
        try:
            logging.debug(self.dict['b'])
        except KeyError, e:
            logging.exception(e)

控制台中的输出:

- __main__ - INFO    : Script starts
- __main__ - INFO    : calling class Class
- __main__ - INFO    : calling c.do_something()
- __main__ - INFO    : calling c.try_something()
No handlers could be found for logger "module"

另外:如果日志记录在我的日志文件中,而不在上面的每个类中声明一个新的日志记录程序,那么是否有方法获取模块名?同样地,每次我想记录一些东西时,我都必须使用self.logger.info()。我希望在整个代码中使用logging.info()logger.info()

全球伐木者也许是正确的答案?但这样我就无法得到日志中出现错误的模块。。。

最后一个问题:这是Python吗?或者有更好的建议来做正确的事情。


Tags: 模块文件nameselfinfomainlogging记录
2条回答

在您的主模块中,您正在配置名称为'__main__'(或者在您的情况下等同于__name__)的记录器,而在module.py中,您正在使用不同的记录器。您要么需要为每个模块配置日志记录器,要么可以在主模块中配置根日志记录器(通过配置logging.getLogger()),默认情况下,根日志记录器将应用于项目中的所有日志记录器。

我建议使用配置文件来配置记录器。这个链接应该能给你一个良好实践的好主意:http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python

编辑:在格式化程序中使用%(module)将模块名称包含在日志消息中。

您应该有一个全局记录器和处理程序:

logger= logging.getLogger("myapp")
#configure handlers

然后,在每个模块上:

logger= logging.getLogger("myapp."+__name__)

是否需要每个类的记录器取决于您-我看到的大多数项目(最多)每个模块都有一个记录器。我的建议是,如果不同的类不需要不同的处理程序,那么请坚持每个模块使用一个记录器,或者甚至每个项目使用一个记录器—如果项目很小。

如果日志中需要更多上下文,请注意,可以在格式化程序上使用%(funcName)s打印当前函数名

相关问题 更多 >