Python loggershandlers配置错误?

问题描述 投票:0回答:1

虽然我使用pythonipython已经有一段时间了,但我认为自己是个新手。 还有很多东西,特别是关于日志支持的,我以为我从文档中了解了,但显然比我之前希望的更难配置。 我使用的是 ipython 5.5.0 / python 2.7.17 on Xubuntu 18.04.04 LTS 与colorlogs。 我的日志配置模块如下。

import coloredlogs
import datetime
import logging
import logging.config
import os
import yaml

def setup_logging( default_path='../Config/logging.yaml',
                   default_level=logging.DEBUG,
                   env_key='LOG_CFG'):

  path = os.path.join(os.path.dirname(os.path.realpath(__file__)), default_path)
  value = os.getenv(env_key, None)

  # If the envvar is set, use it's value
  if value:
    path = value

  _dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  print("%s Using Logging Configuration: %s" % (_dt, path) )

  #
  # If the configuration file path is there, read it
  #
  if os.path.exists(path):
    with open(path, 'rt') as f:
      try:
        config = yaml.safe_load(f.read())
        logging.config.dictConfig(config)
        coloredlogs.install(level=default_level)
      except Exception as err:
        print(err)
        print('Error in Logging Configuration. Using default configs')
        logging.basicConfig(level=default_level)
        coloredlogs.install(level=default_level)

  # Otherwise, continue without a configuration
  else:
    logging.basicConfig(level=logging.DEBUG)
    coloredlogs.install(level=logging.DEBUG)
    print('Failed to load configuration file. Using default configs')

配置保存在一个yaml文件中,定义如下。

version: 1
disable_existing_loggers: False

formatters:
    basic:
        format: "%(name)s - %(message)s"
    standard:
        format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    error:
        format: "%(levelname)s <PID %(process)d:%(processName)s> %(name)s.%(funcName)s(): %(message)s"

handlers:
    console_basic:
        class: logging.StreamHandler
        level: DEBUG
        formatter: basic
        stream: ext://sys.stdout

    console_out:
        class: logging.StreamHandler
        level: DEBUG
        formatter: standard
        stream: ext://sys.stdout

    console_err:
        class: logging.StreamHandler
        level: DEBUG
        formatter: standard
        stream: ext://sys.stderr

    debug_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: DEBUG
        formatter: standard
        filename: /tmp/debug.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    info_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: INFO
        formatter: standard
        filename: /tmp/info.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    warn_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: WARN
        formatter: standard
        filename: /tmp/warn.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    error_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: ERROR
        formatter: error
        filename: /tmp/errors.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

    critical_file_handler:
        class: logging.handlers.RotatingFileHandler
        level: CRITICAL
        formatter: standard
        filename: /tmp/critical.log
        maxBytes: 10485760 # 10MB
        backupCount: 20
        encoding: utf8

root:
    level: CRITICAL
    handlers: [console_err]
    propogate: no

loggers:
  test:
    level: DEBUG
    handlers: [console_basic]
    propogate: no

  Utils.paragraph_processing:
    level: DEBUG
    handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
    propogate: no

  Utils.graphing_functions:
    level: DEBUG
    handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
    propogate: no

下面是我的test.py模块的片段。

import coloredlogs
from copy import deepcopy
import cv2
import imutils
import logging
import logging.config
import os
import yaml

import matplotlib.pyplot as PLT
import matplotlib.image as MPI
import numpy as np

import Tests.filtering_tests as FT
import Tests.morphology_tests as MT

import Utils.global_defs as GL
import Utils.graphing_functions as GF
import Utils.paragraph_processing as PP
import Utils.logging_functions as LF

.
.
.
def phony_main():
  LF.setup_logging()
  # create logger
  LOG = logging.getLogger(__name__)

  LOG.critical("Logging Started...")


# -----------------------------------------------------------------------------
#
# Main
#
img = None

if __name__ == "__main__":
    # execute only if run as a script
    phony_main()

我的问题是,当我把配置从[console_out]改成[console_basic]时,我希望消息能符合要求,但它们没有。 这让我相信是其他的记录器,root(?)在处理调用? 但是,如果我把它改成使用[console_basic],消息还是一样。也就是说,人们会期望时间和级别名称不再存在,但它们确实存在!我再次强调,我并不假装自己是在使用[console_basic]。enter image description here

再次强调,我并不假装理解发生了什么,但我认为文档中显示的是简单的继承,我开始怀疑它比这更复杂。 我到底做错了什么?

当我修正了我的拼写错误并移除测试用的记录器时,我仍然得到了同样的行为。 开启传播功能,让控制台的日志能传到根目录下,而根目录下有[console_basic],但还是会用旧的格式显示信息。enter image description here

对我的 yaml 做了以下修改,似乎解决了 @blues 指出的问题。

root:
    level: NOTSET
    handlers: [console_basic]
    propagate: no

loggers:
  __main__:
    level: DEBUG
    handlers: [console_basic]
    propagate: no

  Utils.paragraph_processing:
    level: DEBUG
    handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
    propagate: no

  Utils.graphing_functions:
    level: DEBUG
    handlers: [info_file_handler, debug_file_handler, warn_file_handler, error_file_handler, critical_file_handler]
    propagate: no
python logging configuration ipython handler
1个回答
1
投票

这里面有两个问题。首先,有一个拼写错误的 propagate 的配置中。它被错误地拼写为propogate:请注意 "o "的位置应该是 "a"。这意味着所有的日志记录者实际上都会将他们的日志向上传播。

第二件事是,当传播开启时,祖先日志记录器的级别,在本例中是根日志记录器,会被忽略,只考虑处理程序的级别。由于 console_err 添加到root的处理程序具有级别 DEBUG 和所有的日志都会传播到root,这个处理程序会记录每一条日志。

相关信息可以在python文档中找到。此处:

信息直接传递给祖先记录仪的处理程序--既不考虑有关祖先记录仪的级别,也不考虑其过滤器。

© www.soinside.com 2019 - 2024. All rights reserved.