简体   繁体   English

Python 记录器/处理程序配置错误?

[英]Python loggers/handlers misconfigured?

Though I have been working with python/ipython for some time now, I consider myself a newb.虽然我已经使用 python/ipython 有一段时间了,但我认为自己是一个新手。 There are still many things, especially about the logging support, I thought I understood from the documentation, but apparently are more difficult to configure than I previously had hoped.还有很多东西,特别是关于日志记录的支持,我想我从文档中理解了,但显然比我以前希望的更难配置。 I am using ipython 5.5.0 / python 2.7.17 on Xubuntu 18.04.04 LTS with the colorlogs.我在ipython 5.5.0 / python 2.7.17 on Xubuntu 18.04.04 LTS 2.7.17。 My logging configuration module is below.我的日志记录配置模块如下。

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')

The configuration is held in a yaml file with the following definitions.配置保存在具有以下定义的 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

The following snippet of my test.py module follows.下面是我的 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()

My questions are, when I change the configuration as I did from [console_out] to [console_basic], I expected the messages to conform, but they do not.我的问题是,当我将配置从 [console_out] 更改为 [console_basic] 时,我希望消息符合要求,但事实并非如此。 Leading me to believe that some other logger, root(?), is handling the call?让我相信其他一些记录器 root(?) 正在处理呼叫? But, if I change that to use [console_basic] the messages are still the same.但是,如果我将其更改为使用 [console_basic] 消息仍然是相同的。 That is, one would expect the time and levelname to no longer be there, but they are!也就是说,人们会期望 time 和 levelname 不再存在,但它们确实存在! 在此处输入图像描述

Again, I do not pretend to understand what's going on, but where I thought the documentation showed simple inheritance I am beginning to wonder it's a bit more complicated than that.同样,我不会假装理解发生了什么,但我认为文档显示简单 inheritance 我开始怀疑它比这更复杂一些。 What am I doing wrong?我究竟做错了什么?

When I fix my spelling mistake and remove the logger for test, I still get the same behavior.当我修复拼写错误并删除记录器进行测试时,我仍然得到相同的行为。 Turning propagation on so that console logs will got to root logger, which has [console_basic] still shows the messages using the old format.打开传播,以便控制台日志将到达根记录器,它具有 [console_basic] 仍然使用旧格式显示消息。 在此处输入图像描述

Making the following changes to my yaml, seems to fix the issues, as pointed out by @blues.正如@blues 所指出的,对我的 yaml 进行以下更改似乎可以解决问题。

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

There is two things going on here.这里有两件事。 First of all there is a misspelling of propagate in the config.首先,配置中的propagate拼写错误。 It is wrongly spelled prop o gate: notice the "o" where an "a" should be.它是错误拼写的 prop o gate:注意应该是“a”的“o”。 That means all the loggers do in fact propagate their logs up the hierarchy.这意味着所有记录器实际上都会将其日志向上传播。

The second thing is that when propagation is on, the level of the ancestor loggers, in this case the root logger, is ignored and only the level of the handlers is taken into consideration.第二件事是,当传播打开时,祖先记录器的级别,在这种情况下是根记录器,被忽略,只考虑处理程序的级别。 Since the console_err handler that is added to root has level DEBUG and all logs propagate to root this handler will log every log.由于添加到 root 的console_err处理程序具有级别DEBUG并且所有日志都传播到 root,因此此处理程序将记录每个日志。

The relevant piece of information can be found the python documentation here :相关信息可在此处的 python 文档中找到:

Messages are passed directly to the ancestor loggers' handlers - neither the level nor filters of the ancestor loggers in question are considered.消息直接传递给祖先记录器的处理程序 - 既不考虑所讨论的祖先记录器的级别也不考虑过滤器。

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

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