日志层次结构与根记录器?

61

在我的代码某个深处,我有类似这样的东西:

logger = logging.getLogger('debug0.x')

我理解的方式是,只有当我之前做过类似以下操作时,它才会响应:

logging.basicConfig(filename='10Nov2010a.txt',level=logging.DEBUG, name='debug0')

请注意,name已被定义为debug0。然而,我发现如果这样做
logging.basicConfig(filename='10Nov2010a.txt',level=logging.DEBUG)

没有使用名称关键字,那么上面定义的debug0.x记录器会响应并写入日志文件。我曾经认为它只在第一种情况下响应,即记录器已被命名。

我感到困惑。


6
logging.basicConfig()方法没有name关键字参数。 - Sven Marnach
2个回答

126

Python的logging模块将日志记录器组织成层次结构。 所有的日志记录器都是根日志记录器的子孙。每个日志记录器将日志消息传递给它的父级。

使用getLogger()函数创建新的日志记录器。函数调用logging.getLogger('debug0.x')将创建一个名为x的日志记录器,它是debug0的子级,而debug0本身是根日志记录器的子级。 当记录到此记录器时,它将把消息传递给其父级,其父级将把消息传递给根日志记录器。您可以使用basicConfig()函数来配置根日志记录器将日志记录到文件中,因此您的消息最终将出现在那里。


1
那么在Python中获取记录器的最佳实践是什么?在Java中,您只需执行getLogger(getClass()。getName())(或一些方便的方法getLogger(getClass()),它委托给我提到的其他方法)。在Python中应该使用什么?我们肯定不必为每个模块编写一些记录器ID并手动插入。 - Garret Wilson
14
在Python中,最常见的方法是在每个模块的顶部使用logger = logging.getLogger(__name__)。变量__name__包含当前模块的点分名称。 - Sven Marnach
1
有什么原因最佳实践不是使用“_logger”,这样当模块被导入时变量就不会暴露出来? - Garret Wilson
@GarretWilson 有些人也使用 _loggerLOGGER,所以这取决于你。你还可以设置 __all__ 来声明导出名称的列表。 - Sven Marnach

18

如果你查看代码或文档:

>>> print logging.basicConfig.__doc__

    Do basic configuration for the logging system.

    This function does nothing if the root logger already has handlers
    configured. ...............
    A number of optional keyword arguments may be specified, which can alter
    the default behaviour.

    filename  Specifies that a FileHandler be created, using the specified
              filename, rather than a StreamHandler.
    filemode  Specifies the mode to open the file, if filename is specified
              (if filemode is unspecified, it defaults to 'a').
    format    Use the specified format string for the handler.
    datefmt   Use the specified date/time format.
    level     Set the root logger level to the specified level.
    stream    Use the specified stream to initialize the StreamHandler. Note
              that this argument is incompatible with 'filename' - if both
              are present, 'stream' is ignored.

logging.basicConfig方法根本不使用name参数。它初始化了根记录器。而getLogger方法需要一个"name"参数。

>>> print logging.getLogger.__doc__

    Return a logger with the specified name, creating it if necessary.

    If no name is specified, return the root logger.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接