【问题标题】:Where is a complete example of logging.config.dictConfig?logging.config.dictConfig 的完整示例在哪里?
【发布时间】:2011-11-22 09:31:55
【问题描述】:

我想使用dictConfig,但文档有点抽象。我在哪里可以找到与dictConfig 一起使用的字典的具体、可复制+粘贴示例?

【问题讨论】:

    标签: python logging python-logging


    【解决方案1】:

    这里怎么样!对应的文档参考是configuration-dictionary-schema

    LOGGING_CONFIG = { 
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': { 
            'standard': { 
                'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
            },
        },
        'handlers': { 
            'default': { 
                'level': 'INFO',
                'formatter': 'standard',
                'class': 'logging.StreamHandler',
                'stream': 'ext://sys.stdout',  # Default is stderr
            },
        },
        'loggers': { 
            '': {  # root logger
                'handlers': ['default'],
                'level': 'WARNING',
                'propagate': False
            },
            'my.packg': { 
                'handlers': ['default'],
                'level': 'INFO',
                'propagate': False
            },
            '__main__': {  # if __name__ == '__main__'
                'handlers': ['default'],
                'level': 'DEBUG',
                'propagate': False
            },
        } 
    }
    

    用法:

    import logging.config
    
    # Run once at startup:
    logging.config.dictConfig(LOGGING_CONFIG)
    
    # Include in each module:
    log = logging.getLogger(__name__)
    log.debug("Logging is configured.")
    

    如果您看到来自第三方包的日志过多,请务必在导入第三方包之前使用logging.config.dictConfig(LOGGING_CONFIG) 运行此配置。

    要使用日志过滤器向每条日志消息添加额外的自定义信息,请考虑this answer

    【讨论】:

    • 还有一个替代位置可以指定root 记录器:在字典的顶层。它在docs 中有描述,当两者都存在时优先于['loggers'][''],但在我看来,['loggers'][''] 更合乎逻辑。另见讨论here
    • python logging.config 文档中所有那些简洁、漂亮的 YAML sn-ps 无法直接阅读。无赖。
    • 这不是 django 特有的吗?如果我使用不同的框架(Flask、Bottle 等),或者甚至不使用 Web 应用程序怎么办?
    • 这感觉就像'disable_existing_loggers': False 的作弊因为你可能没有配置它整块布,但可能重用已经存在的东西.. 如果你将它设置为 True 那么我不'似乎没有任何输出。
    • 可恢复的错误怎么样?错误不应出现在标准输出中。仅用于程序输出。
    【解决方案2】:

    logging cookbook examples 中声明了一个 logging.config.dictConfig() dictionary schema 的更新示例。从该食谱链接向上滚动以查看 dictConfig() 的用法。

    这是一个使用 StreamHandler 和 RotatingFileHandler 以及自定义 formatdatefmt 记录到标准输出和“日志”子目录的示例用例。

    1. 导入模块并建立到“logs”子目录的跨平台绝对路径

      from os.path import abspath, dirname, join
      import logging
      from logging.config import dictConfig
      base_dir = abspath(dirname(__file__))
      logs_target = join(base_dir + "\logs", "python_logs.log")
      
    2. 根据dictionary schema 文档建立架构。

      logging_schema = {
          # Always 1. Schema versioning may be added in a future release of logging
          "version": 1,
          # "Name of formatter" : {Formatter Config Dict}
          "formatters": {
              # Formatter Name
              "standard": {
                  # class is always "logging.Formatter"
                  "class": "logging.Formatter",
                  # Optional: logging output format
                  "format": "%(asctime)s\t%(levelname)s\t%(filename)s\t%(message)s",
                  # Optional: asctime format
                  "datefmt": "%d %b %y %H:%M:%S"
              }
          },
          # Handlers use the formatter names declared above
          "handlers": {
              # Name of handler
              "console": {
                  # The class of logger. A mixture of logging.config.dictConfig() and
                  # logger class-specific keyword arguments (kwargs) are passed in here. 
                  "class": "logging.StreamHandler",
                  # This is the formatter name declared above
                  "formatter": "standard",
                  "level": "INFO",
                  # The default is stderr
                  "stream": "ext://sys.stdout"
              },
              # Same as the StreamHandler example above, but with different
              # handler-specific kwargs.
              "file": {  
                  "class": "logging.handlers.RotatingFileHandler",
                  "formatter": "standard",
                  "level": "INFO",
                  "filename": logs_target,
                  "mode": "a",
                  "encoding": "utf-8",
                  "maxBytes": 500000,
                  "backupCount": 4
              }
          },
          # Loggers use the handler names declared above
          "loggers" : {
              "__main__": {  # if __name__ == "__main__"
                  # Use a list even if one handler is used
                  "handlers": ["console", "file"],
                  "level": "INFO",
                  "propagate": False
              }
          },
          # Just a standalone kwarg for the root logger
          "root" : {
              "level": "INFO",
              "handlers": ["file"]
          }
      }
      
    3. 使用字典架构配置logging

      dictConfig(logging_schema)
      
    4. 尝试一些测试用例,看看是否一切正常

      if __name__ == "__main__":
          logging.info("testing an info log entry")
          logging.warning("testing a warning log entry")
      

    【讨论】:

    • 如果想跨多个模块使用模式,这将如何工作?我认为它是在使用它的模块中声明的?
    【解决方案3】:

    接受的答案很好!但是,如果可以从不那么复杂的东西开始呢?日志模块是非常强大的东西,文档有点压倒性,尤其是对于新手。但是一开始你不需要配置格式化程序和处理程序。当你弄清楚你想要什么时,你可以添加它。

    例如:

    import logging.config
    
    DEFAULT_LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'loggers': {
            '': {
                'level': 'INFO',
            },
            'another.module': {
                'level': 'DEBUG',
            },
        }
    }
    
    logging.config.dictConfig(DEFAULT_LOGGING)
    
    logging.info('Hello, log')
    

    【讨论】:

    • 这是更相关/更有用的例子,至少在我的情况下。是最后一个logging.info('Hello, log') 让我觉得很开心。文档中的混乱之处在于,使用 dictConfig 我们不再需要执行 getLogger 或任何这些操作。
    • @theotheo 你能解释一下空键 '': { 'level': 'INFO'... 以及为什么没有它就不能工作(例如,将空白值更改为有效值时,例如 standard
    • @MikeWilliamson:不过,如果您想要多个具有不同名称的记录器,仍然调用getLogger() 会很有用。这些记录器中的每一个都从根记录器继承配置。
    • @MikeWilliamson getLogger 始终是可选的。当直接使用logging.info() 方法时,使用根记录器,而使用getLogger(),您可以拥有不同的记录器,具有不同的名称和级别。
    【解决方案4】:

    流处理程序、文件处理程序、旋转文件处理程序和 SMTP 处理程序的示例

    from logging.config import dictConfig
    
    LOGGING_CONFIG = {
        'version': 1,
        'loggers': {
            '': {  # root logger
                'level': 'NOTSET',
                'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler', 'critical_mail_handler'],
            },
            'my.package': { 
                'level': 'WARNING',
                'propagate': False,
                'handlers': ['info_rotating_file_handler', 'error_file_handler' ],
            },
        },
        'handlers': {
            'debug_console_handler': {
                'level': 'DEBUG',
                'formatter': 'info',
                'class': 'logging.StreamHandler',
                'stream': 'ext://sys.stdout',
            },
            'info_rotating_file_handler': {
                'level': 'INFO',
                'formatter': 'info',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': 'info.log',
                'mode': 'a',
                'maxBytes': 1048576,
                'backupCount': 10
            },
            'error_file_handler': {
                'level': 'WARNING',
                'formatter': 'error',
                'class': 'logging.FileHandler',
                'filename': 'error.log',
                'mode': 'a',
            },
            'critical_mail_handler': {
                'level': 'CRITICAL',
                'formatter': 'error',
                'class': 'logging.handlers.SMTPHandler',
                'mailhost' : 'localhost',
                'fromaddr': 'monitoring@domain.com',
                'toaddrs': ['dev@domain.com', 'qa@domain.com'],
                'subject': 'Critical error with application name'
            }
        },
        'formatters': {
            'info': {
                'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
            },
            'error': {
                'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
            },
        },
    
    }
    
    dictConfig(LOGGING_CONFIG)
    

    【讨论】:

      【解决方案5】:

      我在下面找到Django v1.11.15 默认配置,希望对您有所帮助

      DEFAULT_LOGGING = {
          'version': 1,
          'disable_existing_loggers': False,
          'filters': {
              'require_debug_false': {
                  '()': 'django.utils.log.RequireDebugFalse',
              },
              'require_debug_true': {
                  '()': 'django.utils.log.RequireDebugTrue',
              },
          },
          'formatters': {
              'django.server': {
                  '()': 'django.utils.log.ServerFormatter',
                  'format': '[%(server_time)s] %(message)s',
              }
          },
          'handlers': {
              'console': {
                  'level': 'INFO',
                  'filters': ['require_debug_true'],
                  'class': 'logging.StreamHandler',
              },
              'django.server': {
                  'level': 'INFO',
                  'class': 'logging.StreamHandler',
                  'formatter': 'django.server',
              },
              'mail_admins': {
                  'level': 'ERROR',
                  'filters': ['require_debug_false'],
                  'class': 'django.utils.log.AdminEmailHandler'
              }
          },
          'loggers': {
              'django': {
                  'handlers': ['console', 'mail_admins'],
                  'level': 'INFO',
              },
              'django.server': {
                  'handlers': ['django.server'],
                  'level': 'INFO',
                  'propagate': False,
              },
          }
      }
      

      【讨论】:

      • 这个例子很好,但我认为要在公认的答案之外脱颖而出,一些解释会有所帮助。
      猜你喜欢
      • 2011-10-20
      • 1970-01-01
      • 2019-07-22
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 2015-02-25
      • 1970-01-01
      相关资源
      最近更新 更多