【问题标题】:Python logger not output to filePython记录器不输出到文件
【发布时间】:2020-03-08 02:25:04
【问题描述】:

我的 logging.ini 文件可能有问题。我的 python 代码适用于另一个文件,但不是这个。

Python 运行这个main.py

# main.py
import logging
from logging.config import fileConfig

import my_module

# load the logging configuration
fileConfig('logging.ini')

my_module.foo()
bar = my_module.Bar()
bar.bar()

另一个具有自定义方法的文件

# my_module.py
import logging

def foo():
    logger = logging.getLogger(__name__)
    logger.info('Hi, foo')

class Bar(object):
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def bar(self):
        self.logger.info('Hi, bar')
        self.logger.debug('Testing')

我试过这个logging.ini 文件,它工作正常

keys=root

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

然后我想保存一些日志到文件,并打印一些到控制台,所以我在这里尝试了另一个logging.ini文件

[loggers]
keys=root,sLogger

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=consoleFormatter,fileFormatter


[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_sLogger]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=sLogger
propagate=0


[handler_consoleHandler]
class=StreamHandler
level=WARNING
formatter=consoleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=fileFormatter
args=('display_info.log','w')


[formatter_consoleFormatter]
format=%(levelname)s - %(message)s
datefmt=

[formatter_fileFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=

就是这样执行的

python main.py

这次程序运行良好,没有错误。但是display_info.log没有登录。有人可以帮我解决这个问题吗?谢谢!

【问题讨论】:

  • 所以文件叫display_info,但是级别是DEBUG。您对文件的意图是什么?
  • @FrankMerrow 我猜 OP 在发送信息级别消息时遇到了问题,并且正在使用调试级别进行调试

标签: python logging output ini


【解决方案1】:

这是因为您试图通过__name__ 获取记录器,它不是"__main__",而是“my_module”。您没有它的密钥,因此未配置记录器。更改您的 getLogger 以调用正确的 qualname,sLogger,它会抓住正确的名称:

import logging

def foo():
    # here
    logger = logging.getLogger("sLogger")
    logger.info('Hi, foo')

class Bar(object):
    def __init__(self, logger=None):
        # or here
        self.logger = logger or logging.getLogger("sLogger")

    def bar(self):
        self.logger.info('Hi, bar')
        self.logger.debug('Testing')

这会以您给它的名称(它在 .ini 文件中指向的 key)调用记录器。现在你的display_info.log 文件应该是这样的:

# display_info.log

2020-03-07 22:14:45,351 - sLogger - INFO - Hi, foo
2020-03-07 22:14:45,351 - sLogger - INFO - Hi, bar
2020-03-07 22:14:45,351 - sLogger - DEBUG - Testing

原因是每个记录器都有一个名称,因此当您调用logging.getLogger(<some_name>) 时,该记录器实际上就是您给它的名称。然后,当您从其他模块调用该记录器时,它已经可用。

__name__ 属性不是记录器的名称,而是您正在运行的脚本的名称。当你调用python somescript.py 时,somescript.__name____main__,因为它是被调用的主模块。但是通过导入,__name__ 是模块的名称,因为它没有被执行。所以,实际上,发生的事情是这样的:

import logging

''' these two are created when you load the .ini file '''
# this is aliased as root
main_logger = logging.getLogger("__main__")
~ some logging configuration ~

# the other logger you configured
sLogger = logging.getLogger("sLogger")
~ some logging configuration ~
''' and are in global scope in the main script '''

# and the logger you were getting by mistake
logger = logging.getLogger("my_module")


# when you really meant to do this
# which is the same thing as sLogger
logger = logging.getLogger("sLogger")

或者,如果您想保留 __name__ 语法并拥有特定于模块的记录器,那么您只需将模块的名称添加为 qualnames:

# logging.ini
~ snip ~

[logger_sLogger]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=my_module
propagate=0

~ rest of file ~

您可以继续拨打logging.getLogger(__name__)

# my_module.py
import logging

def foo():
    logger = logging.getLogger(__name__)
    logger.info('Hi, foo')

class Bar(object):
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def bar(self):
        self.logger.info('Hi, bar')
        self.logger.debug('Testing')

【讨论】:

  • @WFL np!如果您想通过原始 __name__ 语法跟踪,我添加了更多信息
  • 谢谢!那么这是否意味着如果我有其他几个 .py 文件,那么我需要将它们的所有名称添加到我的 .ini 文件中?
  • @WFL 如果你想保留__name__ 语法,那么可以
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 2019-04-24
  • 2017-04-13
  • 1970-01-01
  • 2015-07-26
  • 1970-01-01
  • 2012-11-23
相关资源
最近更新 更多