设置日志记录级别
Posted
技术标签:
【中文标题】设置日志记录级别【英文标题】:Set logging levels 【发布时间】:2016-11-27 00:48:43 【问题描述】:我正在尝试使用标准库来调试我的代码:
这很好用:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info('message')
我无法让较低级别的记录器工作:
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.info('message')
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug('message')
我没有得到任何回应。
【问题讨论】:
【参考方案1】:什么 Python 版本?这在 3.4 中对我有用。但请注意,basicConfig() 不会影响已设置的根处理程序:
如果根记录器已经为其配置了处理程序,则此函数不执行任何操作。
要在 root 上显式设置级别,请执行 logging.getLogger().setLevel(logging.DEBUG)
。但请确保您事先已调用basicConfig()
,以便根记录器最初进行一些设置。即:
import logging
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
logging.getLogger('foo').debug('bah')
logging.getLogger().setLevel(logging.INFO)
logging.getLogger('foo').debug('bah')
还请注意,“记录器”和它们的“处理程序”都具有不同的独立日志级别。因此,如果您之前在 Python 脚本中显式加载了一些复杂的记录器配置,并且与根记录器的处理程序混淆,那么这可能会产生影响,并且仅使用 logging.getLogger().setLevel(..)
更改记录器日志级别可能不会工作。这是因为附加的处理程序可能具有独立设置的日志级别。这种情况不太可能发生,您通常不必担心。
【讨论】:
您现在可以向 basicConfig 发送force=True
以使其工作,即使它已经设置好了。【参考方案2】:
我使用以下设置进行日志记录
基于 Yaml 的配置
像这样创建一个名为 logging.yml 的 yaml 文件
version: 1
formatters:
simple:
format: "%(name)s - %(lineno)d - %(message)s"
complex:
format: "%(asctime)s - %(name)s - %(lineno)d - %(message)s"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
file:
class: logging.handlers.TimedRotatingFileHandler
when: midnight
backupCount: 5
level: DEBUG
formatter: simple
filename : Thrift.log
loggers:
qsoWidget:
level: INFO
handlers: [console,file]
propagate: yes
__main__:
level: DEBUG
handlers: [console]
propagate: yes
Python - 主要
“主”模块应如下所示
import logging.config
import logging
with open('logging.yaml','rt') as f:
config=yaml.safe_load(f.read())
f.close()
logging.config.dictConfig(config)
logger=logging.getLogger(__name__)
logger.info("Contest is starting")
子模块/类
这些应该像这样开始
import logging
class locator(object):
def __init__(self):
self.logger = logging.getLogger(__name__)
self.logger.debug(' initialized')
希望对你有帮助...
【讨论】:
qsoWidget
只是您应用的名称吗?
在__init__.py
中包含所有日志配置不是最佳做法吗?这是一个问题。
我会说 - 您应该尝试将日志记录设置放在项目中可能的最高点。然后让依赖的模块使用它。这样你就有了一致的日志记录。对每个模块执行模块将导致不同级别、不同的日志格式输出。这将使下游日志处理(Humio、Splunk、PIG)变得更加困难。
很好的例子!谢谢你。通过 .yaml 设置记录器配置听起来是一个非常有效的解决方案
@AlexSkorokhod 我认为 yaml 是可读的,但是将日志记录在外部文件中,可以让您在不接触代码的情况下改变日志级别。【参考方案3】:
在我看来,这是大多数情况下的最佳方法。
通过 INI 文件配置
在项目根目录下创建文件名logging.ini
,如下:
[loggers]
keys=root
[logger_root]
level=DEBUG
handlers=screen,file
[formatters]
keys=simple,verbose
[formatter_simple]
format=%(asctime)s [%(levelname)s] %(name)s: %(message)s
[formatter_verbose]
format=[%(asctime)s] %(levelname)s [%(filename)s %(name)s %(funcName)s (%(lineno)d)]: %(message)s
[handlers]
keys=file,screen
[handler_file]
class=handlers.TimedRotatingFileHandler
interval=midnight
backupCount=5
formatter=verbose
level=WARNING
args=('debug.log',)
[handler_screen]
class=StreamHandler
formatter=simple
level=DEBUG
args=(sys.stdout,)
然后配置如下:
import logging
from logging.config import fileConfig
fileConfig('logging.ini')
logger = logging.getLogger('dev')
name = "***"
logger.info(f"Hello name!")
logger.critical('This message should go to the log file.')
logger.error('So should this.')
logger.warning('And this, too.')
logger.debug('Bye!')
如果您运行脚本,sysout
将是:
2021-01-31 03:40:10,241 [INFO] dev: Hello ***!
2021-01-31 03:40:10,242 [CRITICAL] dev: This message should go to the log file.
2021-01-31 03:40:10,243 [ERROR] dev: So should this.
2021-01-31 03:40:10,243 [WARNING] dev: And this, too.
2021-01-31 03:40:10,243 [DEBUG] dev: Bye!
而debug.log
文件应包含:
[2021-01-31 03:40:10,242] CRITICAL [my_loger.py dev <module> (12)]: This message should go to the log file.
[2021-01-31 03:40:10,243] ERROR [my_loger.py dev <module> (13)]: So should this.
[2021-01-31 03:40:10,243] WARNING [my_loger.py dev <module> (14)]: And this, too.
全部完成。
【讨论】:
【参考方案4】:我想将默认记录器保留在警告级别,但我的代码有详细的低级记录器。但它不会显示任何东西。在另一个答案的基础上,事先运行logging.basicConfig()
至关重要。
import logging
logging.basicConfig()
logging.getLogger('foo').setLevel(logging.INFO)
logging.getLogger('foo').info('info')
logging.getLogger('foo').debug('info')
logging.getLogger('foo').setLevel(logging.DEBUG)
logging.getLogger('foo').info('info')
logging.getLogger('foo').debug('debug')
预期输出
INFO:foo:info
INFO:foo:info
DEBUG:foo:debug
对于跨模块的日志记录解决方案,我这样做了
# cfg.py
import logging
logging.basicConfig()
logger = logging.getLogger('foo')
logger.setLevel(logging.INFO)
logger.info(f'active')
# main.py
import cfg
cfg.logger.info(f'main')
【讨论】:
以上是关于设置日志记录级别的主要内容,如果未能解决你的问题,请参考以下文章