在哪里配置日志记录?

Sym*_*nen 5 python logging project

我想知道在哪里配置和初始化与日志记录模块相关的内容?

例如,我编写了一些类,并且想在执行方法时记录一些信息。我应该在模块顶部的init或以上类中配置登录:

# LOGGING STUFF <--- Should be here ? 

class SomeClass:

    def __init__(self):
        # class stuff
        # LOGGING STUFF <--- Or should be here ? 

    def some_method(self):
        # method stuff
        # LOGGING SOME INFO    

    def some_method2(self):
        # method stuff
        # LOGGING SOME INFO
Run Code Online (Sandbox Code Playgroud)

最佳做法是什么?

Guy*_*emi 6

日志记录包有两个目的,帮助作者创建日志和帮助用户使用日志。您可能会同时扮演这两个角色,但是分别考虑它们将有助于您编写简洁易懂的代码。

作者关注

作者应在正确的级别实例化记录器:

  • 包记录器应进入包__init__文件。注意使用__name__,它将解析为SomePackage

    import logging
    package_logger = logging.getLogger(__name__)
    
    Run Code Online (Sandbox Code Playgroud)
  • 模块顶部的模块记录器。注意的力量__name__!在这里它将解决SomePackage.SomeModule

    import logging
    module_logger = logging.getLogger(__name__)
    
    Run Code Online (Sandbox Code Playgroud)
  • 类级别记录器可以进入一个类__init__(或使用一个meta-class)。注意__name__getLogger增强的强大功能!记录器的名称为SomePackage.SomeModule.SomeClass。另外,不要使用下划线_class_logger来表示它仅供内部使用。

    class SomeClass:
        def __init__(self):
            self._class_logger = logging.getLogger(__name__).getChild(self.__class__.__name__)
    
    Run Code Online (Sandbox Code Playgroud)
  • 类中的实例记录器__init__。使用ID产生唯一的标识符。注意stupend ...您就知道了。记录器名称为SomePackage.SomeModule.SomeClass.<large_unique_number>

    class SomeClass:
        def __init__(self):
            self._instance_logger = logging.getLogger(__name__).getChild(self.__class__.__name__).getChild(id(self))
    
    Run Code Online (Sandbox Code Playgroud)

名称可能不适合您的应用程序。例如,您可能想要一个实例记录器,该实例记录器是从其实例化arg之一派生的。但是,您仍应努力使记录器处于适当的水平。

用户关注

配置处理程序是“用户”工作。通常,作者将确保默认情况下没有处理程序处于活动状态。logging.basicConfig会将所有级别警告及以上的所有日志记录转储至stderr。

import SomePackage
import logging

logging.basicConfig()
Run Code Online (Sandbox Code Playgroud)

记住,您可以使用logging.getLogger()来访问作者定义的相同记录器。

from SomePackage import SomeModule
import logging

# module_logger debug to a file 
h = logging.FileHandler('debug')
h.setLevel('DEBUG')
SomeModule.module_logger.addHandler(h)

# class_logger warning to stderr
h = logging.StreamHandler()
getLogger('SomePackage.SomeModule.SomeClass').addHandler(h)
Run Code Online (Sandbox Code Playgroud)

如果要通过直接调用它们来调试自己的模块,则可能有一个def main(),它们应该放在那里。这样可以确保程序包用户不会收到意外的日志文件或控制台消息。