logging-Python 的日志记录工具

源代码: Lib/logging/init.py

Important

此页面包含 API 参考信息。有关教程信息和更多高级主题的讨论,请参见


该模块定义函数和类,这些函数和类为应用程序和库实现了灵活的事件日志记录系统。

由标准库模块提供的日志记录 API 的主要好处是所有 Python 模块都可以参与日志记录,因此您的应用程序日志可以包括您自己的消息以及与第三方模块的消息集成的消息。

该模块提供了很多Function和灵 Active。如果您不熟悉日志记录,那么最好的方法是查看教程(请参阅右侧的链接)。

下面列出了模块定义的基本类及其Function。

  • Logger 公开了应用程序代码直接使用的接口。

  • 处理程序将日志记录(由 Logger 创建)发送到适当的目的地。

  • 筛选器提供了更细粒度的Function,用于确定要输出的日志记录。

  • 格式化程序在finally输出中指定日志记录的布局。

Logger Objects

Logger 具有以下属性和方法。请注意,Logger 不应直接实例化,但应始终pass模块级函数logging.getLogger(name)实例化。对具有相同名称的getLogger()的多次调用将始终返回对同一 Logger 对象的引用。

name可能是句点分隔的分层值,例如foo.bar.baz(尽管例如也可以是普通foo)。层次结构列表中位于最下方的 Logger 是列表中较高位置的 Logger 的子级。例如,给定名称为foo的 Logger,名称为foo.barfoo.bar.bazfoo.bam的 Logger 都是foo的后代。记录程序名称层次结构类似于 Python 包层次结构,如果您使用推荐的结构logging.getLogger(__name__)在每个模块的基础上组织记录程序,则该记录程序名称层次结构也相同。这是因为在模块中,__name__是 Python 包命名空间中模块的名称。

  • 类别 logging. Logger
      • propagate
      • 如果此属性评估为 true,则除了附加到此 Logger 的任何处理程序之外,记录到该 Logger 的事件还将传递到更高级别(祖先)Logger 的处理程序。消息直接传递给祖先 Logger 的处理程序-既不考虑所讨论祖先 Logger 的级别也没有过滤器。

如果此结果为 false,则不会将日志记录消息传递给祖先 Logger 的处理程序。

构造函数将此属性设置为True

Note

如果将处理程序附加到 Logger及其一个或多个祖先,它可能会多次发出相同的记录。通常,您不需要将一个处理程序附加到一个以上的 Logger 上-如果仅将它附加到 Logger 层次结构中最高的适当 Logger 上,则它将看到所有后代 Logger 记录的所有事件,前提是它们的传播设置保留为True。一种常见的情况是仅将处理程序附加到根 Logger,并让传播来处理其余部分。

  • setLevel(级别)
    • 将此 Logger 的阈值设置为* level 。严重程度低于 level 的日志消息将被忽略;严重性为 level 或更高的日志消息将由服务该 Logger 的任何一个或多个处理程序发出,除非将处理程序的级别设置为比 level *更高的严重性级别。

创建 Logger 时,级别设置为NOTSET(当该 Logger 是根 Logger 时,将处理所有消息;如果该 Logger 是非根 Logger,则将委派给父级)。请注意,根 Logger 是使用WARNING级别创建的。

术语“委托给父代”是指如果 Logger 具有 NOTSET 级别,则遍历其祖先 Logger 链,直到找到非 NOTSET 级别的祖先或到达根为止。

如果发现某个祖先的级别不是 NOTSET,那么该祖先的级别将被视为祖先搜索开始的 Logger 的有效级别,并用于确定如何处理日志事件。

如果到达根目录,并且其级别为 NOTSET,则将处理所有消息。否则,将使用根的级别作为有效级别。

有关级别列表,请参见Logging Levels

在版本 3.2 中进行了更改:* level *参数现在接受级别的字符串表示形式,例如'INFO',以代替INFO等整数常量。但是请注意,级别在内部存储为整数,而方法例如getEffectiveLevel()isEnabledFor()将返回/期望被传递的整数。

  • isEnabledFor(级别)

    • 指示此 Logger 是否将处理严重性为* level *的消息。此方法首先检查由logging.disable(level)设置的模块级别级别,然后检查由getEffectiveLevel()确定的 Logger 的有效级别。
  • getEffectiveLevel ( )

    • 指示此 Logger 的有效级别。如果使用setLevel()设置了NOTSET以外的值,则返回该值。否则,将层次结构遍历到根,直到找到NOTSET以外的值,然后返回该值。返回的值是一个整数,通常为logging.DEBUGlogging.INFO等之一。
  • getChild(后缀)

    • 返回由后缀确定的 Logger,该 Logger 是该 Logger 的后代。因此,logging.getLogger('abc').getChild('def.ghi')将返回与logging.getLogger('abc.def.ghi')返回的 Logger 相同的 Logger。这是一种方便的方法,当使用诸如__name__而不是 Literals 字符串。

3.2 版中的新Function。

  • debug(* msg *, *args * kwargs *)
    • 在此 Logger 上记录一条级别为DEBUG的消息。 * msg 是消息格式字符串,而 args 是使用字符串格式运算符合并到 msg 中的参数。 (请注意,这意味着您可以在格式字符串中使用关键字以及单个字典参数.)如果未提供 args ,则不会对 msg *进行%格式化操作。
  • kwargs 中有四个关键字参数被检查: exc_info stack_info stacklevel extra *。

如果* exc_info *的评估结果不为 false,则会导致将异常信息添加到日志消息中。如果提供了一个异常 Tuples(由sys.exc_info()返回的格式)或一个异常实例,则使用它。否则,将调用sys.exc_info()以获取异常信息。

第二个可选关键字参数是* stack_info ,默认为False。如果为 true,则将堆栈信息添加到日志消息中,包括实际的日志调用。请注意,这与pass指定 exc_info *显示的堆栈信息不同:前者是从堆栈底部一直到当前线程中的日志记录调用的堆栈帧,而后者是有关已被使用的堆栈帧的信息。搜索异常处理程序时,在发生异常后解开卷。

您可以独立于* exc_info 来指定 stack_info *,例如仅显示您如何到达代码中的特定点,即使没有引发异常也是如此。堆栈框架在标题行之后打印:

Stack (most recent call last):

这模仿了显示异常帧时使用的Traceback (most recent call last):

第三个可选关键字参数是* stacklevel *,默认为1。如果大于 1,则在计算为日志记录事件创建的LogRecord中设置的行号和函数名称时,将跳过相应数量的堆栈帧。可以在记录帮助程序时使用它,以便记录的函数名称,文件名和行号不是帮助程序Function/方法的信息,而是其调用方的信息。此参数的名称反映了warnings模块中的等效参数。

第四个关键字参数是* extra *,可用于传递字典,该字典用于使用用户定义的属性填充为日志记录事件创建的LogRecord的__dict__。然后可以根据需要使用这些自定义属性。例如,可以将它们合并到已记录的消息中。例如:

FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logger = logging.getLogger('tcpserver')
logger.warning('Protocol problem: %s', 'connection reset', extra=d)

将打印类似

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset
  • extra *中传递的字典中的键不应与日志系统使用的键冲突。 (有关日志记录系统使用哪些键的更多信息,请参见Formatter文档。)

如果选择在已记录的消息中使用这些属性,则需要格外小心。例如,在上面的示例中,Formatter已使用格式字符串设置,该字符串期望LogRecord的属性字典中的“ clientip”和“ user”。如果缺少这些内容,则将不会记录该消息,因为会发生字符串格式化异常。因此,在这种情况下,您始终需要pass这些键传递* extra *词典。

尽管这可能很烦人,但是此Function旨在用于特殊情况,例如在多个上下文中执行相同代码的多线程服务器,并且出现的有趣条件取决于此上下文(例如,远程 Client 端 IP 地址和已验证用户名,在上面的示例中)。在这种情况下,很可能将专门的Formatter与特定的Handler一起使用。

在版本 3.2 中更改:添加了* stack_info *参数。

在版本 3.5 中更改:* exc_info *参数现在可以接受异常实例。

在版本 3.8 中更改:添加了* stacklevel *参数。

  • info(* msg *, *args * kwargs *)

    • 在此 Logger 上记录级别为INFO的消息。参数解释为debug()
  • warning(* msg *, *args * kwargs *)

    • 在此 Logger 上记录级别为WARNING的消息。参数解释为debug()

Note

有一种过时的方法warn在Function上与warning相同。由于warn已过时,请不要使用它-改用warning

  • error(* msg *, *args * kwargs *)

    • 在此 Logger 上记录级别为ERROR的消息。参数解释为debug()
  • critical(* msg *, *args * kwargs *)

    • 在此 Logger 上记录级别为CRITICAL的消息。参数解释为debug()
  • log((* level msg *, *args * kwargs *)

    • 在此 Logger 上记录整数级别为* level *的消息。其他参数的解释与debug()相同。
  • exception(* msg *, *args * kwargs *)

    • 在此 Logger 上记录级别为ERROR的消息。参数解释为debug()。异常信息将添加到日志消息中。仅应从异常处理程序中调用此方法。
  • addFilter(* filter *)

    • 将指定的过滤器* filter *添加到此 Logger。
  • removeFilter(* filter *)

    • 从此 Logger 中删除指定的过滤器* filter *。
  • filter(记录)

    • 将此 Logger 的过滤器应用于记录,如果要处理记录,则返回True。依次查询过滤器,直到其中一个返回假值为止。如果它们都不返回假值,则记录将被处理(传递给处理程序)。如果返回一个假值,则不会对该记录进行进一步处理。
  • addHandler(* hdlr *)

    • 将指定的处理程序* hdlr *添加到此 Logger。
  • removeHandler(* hdlr *)

    • 从此 Logger 中删除指定的处理程序* hdlr *。
  • findCaller(* stack_info = False stacklevel = 1 *)

    • 查找呼叫者的源文件名和线路号。以 4 元素 Tuples 的形式返回文件名,行号,函数名称和堆栈信息。除非* stack_info *为True,否则堆栈信息将以None的形式返回。
  • stacklevel *参数是pass调用debug()和其他 API 的代码传递的。如果大于 1,则多余部分将用于跳过堆栈帧,然后再确定要返回的值。当从帮助程序/包装程序代码调用日志记录 API 时,这通常很有用,因此事件日志中的信息不是指帮助程序/包装程序代码,而是指调用它的代码。
  • handle(记录)

    • pass将记录传递给与此 Logger 及其祖先关联的所有处理程序来处理记录(直到找到错误的* propagate *值)。此方法用于从套接字接收的未选择记录以及在本地创建的记录。Logger 级过滤使用filter()进行。
  • makeRecord((* name level fn lno msg args exc_info func = None extra = None sinfo = None *)

    • 这是一种工厂方法,可以在子类中对其进行重写以创建专门的LogRecord实例。
  • hasHandlers ( )

    • 检查此 Logger 是否配置了任何处理程序。这是pass在此 Logger 及其父 Logger 层次结构中查找处理程序来完成的。如果找到处理程序,则返回True,否则返回False。只要找到“ propagate”属性设置为 false 的 Logger,该方法就会停止搜索层次结构-这将是最后一个检查处理程序是否存在的 Logger。

3.2 版中的新Function。

在版本 3.7 中进行了更改:现在可以对 Logger 进行 Pickling 和取消 Pickling。

Logging Levels

下表中给出了日志记录级别的数值。如果您想定义自己的级别,并且需要它们具有相对于 sched 义级别的特定值,那么这些是最重要的。如果用相同的数值定义一个级别,它将覆盖 sched 义的值;sched 义名称丢失。

LevelNumeric value
CRITICAL50
ERROR40
WARNING30
INFO20
DEBUG10
NOTSET0

Handler Objects

处理程序具有以下属性和方法。注意Handler永远不会直接实例化;此类充当更有用的子类的基础。但是,子类中的init()方法需要调用Handler.init()

  • 类别 logging. Handler

      • __init__(* level = NOTSET *)
      • pass设置其级别,将过滤器列表设置为空列表并创建锁(使用createLock())来初始化对 I/O 机制的访问,从而初始化Handler实例。
  • createLock ( )

    • 初始化线程锁,该线程锁可用于序列化对可能不是线程安全的基础 I/O Function的访问。
  • acquire ( )

  • release ( )

  • setLevel(级别)

    • 将此处理程序的阈值设置为* level 。严重程度低于 level *的日志消息将被忽略。创建处理程序时,级别设置为NOTSET(这将处理所有消息)。

有关级别列表,请参见Logging Levels

在版本 3.2 中进行了更改:* level *参数现在接受级别的字符串表示形式,例如'INFO',以替代整数常量(例如__)。

  • setFormatter(* fmt *)

    • 将此处理程序的Formatter设置为* fmt *。
  • addFilter(* filter *)

    • 将指定的过滤器* filter *添加到此处理程序。
  • removeFilter(* filter *)

    • 从此处理程序中删除指定的过滤器* filter *。
  • filter(记录)

    • 将此处理程序的过滤器应用于记录,如果要处理记录,则返回True。依次查询过滤器,直到其中一个返回假值为止。如果它们都不返回假值,则将发出记录。如果返回一个假值,则处理程序将不会发出记录。
  • flush ( )

    • 确保已清除所有日志记录输出。此版本不执行任何操作,并且打算由子类实现。
  • close ( )

    • 整理处理程序使用的所有资源。此版本不输出,但从内部处理程序列表中删除处理程序,该内部处理程序在调用shutdown()时关闭。子类应确保从覆盖的close()方法中调用此方法。
  • handle(记录)

    • 根据可能已添加到处理程序的筛选器,有条件地发出指定的日志记录。用获取/释放 I/O 线程锁包装记录的实际运行。
  • handleError(记录)

    • emit()调用期间遇到异常时,应从处理程序中调用此方法。如果模块级属性raiseExceptionsFalse,则异常会被静默忽略。这是日志系统最需要的-大多数用户不会关心日志系统中的错误,他们对应用程序错误更感兴趣。但是,您可以根据需要将其替换为自定义处理程序。指定的记录是发生异常时正在处理的记录。 (raiseExceptions的默认值为True,因为它在开发过程中更有用)。
  • format(记录)

    • 对记录进行格式化-如果设置了格式化程序,请使用它。否则,请使用模块的默认格式化程序。
  • emit(记录)

    • 执行任何操作以实际记录指定的记录记录。此版本旨在由子类实现,因此引发NotImplementedError

有关标准随附的处理程序的列表,请参见logging.handlers

Formatter Objects

Formatter对象具有以下属性和方法。它们负责将LogRecord转换为(通常)可由人或外部系统解释的字符串。基本Formatter允许指定格式字符串。如果未提供任何参数,则使用默认值'%(message)s',它仅将消息包括在日志记录调用中。要在格式化输出中有其他信息项(例如时间戳记),请 continue 阅读。

格式化程序可以使用格式化字符串初始化,该字符串利用LogRecord属性的知识-例如上述默认值,它利用用户的消息和参数已预先格式化为LogRecord的* message *属性的事实。此格式字符串包含标准的 Python%样式 Map 键。有关字符串格式的更多信息,请参见printf 样式的字符串格式部分。

LogRecord中有用的 Map 键在LogRecord attributes的部分中给出。

    • class * logging. Formatter(* fmt = None datefmt = None style ='%'*)
    • 返回Formatter类的新实例。实例将使用整个消息的格式字符串以及消息的日期/时间部分的格式字符串进行初始化。如果未指定* fmt ,则使用'%(message)s'。如果未指定 datefmt *,则使用formatTime()文档中描述的格式。

在版本 3.2 中更改:添加了* style *参数。

在 3.8 版中进行了更改:添加了* validate *参数。不正确或不匹配的样式和 fmt 将引发ValueError。例如:logging.Formatter('%(asctime)s - %(message)s', style='{')

  • format(记录)
    • 记录的属性字典用作字符串格式化操作的操作数。返回结果字符串。在格式化字典之前,需要执行几个准备步骤。记录的* message 属性是使用 msg args 计算的。如果格式化字符串包含'(asctime)',则调用formatTime()来格式化事件时间。如果有异常信息,则使用formatException()对其进行格式化并附加到消息中。请注意,格式化的异常信息缓存在属性 exc_text *中。这很有用,因为可以对异常信息进行 Pickling 并pass网络发送,但是如果您有多个Formatter子类可自定义异常信息的格式,则应格外小心。在这种情况下,您必须在格式化程序完成格式化后清除缓存的值,以便处理事件的下一个格式化程序不会使用缓存的值,而是重新计算它。

如果堆栈信息可用,则将其附加在异常信息之后,并在必要时使用formatStack()对其进行转换。

  • formatTime(* record datefmt = None *)
    • 想要使用格式化时间的格式化程序应从format()调用此方法。可以在格式化程序中重写此方法以提供任何特定要求,但是基本行为如下:如果指定了* datefmt *(字符串),则它与time.strftime()一起使用以格式化记录的创建时间。否则,使用格式'%Y-%m-%d%H:%M:%S,uuu',其中 uuu 部分是毫秒值,其他字母按照time.strftime()文档。这种格式的示例时间是2003-01-23 00:29:50,411。返回结果字符串。

此函数使用用户可配置的函数将创建时间转换为 Tuples。默认情况下,使用time.localtime();要针对特定格式化程序实例更改此设置,请将converter属性设置为具有与time.localtime()time.gmtime()相同签名的函数。要为所有格式化程序更改它,例如,如果要在 GMT 中显示所有日志记录时间,请在Formatter类中设置converter属性。

在版本 3.3 中进行了更改:以前,此示例中对缺省格式进行了硬编码:2010-09-06 22:38:15,292,其中逗号前的部分由 strptime 格式字符串('%Y-%m-%d %H:%M:%S')处理,逗号后的部分是毫秒值。因为 strptime 在几毫秒内没有格式占位符,所以使用另一个格式字符串'%s,%03d'附加了毫秒值,并且这两个格式字符串都已硬编码到此方法中。pass更改,这些字符串被定义为类级别的属性,可以在需要时在实例级别覆盖它们。属性的名称是default_time_format(用于 strptime 格式字符串)和default_msec_format(用于附加毫秒值)。

  • formatException(* exc_info *)

  • formatStack(* stack_info *)

    • 将指定的堆栈信息(由traceback.print_stack()返回的字符串,但除去最后一个换行符)格式化为字符串。此默认实现仅返回 Importing 值。

Filter Objects

HandlersLoggers可以使用Filters进行比级别所提供的更为复杂的过滤。基本过滤器类仅允许 Logger 层次结构中特定点以下的事件。例如,使用“ AB”初始化的过滤器将允许 Logger“ A.B”,“ ABC”,“ ABCD”,“ ABD”等记录事件,但不允许“ A.BB”,“ BAB”等记录。如果使用空字符串初始化,则会传递所有事件。

    • class * logging. Filter(* name =''* *)
    • 返回Filter类的实例。如果指定了* name ,它将命名一个 Logger,该 Logger 及其子记录将允许其事件pass过滤器。如果 name *是空字符串,则允许每个事件。
  • filter(记录)

    • 是否要记录指定的记录?返回零表示否,非零表示是。如果认为合适,则可以pass此方法在原位修改记录。

请注意,在处理程序发出事件之前,将先查询附加到处理程序的过滤器,而在将事件发送到处理程序之前,无论何时记录事件(使用debug()info()等),都将查询附加到 Logger 的过滤器。这意味着由后代 Logger 生成的事件将不会被 Logger 的过滤器设置过滤,除非该过滤器也已应用于这些后代 Logger。

实际上,您不需要继承Filter:可以传递具有filter方法且具有相同语义的任何实例。

在版本 3.2 中进行了更改:不需要创建专门的Filter类,也不需要将其他类与filter方法一起使用:可以将函数(或其他可调用)用作过滤器。过滤逻辑将检查过滤对象是否具有filter属性:如果有,则假定它为Filter并调用其filter()方法。否则,假定它是可调用的,并且以记录作为单个参数进行调用。返回的值应与filter()返回的值一致。

尽管过滤器主要用于根据比级别更复杂的条件来过滤记录,但是它们可以查看由其附加到的处理程序或 Logger 处理的每条记录:如果您要进行计数等操作,这将非常有用记录由特定的 Logger 或处理程序处理,或在正在处理的LogRecord中添加,更改或删除属性。显然,更改 LogRecord 需要格外小心,但确实允许将上下文信息注入日志中(请参阅使用过滤器传递上下文信息)。

LogRecord Objects

LogRecord实例会在每次记录内容时由Logger自动创建,并且可以passmakeLogRecord()手动创建(例如,pass网络接收的腌制事件)。

    • class * logging. LogRecord(* name level pathname lineno msg args exc_info func = None sinfo = None *)
    • 包含与正在记录的事件有关的所有信息。

主要信息在msgargs中传递,它们使用msg % args组合在一起以创建记录的message字段。

  • Parameters

      • name –用于记录此 LogRecord 表示的事件的 Logger 的名称。请注意,此名称将始终具有该值,即使它可能是由连接到不同(祖先)Logger 的处理程序发出的。
  • level –记录事件的数字级别(DEBUG,INFO 等之一),请注意,这将转换为 LogRecord 的两个属性:levelno表示数字值,levelname表示对应的级别名称。

  • pathname –进行日志记录调用的源文件的完整路径名。

  • lineno –进行日志记录调用的源文件中的行号。

  • msg –事件描述消息,可能是带有变量数据占位符的格式字符串。

  • args –变量数据合并到* msg *参数中以获得事件描述。

  • exc_info –具有当前异常信息的异常 Tuples;如果没有可用的异常信息,则为None

  • func –调用日志记录调用的函数或方法的名称。

  • sinfo –表示从当前线程中的堆栈底部直到日志记录调用的堆栈信息的文本字符串。

  • getMessage ( )

    • 将用户提供的任何参数与消息合并后,返回此LogRecord实例的消息。如果日志记录调用的用户提供的 message 参数不是字符串,则在其上调用str()会将其转换为字符串。这允许将用户定义的类用作消息,其__str__方法可以返回要使用的实际格式字符串。

在版本 3.2 中进行了更改:pass提供一个用于创建记录的工厂,使LogRecord的创建更加可配置。可以使用getLogRecordFactory()setLogRecordFactory()设置工厂(有关工厂的签名,请参见此设置)。

此Function可用于在创建时将自己的值注入LogRecord。您可以使用以下模式:

old_factory = logging.getLogRecordFactory()

def record_factory(*args, **kwargs):
    record = old_factory(*args, **kwargs)
    record.custom_attribute = 0xdecafbad
    return record

logging.setLogRecordFactory(record_factory)

pass这种模式,可以链接多个工厂,并且只要它们不覆盖彼此的属性或无意覆盖上面列出的标准属性,就不会感到惊讶。

LogRecord attributes

LogRecord 具有许多属性,其中大多数是从构造函数的参数派生的。 (请注意,名称在 LogRecord 构造函数参数和 LogRecord 属性之间并不总是完全对应.)这些属性可用于将 Logging 的数据合并到格式字符串中。下表(按字母 Sequences)以%样式格式字符串列出了属性名称,它们的含义和相应的占位符。

如果使用\ {} -formatting(str.format()),则可以将{attrname}用作格式字符串中的占位符。如果您使用的是$格式(string.Template),请使用${attrname}形式。当然,在两种情况下,都将attrname替换为要使用的实际属性名称。

在\ {} -formatting 的情况下,可以pass将格式标记放置在属性名称之后(用冒号与之隔开)来指定格式标记。例如:{msecs:03d}的占位符会将4的毫秒值格式化为004。有关可用选项的完整详细信息,请参阅str.format()文档。

Attribute nameFormatDescription
args您不需要自己格式化。参数的 Tuples 合并到msg以产生message,或者是将其值用于合并的 dict(当只有一个参数且它是一本字典时)。
asctime%(asctime)sLogRecord创建时的可读时间。默认情况下,其格式为“ 2003-07-08 16:49:45,896”(逗号后的数字是时间的毫秒部分)。
created%(created)f创建LogRecord的时间(由time.time()返回)。
exc_info您不需要自己格式化。异常 Tuples(la sys.exc_info),或者,如果没有发生异常,则None
filename%(filename)spathname的文件名部分。
funcName%(funcName)s包含日志记录调用的函数的名称。
levelname%(levelname)s消息的文本记录级别('DEBUG''INFO''WARNING''ERROR''CRITICAL')。
levelno%(levelno)s消息的数字记录级别(DEBUGINFOWARNINGERRORCRITICAL)。
lineno%(lineno)d发出日志记录调用的源行号(如果有)。
message%(message)s记录的消息,计算为msg % args。调用Formatter.format()时设置。
module%(module)s模块(filename的名称部分)。
msecs%(msecs)d创建LogRecord的时间的毫秒部分。
msg您不需要自己格式化。原始日志记录调用中传递的格式字符串。与args合并以产生message或任意对象(请参见使用任意对象作为消息)。
name%(name)s用于记录呼叫的 Logger 的名称。
pathname%(pathname)s发出日志记录调用的源文件的完整路径名(如果有)。
process%(process)d进程 ID(如果有)。
processName%(processName)s进程名称(如果有)。
relativeCreated%(relativeCreated)d创建 LogRecord 的时间(以毫秒为单位),相对于加载日志模块的时间。
stack_info您不需要自己格式化。从当前线程的堆栈底部开始直到导致该记录创建的日志记录调用的堆栈框架(包括可用)的堆栈框架信息(如果有)。
thread%(thread)d线程 ID(如果有)。
threadName%(threadName)s线程名称(如果有)。

在版本 3.1 中更改:添加了* processName *。

LoggerAdapter Objects

LoggerAdapter实例用于将上下文信息方便地传递到日志记录调用中。有关用法示例,请参见将上下文信息添加到日志输出部分。

    • class * logging. LoggerAdapter(* logger extra *)
  • process(* msg kwargs *)

    • 修改传递给日志记录调用的消息和/或关键字参数,以插入上下文信息。此实现将作为附加对象传递给构造函数的对象,并使用键“附加”将其添加到 kwargs 中。返回值是一个(* msg kwargs *)Tuples,该 Tuples 具有传入的(可能已修改的)参数版本。

除此之外,LoggerAdapter还支持Logger的以下方法:debug()info()warning()error()exception()critical()log()isEnabledFor()getEffectiveLevel()setLevel()hasHandlers()。这些方法与Logger中的方法具有相同的签名,因此您可以互换使用两种类型的实例。

在版本 3.2 中更改:isEnabledFor()getEffectiveLevel()setLevel()hasHandlers()方法已添加到LoggerAdapter。这些方法委托给基础 Logger。

Thread Safety

日志记录模块旨在实现线程安全,而 Client 端无需执行任何特殊工作。它pass使用线程锁来实现。有一个锁用于序列化对模块共享数据的访问,每个处理程序还创建一个锁,以序列化对对其基础 I/O 的访问。

如果要使用signal模块实现异步 signal 处理程序,则可能无法使用此类处理程序中的日志记录。这是因为threading模块中的锁实现并不总是可重入的,因此不能从此类 signal 处理程序中调用。

Module-Level Functions

除了上述类之外,还有许多模块级Function。

  • logging. getLogger(* name = None *)
    • 返回具有指定名称的 Logger,或者,如果名称为None,则返回一个 Logger,该 Logger 是层次结构的根 Logger。如果指定,则名称通常是点分隔的分层名称,例如*'a''a.b''a.b.c.d'*。这些名称的选择完全取决于正在使用日志记录的开发人员。

使用给定名称对该函数的所有调用均返回相同的 Logger 实例。这意味着 Logger 实例永远不需要在应用程序的不同部分之间传递。

  • logging. getLoggerClass ( )
    • 返回标准的Logger类,或返回传递给setLoggerClass()的最后一个类。可以从新的类定义中调用此函数,以确保安装定制的Logger类不会撤消其他代码已经应用的定制。例如:
class MyLogger(logging.getLoggerClass()):
    # ... override behaviour here
  • logging. getLogRecordFactory ( )
    • 返回用于创建LogRecord的可调用对象。

3.2 版中的新增Function:此Function与setLogRecordFactory()一起提供,以使开发人员可以更好地控制表示日志事件的LogRecord的构造方式。

有关如何调用工厂的更多信息,请参见setLogRecordFactory()

  • logging. debug(* msg *, *args * kwargs *)
    • 在根 Logger 上记录级别为DEBUG的消息。 * msg 是消息格式字符串,而 args 是使用字符串格式运算符合并到 msg *中的参数。 (请注意,这意味着您可以在格式字符串中使用关键字以及单个字典参数.)

在* kwargs 中检查了三个关键字参数: exc_info *,如果不将其评估为 false,则会导致将异常信息添加到日志消息中。如果提供了一个异常 Tuples(由sys.exc_info()返回的格式)或一个异常实例,则使用它。否则,将调用sys.exc_info()以获取异常信息。

第二个可选关键字参数是* stack_info ,默认为False。如果为 true,则将堆栈信息添加到日志消息中,包括实际的日志调用。请注意,这与pass指定 exc_info *显示的堆栈信息不同:前者是从堆栈底部一直到当前线程中的日志记录调用的堆栈帧,而后者是有关已被使用的堆栈帧的信息。搜索异常处理程序时,在发生异常后解开卷。

您可以独立于* exc_info 来指定 stack_info *,例如仅显示您如何到达代码中的特定点,即使没有引发异常也是如此。堆栈框架在标题行之后打印:

Stack (most recent call last):

这模仿了显示异常帧时使用的Traceback (most recent call last):

第三个可选关键字参数是* extra *,可用于传递字典,该字典用于使用用户定义的属性填充为日志记录事件创建的 LogRecord 的__dict__。然后可以根据需要使用这些自定义属性。例如,可以将它们合并到已记录的消息中。例如:

FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning('Protocol problem: %s', 'connection reset', extra=d)

将打印如下内容:

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset
  • extra *中传递的字典中的键不应与日志系统使用的键冲突。 (有关日志记录系统使用哪些键的更多信息,请参见Formatter文档。)

如果选择在已记录的消息中使用这些属性,则需要格外小心。例如,在上面的示例中,Formatter已设置为格式字符串,该字符串在 LogRecord 的属性字典中期望为“ clientip”和“ user”。如果缺少这些内容,则将不会记录该消息,因为会发生字符串格式化异常。因此,在这种情况下,您始终需要pass这些键传递* extra *词典。

尽管这可能很烦人,但是此Function旨在用于特殊情况,例如在多个上下文中执行相同代码的多线程服务器,并且出现的有趣条件取决于此上下文(例如,远程 Client 端 IP 地址和已验证用户名,在上面的示例中)。在这种情况下,很可能将专门的Formatter与特定的Handler一起使用。

在版本 3.2 中更改:添加了* stack_info *参数。

  • logging. info(* msg *, *args * kwargs *)

    • 在根 Logger 上记录级别为INFO的消息。参数解释为debug()
  • logging. warning(* msg *, *args * kwargs *)

    • 在根 Logger 上记录级别为WARNING的消息。参数解释为debug()

Note

有一个过时的Functionwarn在Function上与warning相同。由于warn已过时,请不要使用它-改用warning

  • logging. error(* msg *, *args * kwargs *)

    • 在根 Logger 上记录级别为ERROR的消息。参数解释为debug()
  • logging. critical(* msg *, *args * kwargs *)

    • 在根 Logger 上记录级别为CRITICAL的消息。参数解释为debug()
  • logging. exception(* msg *, *args * kwargs *)

    • 在根 Logger 上记录级别为ERROR的消息。参数解释为debug()。异常信息将添加到日志消息中。仅应从异常处理程序中调用此函数。
  • logging. log(* level msg *, *args * kwargs *)

    • 在根 Logger 上记录级别为* level *的消息。其他参数的解释与debug()相同。

Note

上面委派给 rootLogger 的模块级别的便捷Function调用basicConfig()以确保至少有一个处理程序可用。因此,除非在启动线程之前(至少)在根 Logger 中添加了至少一个处理程序,否则它们不应在 2.7.1 和 3.2 之前的 Python 版本中用于线程中。在早期版本的 Python 中,由于basicConfig()中的线程安全性不足,这可能(在极少数情况下)导致将处理程序多次添加到 rootLogger 中,这反过来又可能导致同一事件的多个消息。

  • logging. disable(* level = CRITICAL *)
    • 为所有 Logger 提供一个优先级别* level ,该级别优先于 Logger 自己的级别。当需要临时限制整个应用程序中的日志记录输出时,此Function很有用。它的作用是禁用所有严重性为 level *及以下的日志记录调用,因此,如果您使用 INFO 值进行调用,则将丢弃所有 INFO 和 DEBUG 事件,而严重性为 WARNING 及以上的事件将根据以下处理:Logger 的有效级别。如果调用了logging.disable(logging.NOTSET),它将有效地删除此替代级别,因此日志输出又取决于各个 Logger 的有效级别。

请注意,如果您定义了高于CRITICAL的任何自定义日志记录级别(不建议这样做),则将无法依赖* level *参数的默认值,但必须显式提供合适的值。

在 3.7 版中更改:* level *参数默认为CRITICAL级别。有关此更改的更多信息,请参见问题#28524.

  • logging. addLevelName(* level levelName *)
    • 将级别* level 与内部字典中的文本 levelName *关联,该字典用于将数字级别 Map 到文本表示形式,例如Formatter格式化消息时。此Function还可用于定义您自己的级别。唯一的限制是所使用的所有级别都必须使用此Function进行注册,级别应为正整数,并且应按照严重性从高到低的 Sequences 递增。

Note

如果您想定义自己的级别,请参阅Custom Levels的部分。

  • logging. getLevelName(级别)
    • 返回日志记录级别* level 的文本表示形式。如果级别是 sched 义级别CRITICALERRORWARNINGINFODEBUG之一,则将获得相应的字符串。如果您使用addLevelName()将名称与级别关联,则将返回与 level *关联的名称。如果传入了与定义的级别之一相对应的数值,则返回相应的字符串表示形式。否则,返回字符串'Level%s'%level。

Note

级别是内部整数(因为它们需要在日志记录逻辑中进行比较)。此函数用于pass%(levelname)s格式说明符(请参见LogRecord attributes)在整数级别和格式化日志输出中显示的级别名称之间进行转换。

在 3.4 版中进行了更改:在 3.4 版之前的 Python 版本中,此函数也可以传递文本级别,并返回该级别的相应数值。这种未记录的行为被视为错误,已在 Python 3.4 中删除,但由于保留了向后兼容性,在 3.4.2 中将其恢复。

  • logging. makeLogRecord(* attrdict *)

    • 创建并返回一个新的LogRecord实例,该实例的属性由* attrdict *定义。此函数对于获取经过腌制的LogRecord属性字典(pass套接字发送)并将其重构为接收端的LogRecord实例很有用。
  • logging. basicConfig(*** kwargs *)

如果根 Logger 已经配置了处理程序,则此函数不执行任何操作,除非将关键字参数* force *设置为True

Note

在启动其他线程之前,应从主线程调用此函数。在 2.7.1 和 3.2 之前的 Python 版本中,如果从多个线程调用此函数,则有可能(在极少数情况下)多次将处理程序添加到根 Logger 中,从而导致意外结果,例如消息在日志中被复制。

支持以下关键字参数。

FormatDescription
filename指定使用指定的文件名而不是 StreamHandler 创建 FileHandler。
filemode如果指定了* filename *,请在此mode中打开文件。默认为'a'
format为处理程序使用指定的格式字符串。
datefmt使用time.strftime()接受的指定日期/时间格式。
style如果指定了* format *,请对该格式字符串使用此样式。分别针对printf-stylestr.format()string.Template'%''{''$'之一。默认为'%'
level将根记录程序级别设置为指定的level
stream使用指定的流初始化 StreamHandler。请注意,此参数与* filename *不兼容-如果两者都存在,则会引发ValueError
handlers如果指定,这应该是已经创建的处理程序的迭代过程,以添加到根 Logger。任何尚未设置格式器的处理程序都将被分配此函数中创建的默认格式器。请注意,此参数与* filename stream *不兼容-如果同时存在,则引发ValueError
force如果将此关键字参数指定为 true,则在执行其他参数指定的配置之前,将删除并关闭附加到根记录程序的所有现有处理程序。

在版本 3.2 中更改:添加了* style *参数。

在版本 3.3 中进行了更改:添加了* handlers 参数。添加了附加检查以捕获指定了不兼容参数的情况(例如 handlers stream filename stream filename *一起)。

在 3.8 版中进行了更改:添加了* force *参数。

  • logging. shutdown ( )
    • pass刷新和关闭所有处理程序来通知日志记录系统执行有序的关闭。这应该在应用程序 Export 处调用,并且在此调用之后不应进一步使用日志记录系统。

导入日志记录模块时,它将此函数注册为退出处理程序(请参见atexit),因此通常无需手动执行此操作。

  • logging. setLoggerClass(* klass *)

    • 告诉日志记录系统在实例化 Logger 时使用* klass *类。该类应定义init(),以便仅需要 name 参数,而init()应调用Logger.__init__()。通常在需要使用自定义 Logger 行为的应用程序实例化任何 Logger 之前,会调用此函数。在此调用之后,与其他任何时间一样,请勿直接使用子类实例化 Logger:continue 使用logging.getLogger() API 来获取 Logger。
  • logging. setLogRecordFactory(工厂)

    • 设置用于创建LogRecord的可调用对象。
  • Parameters

    • 工厂 –可用于实例化日志记录的工厂。

3.2 版中的新增Function:此Function与getLogRecordFactory()一起提供,以使开发人员可以更好地控制表示日志事件的LogRecord的构造方式。

工厂具有以下签名:

factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)

Note

  • name

  • Logger 名称。

  • level

  • 日志记录级别(数字)。

  • fn

  • 进行日志记录调用的文件的完整路径名。

  • lno

  • 记录调用所在文件中的行号。

  • msg

  • 日志消息。

  • args

  • 日志记录消息的参数。

  • exc_info

  • 异常 Tuples 或None

  • func

  • 调用日志记录调用的函数或方法的名称。

  • sinfo

  • traceback.print_stack()提供的堆栈回溯,显示了调用层次结构。

  • kwargs

  • 其他关键字参数。

Module-Level Attributes

  • logging. lastResort
    • pass此属性可以使用“最后处理者”。这是StreamHandler写入_3 的级别,级别为WARNING,用于在没有任何日志记录配置的情况下处理日志记录事件。finally结果是仅将消息打印到sys.stderr。这将替换先前的错误消息,即“找不到 LoggerXYZ 的处理程序”。如果出于某种原因需要较早的行为,可以将lastResort设置为None

3.2 版中的新Function。

与警告模块集成

captureWarnings()函数可用于将loggingwarnings模块集成。

  • logging. captureWarnings(* capture *)
    • 此Function用于pass登录和注销来打开警告捕获。

如果* capture *为True,则由warnings模块发出的警告将重定向到日志记录系统。具体来说,将使用warnings.formatwarning()格式化警告,并将结果字符串记录到名为'py.warnings'的严重性为WARNING的 Logger 中。

如果* capture *为False,则将停止将警告重定向到日志记录系统,并且将警告重定向到其原始目的地(即,在调用captureWarnings(True)之前生效的警告)。

See also

  • Module logging.config

  • 日志记录模块的配置 API。

  • Module logging.handlers

  • 日志记录模块随附的有用处理程序。

  • PEP 282-记录系统

  • 将该特性描述为包含在 Python 标准库中的提案。

  • 原始 Python 记录程序包

  • 这是logging软件包的原始来源。该站点提供的软件包版本适用于 Python 1.5.2、2.1.x 和 2.2.x,它们在标准库中不包含logging软件包。