15.7. loggingPython的日志工具

Source code: Lib/logging/__init__.py


New in version 2.3.

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

The key benefit of having the logging API provided by a standard library module is that all Python modules can participate in logging, so your application log can include your own messages integrated with messages from third-party modules.

The module provides a lot of functionality and flexibility. If you are unfamiliar with logging, the best way to get to grips with it is to see the tutorials (see the links on the right).

The basic classes defined by the module, together with their functions, are listed below.

  • Loggers 提供应用程序代码直接使用的接口。
  • Handlers 发送日志记录(由loggers创建)到正确的目标。
  • Filters 提供粒度更好的工具用于决定输出哪些日志记录。
  • Formatters 指出最终输出中的日志记录的格式。

15.7.1. Logger 对象

Loggers 具有以下的属性和方法。注意永远不要直接初始化Loggers,而应该通过模块级别的函数logging.getLogger(name)来得到它。以相同的名称多次调用getLogger()将永远返回相同Logger对象的引用。

name可以是一个以句号分隔的层次结构的值,比如foo.bar.baz(它也可以只是普通的foo)。层次列表下游的loggers是上游loggers的子孙。例如,对于名称为foo的logger,名称为foo.barfoo.bar.bazfoo.bam的logger都是foo的后代。logger名称的层次结构类似于Python包的层次结构,如果你使用建议的构造方式logging.getLogger(__name__)来组织你的基于模块的loggers,那么层次结构就是一样的。因为在一个模块中,__name__是Python包命名空间中模块的名字。

class logging.Logger
Logger.propagate

如果它为真,记录到该logger的事件除了传递给该logger的handler之外,也被传递给上游(祖先)logger的handler。信息将直接传递给祖先logger的handler - 不会考虑祖先logger的级别和filter。

如果它为假,日志消息不会传递给祖先loggers的handlers。

The constructor sets this attribute to True.

如果你添加一个handler到logger 它的一个或多个祖先中,它可能多次打印相同的记录。一般来说,你不应该需要将一个handler添加给多个logger - 如果你只将它添加到合适的logger而它是logger层次中最高的,那么它将看到所有子logger记录的事件,只要它们的propagate设置保留为True一个常见的场景是将handlers附加给根logger,然后让propagation负责剩下的事情。

Logger.setLevel(lvl)

设置该logger的级别为lvl严重程度低于lvl 的日志消息将被忽略。当创建一个logger时,它的级别设置为NOTSET(它使得当该logger是根logger时所有的信息都将被处理,或者当该logger不是根logger时委托给父logger)。Note that the root logger is created with level WARNING.

“委托给父logger”的意思是如果logger的级别是NOTSET,将遍历它的祖先链直到找到一个级别不是NOTSET的祖先或者到达根logger。

如果找到级别不是NOTSET的祖先,祖先的级别被认为是开始查找祖先的logger的有效级别,用来决定如何处理日志事件。

如果到达root且它的级别是NOTSET,那么将处理所有的信息。否则root的级别将用作有效的级别。

See Logging Levels for a list of levels.

Logger.isEnabledFor(lvl)

表明lvl 级别的信息是否会被该logger处理。该方法首先检查由logging.disable(lvl)设置的模块级的级别,然后检查由getEffectiveLevel()决定的该logger的有效级别。

Logger.getEffectiveLevel()

表明该logger的有效级别。如果使用setLevel()设置了非NOTSET的级别,该级别被返回。否则向根遍历logger层次,直到找到某个非NOTSET级别为止,该级别被返回。

Logger.getChild(suffix)

返回该logger的由suffix决定的后代logger。logging.getLogger('abc').getChild('def.ghi')返回的logger和logging.getLogger('abc.def.ghi')返回的logger是同一个。如果父logger使用如__name__的名称而不是字符串字时,该方法很方便。

版本2.7中新增。

Logger.debug(msg, *args, **kwargs)

在logger上记录一条级别为DEBUG的消息。msg为消息格式字符串,args为通过字符串格式操作符合并到msg的参数。(注意这意味着可以在格式字符串中使用关键字和一个字典参数。)

kwargs中有两个关键字参数会被检查:第一个是exc_info,如果它不为false,异常信息会被添加到日志消息。如果有提供异常元组(格式为sys.exc_info()返回值的格式),使用该元组;否则调用sys.exc_info()来得到异常信息。

第二个检查的关键字参数是extra,可以给它传递一个字典,用来填充LogRecord的__dict__,LogRecord用以表示日志事件,且有自定义属性。你可以随意使用这些自定义属性。例如,它们可以合并到日志消息中。示例:

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'。如果缺失的话,该消息就不会被记录,因为会发生字符串格式异常。在这种情况下,你总是要传递带这些键的extra字典。

这可能有些麻烦,它主要在一些特定的环境下使用。如有一个多线程服务器,相同的代码会在许多上下文执行,而感兴趣的条件在上下文才会出现(如上例中的远端客户端IP地址和已认证用户名)。在这种环境下,很可能对特殊的Handler使用特定的Formatter

Logger.info(msg, *args, **kwargs)

在该logger上以INFO级别记录一条信息。其参数的解释与debug()相同。

Logger.warning(msg, *args, **kwargs)

在该logger上以WARNING级别记录一条信息。其参数的解释与debug()相同。

Logger.error(msg, *args, **kwargs)

在该logger上以ERROR级别记录一条信息。其参数的解释与debug()相同。

Logger.critical(msg, *args, **kwargs)

在该logger上以CRITICAL级别记录一条信息。其参数的解释与debug()相同。

Logger.log(lvl, msg, *args, **kwargs)

在该logger上以整数级别lvl记录一条信息。其余参数的解释与debug()相同。

Logger.exception(msg, *args, **kwargs)

在该logger上以ERROR级别记录一条信息。其参数的解释与debug()相同。异常信息将添加到日志信息中。该方法应该只在异常处理器调用。

Logger.addFilter(filt)

添加指定的filter filt 到该logger。

Logger.removeFilter(filt)

删除该logger中的filter filt

Logger.filter(record)

对record应用该logger的filters,如果该record应该被处理,返回真。轮流调用filters,直到有一个返回假。如果没有filter返回假值,该record将会被处理(传递给handlers)。如果有一个返回了假值,将不会对record做进一步的处理。

Logger.addHandler(hdlr)

将指定的handlerhdlr添加到logger中。

Logger.removeHandler(hdlr)

从logger中移除指定的handler hdlr

Logger.findCaller()

查找调用者的源码文件名和行号。以3元组的形式返回文件名,行号和函数名。

2.4版本中的变动: 函数名被加入进来。在早期版本中,以2元组形式返回文件名和行号。

Logger.handle(record)

处理一个record,将它传给该logger及其祖先的所有的handler(直到propagate为假为止)。该方法用于从套接字接收到的反序列化的record,以及那些本地创建的。使用filter()日志级别过滤会应用。

Logger.makeRecord(name, lvl, fn, lno, msg, args, exc_info, func=None, extra=None)

这是一个工厂方法,可以在子类中覆盖它来创建特定的LogRecord实例。

版本2.5中的改变:添加funcextra 参数。

15.7.2. 日志级别

下表给出日志级别的数值。这主要在你想定义自己的级别时有用,且自定义级别的值是相对于预定义级别的值。如果你定义一个具有相同数值的级别,那么它将覆盖预定义的值;预定义的名称将丢失。

级别 数值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

15.7.3. Handler 对象

Handler有以下属性和方法。注意Handler从不直接初始化;这个类是有用子类的基类。然而子类的__init__()方法需要调用Handler.__init__()

Handler.__init__(level=NOTSET)

初始化Handler实例,设置它的级别,设置filter列表为空列表,创建锁(使用createLock())用以序列化访问I/O机制。

Handler.createLock()

初始化线程锁,用以序列化访问底层的可能非线程安全的I/O机制,

Handler.acquire()

获取createLock()创建的线程锁。

Handler.release()

释放由acquire()获取的线程锁。

Handler.setLevel(lvl)

设置handler级别为lvl严重程度低于lvl的日志消息会被忽略。当handler创建时,级别设为NOTSET(这会处理所有消息)。

参见日志级别以了解级别列表。

Handler.setFormatter(form)

参见格式化器以了解form

Handler.addFilter(filt)

添加指定的filterfilt到handler。

Handler.removeFilter(filt)

从handler移除指定的filter filt

Handler.filter(record)

将handler的filter应用到record,如果该record应该被处理,返回真。轮流调用filter,直到有一个返回假。如果没有一个filter返回假,发出该record。如果有一个filter返回假,handler将不会发出record。

Handler.flush()

确保所有的日志输出被刷新。基类版本不做任何事情,留给子类来实现。

Handler.close()

清除handler所使用的资源。该版本没有输出,它将handler从内部handler列表中移除,当调用shutdown()时handler列表中的handler都会被关闭。子类应该保证在重写的close()方法中调用此方法。

Handler.handle(record)

依赖于加到该handler的filter,有条件的发出特定的日志record。它包装了发出record时对I/O线程锁的获取/释放过程。

Handler.handleError(record)

在handler中调用emit()时发生异常,应该调用该方法。如果模块级属性raiseExceptionsFalse,异常会被静默忽略掉。这是日志系统常见的行为——大多数用户并不关心日志系统中的错误,他们只关心应用的错误。当然如果你愿意,你可以用自定义的处理器来替换它。record参数是异常发生时正在处理的record。raiseExceptions的默认值为True,这在开发中很有用)。

Handler.format(record)

格式化record,如果有formatter,使用formatter。否则使用模块默认的formatter。

Handler.emit(record)

做记录日志record真正需要的动作。基类版本抛出NotImplementedError,留给子类来实现。

参见logging.handlers以了解标准库中的handler。

15.7.4. Formatter 对象

Formatter对象有下述的属性和方法。(一般来说)它负责将LogRecord转化成为一个字符串,人或者外部系统可以解读这些字符串。基类Formatter允许指定一个格式化字符串。如果没有指定格式化字符串,将使用默认值'%(message)s'

可以用格式化字符串来初始化Formatter,格式化字符串可以使用LogRecord的属性——上述的默认的格式化字符串就使用了LogRecordmessage属性,它保存了用户消息及其参数。格式化字符串包含标准的Python的%-风格的映射键值。参见String Formatting Operations章节以得到更多关于字符串格式化的信息。

有用的LogRecord的映射键值在LogRecord attributes章节中给出。

class logging.Formatter(fmt=None, datefmt=None)

返回Formatter类的实例。实例以整个消息的格式化字符串以及消息中日期/时间部分的格式化字符串来初始化。如果不指明fmt,将使用'%(message)s'如果不指明datefmt,将使用ISO8601日期格式。

format(record)

记录的属性字典被用作字符格式化操作的参数。返回结果字符串。在格式化字典之前将会执行一些准备性的动作。记录的message属性用msg % args来计算。如果格式化字符串包含'(asctime)'formatTime()将会被调用用以格式化事件的时间。如果有异常信息,使用formatException()来格式化它,并将结果附加到消息。注意格式化过的异常信息缓存于exc_text属性。这是有用的,因为异常信息可以被序列化并在网络上传递;但是如果你有多个Formatter子类,每个子类都定制了异常信息的格式化方式,这种情况下就得注意。在这种情况下,在一个formatter完成了格式化操作之后需要清掉缓存的值,这样下一个formatter才会重新计算而不是使用缓存值。

formatTime(record, datefmt=None)

formatter在format()内部调用该方法以格式化时间。可以在formatter中重写该方法以满足特定的需求,但基本行为如下:如果指明了datefmt字符串,用该字符串来调用time.strftime()以格式化记录的创建时间。否则使用ISO8601格式。返回结果字符串。

该函数使用用户配置的函数来将创建时间转成元组。默认使用time.localtime()对特定的formatter实例,可以将converter属性设成一个函数,该函数和time.localtime()或者 time.gmtime()有相同的函数签名。如果需要对所有的formatter进行修改,例如你希望所有的日志时间都以GMT格式显式,可以设置Formatter类的converter属性。

formatException(exc_info)

将指明的异常信息(如sys.exc_info()返回的标准异常元组)格式化成字符串。默认实现使用traceback.print_exception()返回结果字符串。

15.7.5. Filter 对象

HandlersLoggers可以使用Filters来完成比级别更复杂的过滤。filter基类只允许特定logger层次以下的事件。例如用‘A.B’初始化的filter允许logger ‘A.B’, ‘A.B.C’, ‘A.B.C.D’, ‘A.B.D’等记录的事件,logger‘A.BB’, ‘B.A.B’ 等就不行。 如果用空字符串来初始化,所有的事件都接受。

class logging.Filter(name='')

返回Filter类的实例。如果指明了name,它是一个logger的名字,该logger及其子logger的事件运行通过该过滤器。如果name是空字符串,所有的事件都允许。

filter(record)

特定的记录是否要记下来?0为否,非0为是。如果认为合适,该方法可以修改记录。

请注意,对于handler所附的filter,在handler发出事件之前会参考这些filter;对于logger所附的filter,在事件被记录时(使用debug(), info()等)、发送事件到handler之前会参考这些filter。这意味着子logger产生的事件是不会被logger的filter设定所过滤掉的,除非filter也适用于子logger。

可以不必继承Filter:只要实例有filter方法,且拥有相同的语义即可。

尽管filter主要用比级别更复杂的标准来过滤记录,但它能看到它所附于的handler或者logger所处理的所有记录:这可以做许多有用的事情,比如对特定的logger或者handler所处理的记录的计数;或者对正在处理的LogRecord,添加、修改或者移除属性。修改LogRecord需要小心,但是它可以在日志中注入上下文信息(参见Using Filters to impart contextual information)。

15.7.6. LogRecord 对象

Logger每次记录日志时都会创建LogRecord实例,也可以调用makeLogRecord()来手动创建LogRecord实例(例如从网络上收到序列化过的事件)。

class logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None)

包含所有跟记录的事件相关的信息。

主要的信息是msgargs,使用msg % args来创建记录的message字段。

  • name记录该LogRecord的logger的名字。注意该名字不会变,哪怕它有可能是由一个不同的(父)logger的handler所发出来的。
  • level记录事件的数字级别(DEBUG、INFO等之一)。注意它被转成LogRecord的两个属性:levelno表示数字值,levelname表示对应的级别名称。
  • pathname日志调用发生的源文件的完整路径名。
  • lineno日志调用发生的源文件的行号。
  • msg描述事件的消息,可以是带占位符的格式化字符串。
  • argsmsg的参数。
  • exc_info带当前异常信息的异常元组,如果没有异常为None
  • func日志调用所在的函数/方法名。

改变于版本2.5:添加了func

getMessage()

返回该LogRecord实例的消息,用户提供的参数已经合并到消息中。如果调用日志时用户提供的参数不是字符串,调用str()来将其转成字符串。这允许用户定义的类实例来用作消息,只要类定义了__str__方法可以返回字符串。

15.7.7. LogRecord 属性

LogRecord有一些属性,大都源自于构造函数的参数。(注意名字在LogRecord构造函数参数中和LogRecord属性中并不总是对应的。)这些属性用来将数据从记录合并到格式化字符串中。下表列出了属性名(按名称排序),含义及其对应的%风格的格式字符串占位符。

属性名 格式 描述
args 不需要格式化args。 参数元组,会合并到msg中以产生message
asctime %(asctime)s 人类可读的LogRecord创建的时间。默认形式为‘2003-07-08 16:49:45,896’(逗号后面的数字表示时间的毫秒部分)。
created %(created)f LogRecord创建的时间(形如time.time()的返回值,即epoch跳秒)。
exc_info 不需要格式化exc_info。 异常元组(形如sys.exc_info,如果没有异常为None
filename %(filename)s pathname的文件名部分。
funcName %(funcName)s 日志调用所在的函数名。
levelname %(levelname)s 消息的级别名称('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')。
levelno %(levelno)s 消息的级别数字(DEBUG, INFO, WARNING, ERROR, CRITICAL)。
lineno %(lineno)d 日志调用所在的源码行号(如果可用)。
module %(module)s 模块(文件名的名字部分)。
msecs %(msecs)d LogRecord创建时间中的毫秒部分。
message %(message)s 日志消息,msg % args的计算结果。Formatter.format()被调用时该属性被设置。
msg 不需要格式化msg。 日志调用时所传进来的原始的格式化字符串。和args合并以产生message或是任意一个对象(参见使用任意对象作为消息)。
name %(name)s 记录日志的logger的名字。
pathname %(pathname)s 日志调用所在文件的完整路径名(如果可用)。
process %(process)d 进程 ID (如果可用)。
processName %(processName)s 进程名(如果可用)。
relativeCreated %(relativeCreated)d LogRecord创建时离装载日志模块时的毫秒数。
thread %(thread)d 线程 ID (如果可用)。
threadName %(threadName)s 线程名字(如果可用)。

改变于版本2.5:添加了funcName

改变于版本2.6:添加了processName

15.7.8. LoggerAdapter 对象

LoggerAdapter实例可以方便的给日志调用传递上下文信息。使用的例子可以参见给日志输出添加上下文信息

出现于版本 2.6。

class logging.LoggerAdapter(logger, extra)

返回LoggerAdapter的实例,它以底层的Logger实例和一个类字典对象来初始化。

process(msg, kwargs)

修改传给日志调用的消息和/或关键字参数,以插入上下文信息。实现使用构造函数中的extra对象,使用'extra'键值将其加入kwargs返回值是(msg, kwargs)的元组,是传入的参数的值(可能修改过)。

除此以外,LoggerAdapter支持Logger的下列方法:debug(), info(), warning(), error(), exception(), critical(), log() and isEnabledFor()这些方法和它们在Logger中的对等物有相同的函数签名,所以可以交叉使用两类实例来调用这些方法。

改变于版本2.7:LoggerAdapter中加入了isEnabledFor()方法。该方法委托给底层的logger。

15.7.9. 线程安全性

日志模块被设计成线程安全的,不需要客户端做什么特别的动作。它使用线程锁来达到该目的;有一个锁被用来同步访问模块的共享数据,每一个handler也创建一个锁来同步访问它底层的I/O。

如果你使用signal模块来实现异步信号处理器,你不能在处理器代码中使用日志。这是因为threading模块中的锁实现并不总是可重入的,从而不能在异步信号处理器中被调用。

15.7.10. 模块级别的函数

除了上述类,还有一些模块级别的函数。

logging.getLogger([name])

返回特定名字的logger,如果没有名字,返回logger层级中的根logger(root logger)。一般名字是点分隔的层级名,比如“a”, “a.b” 或者 “a.b.c.d”使用日志的开发者决定选择什么样的名字。

以相同名字调用该函数总是返回同一个logger实例。这意味着logger实例不需要在应用的各个部分之间传来传去。

logging.getLoggerClass()

返回标准的Logger类,或者最后一次传给setLoggerClass()的类。可以在新类的定义中调用该函数,这可以使得安装一个自定义的Logger类不会撤销其他代码已经定制过的行为。例如:

class MyLogger(logging.getLoggerClass()):
    # ... override behaviour here
logging.debug(msg[, *args[, **kwargs]])

在根logger上记录一个DEBUG级别的消息。msg是消息的格式化字符串,args是参数,它会被合并到msg中,通过字符串格式化操作符。(这意味着你可以在格式化字符串中使用关键字,同时使用一个字典参数)

kwargs中有两个关键字参数被检查:exc_info如果不为false,异常信息会被加入到日志消息。如果提供的是异常元组(以sys.exc_info()返回值的形式),将使用该元组;否则调用sys.exc_info()以得到异常信息。

另一个可选的关键字参数为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’。如果缺失,消息将不会被记录,因为会发生一个字符串格式化异常。在这种情况下,extra字典中应该总包含这些键。

这可能有些麻烦,它主要在一些特定的环境下使用。如有一个多线程服务器,相同的代码会在许多上下文执行,而感兴趣的条件在上下文才会出现(如上例中的远端客户端IP地址和已认证用户名)。在这种情况下,很可能对特殊的Handler使用特定的Formatter

改变于版本2.5:添加了extra

logging.info(msg[, *args[, **kwargs]])

在根logger上记录一个INFO级别的消息。其参数的解释和debug()相同。

logging.warning(msg[, *args[, **kwargs]])

在根logger上记录一个WARNING级别的消息。其参数的解释和debug()相同。

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()相同。

注意

上述模块级别的便利函数委托给根logger,调用basicConfig()保证至少有一个handler可用。因为如此,应该在线程中调用这些函数,也不应该在Python 2.7.1 和 3.2之前的版本使用这些函数;除非在线程启动之前,至少有一个可用的handler被加到根logger。在早期版本的Python中,由于basicConfig()有线程安全的问题,(在极少情况下)可能导致在根logger上多次添加handler,从而导致相同事件被记录多个消息。

logging.disable(lvl)

对所有logger提供级别lvl,该级别会覆盖logger自己的级别。如果需要临时限制整个应用的日志输出,这个函数就很有用。它会禁用lvl及其以下级别的日志调用,如果禁用INFO,那么 INFO 和 DEBUG 事件将会被丢弃, WARNING 及其以上的事件会基于logger的有效级别来处理。如果logging.disable(logging.NOTSET)被调用,相当于移除了禁用级别,日志的输出重新依赖于每个logger的有效级别。

logging.addLevelName(lvl, levelName)

在内部字典中关联lvllevelName文本,可以用来将一个数字级别映射到文本表示,比如Formatter在格式化消息的时候。可以用该函数来定义自己的级别。限制就是必须用该函数来登记所有的级别,级别应该是正整数,且随着严重程度的增加而递增。

注意

如果考虑定义自己的级别,请参见章节自定义级别

logging.getLevelName(lvl)

返回日志级别lvl的文本表示。如果级别是预定义的CRITICAL, ERROR, WARNING, INFODEBUG中的一个,那么可以得到对应的字符串。如果通过addLevelName()关联了级别名,那么关联到lvl的名字会返回。如果传入的是已定义的级别对应的数字值,返回相应的字符串表示。否则返回“Level %s” % lvl。

logging.makeLogRecord(attrdict)

创建并返回LogRecord实例,attrdict定义了其属性。可以在网络上传输序列化过的LogRecord属性字典,然后在接受端重建LogRecord实例。

logging.basicConfig([**kwargs])

创建一个带默认FormatterStreamHandler,将其加到根logger,从而配置基本的日志系统。函数debug(), info(), warning(), error()critical()在根looger没有handler的情况下会自动调用basicConfig()

如果根logger已经配置了handler则该函数什么都不做。

改变于版本2.4:在此之前basicConfig()不接受任何的关键字参数。

注意

该函数应该在其它线程启动之前,在主线程中被调用。在早于2.7.1 和 3.2的Python中,如果该函数在多线程中被调用,(在极少情况下)有可能一个handler被多次加到根logger,导致非预期的结果,比如日志中出现重复的消息。

支持下列关键字参数。

格式 描述
filename 创建一个FileHandler,使用指定的文件名,而不是使用StreamHandler。
filemode 如果指明了文件名,指明打开文件的模式(如果没有指明filemode,默认为'a')。
format handler使用指明的格式化字符串。
datefmt 使用指明的日期/时间格式。
level 指明根logger的级别。
stream 使用指明的流来初始化StreamHandler。该参数与'filename'不兼容,如果两个都有,'stream'被忽略。
logging.shutdown()

通知日志系统执行有序的关闭,刷新并关闭所有的handler。在应用退出的时候调用该函数,调用该函数后不应该继续使用日志系统。

logging.setLoggerClass(klass)

告知日志系统使用class类来实例化logger。类要定义需要一个名字参数的__init__()__init__()应该调用Logger.__init__()典型的,如果应用使用自定义的logger行为,在初始化任一个logger之前需要调用该函数。

15.7.11. 与warnings模块集成

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

logging.captureWarnings(capture)

该函数用来打开/关闭“日志捕获警告”。

如果captureTruewarnings模块产生的警告会被重定向至日志系统。警告会被用warnings.formatwarning()来格式化,结果字符串会被名字为'py.warnings'的logger所记录,严重程度为WARNING

如果captureFalse,重定向警告至日志系统会停止,警告会定向至它们原来的终点,(即captureWarnings(True)调用之前的终点)。

参见

模块logging.config
日志模块的配置API。
模块logging.handlers
日志模块带的有用的handler。
PEP 282 - 日志系统
包含于Python标准库描述该功能的提案。
原始的Python日志包
logging包的原始源码。该站点此版本的包适用与Python 1.5.2, 2.1.x 和 2.2.x,在这些版本的Python标准库中并不保护logging包。