logging --- Python 的日志記錄工具?

源代碼: Lib/logging/__init__.py


這個模塊為應用與庫實現(xiàn)了靈活的事件日志系統(tǒng)的函數(shù)與類。

使用標準庫提供的 logging API 最主要的好處是,所有的 Python 模塊都可能參與日志輸出,包括你自己的日志消息和第三方模塊的日志消息。

這個模塊提供許多強大而靈活的功能。如果你對 logging 不太熟悉的話, 掌握它最好的方式就是查看它對應的教程(詳見右側的鏈接)。

該模塊定義的基礎類和函數(shù)都列在下面。

  • 記錄器暴露了應用程序代碼直接使用的接口。

  • 處理器將日志記錄(由記錄器創(chuàng)建)發(fā)送到適當?shù)哪繕恕?/p>

  • 過濾器提供了更細粒度的功能,用于確定要輸出的日志記錄。

  • 格式器指定最終輸出中日志記錄的樣式。

記錄器對象?

記錄器有以下的屬性和方法。注意 永遠 不要直接實例化記錄器,應當通過模塊級別的函數(shù) logging.getLogger(name) 。多次使用相同的名字調用 getLogger() 會一直返回相同的 Logger 對象的引用。

name 一般是句點分割的層級值, 像``foo.bar.baz`` (盡管也可以只是普通的 foo)。層次結構列表中位于下方的記錄器是列表中較高位置的記錄器的子級。例如,有個名叫 foo 的記錄器,而名字是 foo.barfoo.bar.baz,和 foo.bam 的記錄器都是 foo 的子級。記錄器的名字分級類似 Python 包的層級,如果您使用建議的結構 logging.getLogger(__name__) 在每個模塊的基礎上組織記錄器,則與之完全相同。這是因為在模塊里,__name__ 是該模塊在 Python 包命名空間中的名字。

class logging.Logger?
propagate?

如果這個屬性為真,記錄到這個記錄器的事件除了會發(fā)送到此記錄器的所有處理程序外,還會傳遞給更高級別(祖先)記錄器的處理器,此外任何關聯(lián)到這個記錄器的處理器。消息會直接傳遞給祖先記錄器的處理器 —— 不考慮祖先記錄器的級別和過濾器。

如果為假,記錄消息將不會傳遞給當前記錄器的祖先記錄器的處理器。

Spelling it out with an example: If the propagate attribute of the logger named A.B.C evaluates to true, any event logged to A.B.C via a method call such as logging.getLogger('A.B.C').error(...) will [subject to passing that logger's level and filter settings] be passed in turn to any handlers attached to loggers named A.B, A and the root logger, after first being passed to any handlers attached to A.B.C. If any logger in the chain A.B.C, A.B, A has its propagate attribute set to false, then that is the last logger whose handlers are offered the event to handle, and propagation stops at that point.

構造器將這個屬性初始化為 True

備注

如果你將一個處理器附加到一個記錄器 其一個或多個祖先記錄器,它可能發(fā)出多次相同的記錄。通常,您不需要將一個處理器附加到一個以上的記錄器上 —— 如果您將它附加到記錄器層次結構中最高的適當記錄器上,則它將看到所有后代記錄器記錄的所有事件,前提是它們的傳播設置保留為 True。一種常見的方案是僅將處理器附加到根記錄器,通過傳播來處理其余部分。

setLevel(level)?

給記錄器設置閾值為 level 。日志等級小于 level 會被忽略。嚴重性為 level 或更高的日志消息將由該記錄器的任何一個或多個處理器發(fā)出,除非將處理器的級別設置為比 level 更高的級別。

創(chuàng)建記錄器時,級別默認設置為 NOTSET (當記錄器是根記錄器時,將處理所有消息;如果記錄器不是根記錄器,則將委托給父級)。請注意,根記錄器的默認級別為 WARNING 。

委派給父級的意思是如果一個記錄器的級別設置為 NOTSET,將遍歷其祖先記錄器,直到找到級別不是 NOTSET 的記錄器,或者到根記錄器為止。

如果發(fā)現(xiàn)某個父級的級別不是 NOTSET ,那么該父級的級別將被視為發(fā)起搜索的記錄器的有效級別,并用于確定如何處理日志事件。

如果搜索到達根記錄器,并且其級別為 NOTSET,則將處理所有消息。否則,將使用根記錄器的級別作為有效級別。

參見 日志級別 級別列表。

在 3.2 版更改: 現(xiàn)在 level 參數(shù)可以接受形如 'INFO' 的級別字符串表示形式,以代替形如 INFO 的整數(shù)常量。 但是請注意,級別在內(nèi)部存儲為整數(shù),并且 getEffectiveLevel()isEnabledFor() 等方法的傳入/返回值也為整數(shù)。

isEnabledFor(level)?

指示此記錄器是否將處理級別為 level 的消息。此方法首先檢查由 logging.disable(level) 設置的模塊級的級別,然后檢查由 getEffectiveLevel() 確定的記錄器的有效級別。

getEffectiveLevel()?

指示此記錄器的有效級別。如果通過 setLevel() 設置了除 NOTSET 以外的值,則返回該值。否則,將層次結構遍歷到根,直到找到除 NOTSET 以外的其他值,然后返回該值。返回的值是一個整數(shù),通常為 logging.DEBUG、 logging.INFO 等等。

getChild(suffix)?

返回由后綴確定的該記錄器的后代記錄器。 因此,logging.getLogger('abc').getChild('def.ghi')logging.getLogger('abc.def.ghi') 將返回相同的記錄器。 這是一個便捷方法,當使用如 __name__ 而不是字符串字面值命名父記錄器時很有用。

3.2 新版功能.

debug(msg, *args, **kwargs)?

在此記錄器上記錄 DEBUG 級別的消息。 msg 是消息格式字符串,而 args 是用于字符串格式化操作合并到 msg 的參數(shù)。(請注意,這意味著您可以在格式字符串中使用關鍵字以及單個字典參數(shù)。)當未提供 args 時,不會對 msg 執(zhí)行 % 格式化操作。

kwargs 中會檢查四個關鍵字參數(shù): exc_infostack_info ,stacklevelextra 。

如果 exc_info 的求值結果不為 false ,則它將異常信息添加到日志消息中。如果提供了一個異常元組(按照 sys.exc_info() 返回的格式)或一個異常實例,則它將被使用;否則,調用 sys.exc_info() 以獲取異常信息。

第二個可選關鍵字參數(shù)是 stack_info,默認為 False。如果為 True,則將堆棧信息添加到日志消息中,包括實際的日志調用。請注意,這與通過指定 exc_info 顯示的堆棧信息不同:前者是從堆棧底部到當前線程中的日志記錄調用的堆棧幀,而后者是在搜索異常處理程序時,跟蹤異常而打開的堆棧幀的信息。

您可以獨立于 exc_info 來指定 stack_info,例如,即使在未引發(fā)任何異常的情況下,也可以顯示如何到達代碼中的特定點。堆棧幀在標題行之后打?。?/p>

Stack (most recent call last):

這模仿了顯示異常幀時所使用的 Traceback (most recent call last): 。

第三個可選關鍵字參數(shù)是 stacklevel ,默認為 1 。如果大于 1 ,則在為日志記錄事件創(chuàng)建的 LogRecord 中計算行號和函數(shù)名時,將跳過相應數(shù)量的堆棧幀??梢栽谟涗泿椭鲿r使用它,以便記錄的函數(shù)名稱,文件名和行號不是幫助器的函數(shù)/方法的信息,而是其調用方的信息。此參數(shù)是 warnings 模塊中的同名等效參數(shù)。

第四個關鍵字參數(shù)是 extra ,傳遞一個字典,該字典用于填充為日志記錄事件創(chuàng)建的、帶有用戶自定義屬性的 LogRecord 中的 __dict__ 。然后可以按照需求使用這些自定義屬性。例如,可以將它們合并到已記錄的消息中:

FORMAT = '%(asctime)s %(clientip)-15s %(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 中傳入的字典的鍵不應與日志系統(tǒng)使用的鍵沖突。(有關日志系統(tǒng)使用哪些鍵的更多信息,請參見 Formatter 的文檔。)

如果在已記錄的消息中使用這些屬性,則需要格外小心。例如,在上面的示例中,Formatter 已設置了格式字符串,其在 LogRecord 的屬性字典中鍵值為 “clientip” 和 “user”。如果缺少這些內(nèi)容,則將不會記錄該消息,因為會引發(fā)字符串格式化異常。因此,在這種情況下,您始終需要使用 extra 字典傳遞這些鍵。

盡管這可能很煩人,但此功能旨在用于特殊情況,例如在多個上下文中執(zhí)行相同代碼的多線程服務器,并且出現(xiàn)的有趣條件取決于此上下文(例如在上面的示例中就是遠程客戶端IP地址和已驗證用戶名)。在這種情況下,很可能將專門的 Formatter 與特定的 Handler 一起使用。

If no handler is attached to this logger (or any of its ancestors, taking into account the relevant Logger.propagate attributes), the message will be sent to the handler set on lastResort.

在 3.2 版更改: 增加了 stack_info 參數(shù)。

在 3.5 版更改: exc_info 參數(shù)現(xiàn)在可以接受異常實例。

在 3.8 版更改: 增加了 stacklevel 參數(shù)。

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

在此記錄器上記錄 INFO 級別的消息。參數(shù)解釋同 debug()。

warning(msg, *args, **kwargs)?

在此記錄器上記錄 WARNING 級別的消息。參數(shù)解釋同 debug()。

備注

有一個功能上與 warning 一致的方法 warn。由于 warn 已被棄用,請不要使用它 —— 改為使用 warning。

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

在此記錄器上記錄 ERROR 級別的消息。參數(shù)解釋同 debug()

critical(msg, *args, **kwargs)?

在此記錄器上記錄 CRITICAL 級別的消息。參數(shù)解釋同 debug()。

log(level, msg, *args, **kwargs)?

在此記錄器上記錄 level 整數(shù)代表的級別的消息。參數(shù)解釋同 debug()。

exception(msg, *args, **kwargs)?

在此記錄器上記錄 ERROR 級別的消息。參數(shù)解釋同 debug()。異常信息將添加到日志消息中。僅應從異常處理程序中調用此方法。

addFilter(filter)?

將指定的過濾器 filter 添加到此記錄器。

removeFilter(filter)?

從此記錄器中刪除指定的過濾器 filter。

filter(record)?

將此記錄器的過濾器應用于記錄,如果記錄能被處理則返回 True。過濾器會被依次使用,直到其中一個返回假值為止。如果它們都不返回假值,則記錄將被處理(傳遞給處理器)。如果返回任一為假值,則不會對該記錄做進一步處理。

addHandler(hdlr)?

將指定的處理器 hdlr 添加到此記錄器。

removeHandler(hdlr)?

從此記錄器中刪除指定的處理器 hdlr

findCaller(stack_info=False, stacklevel=1)?

查找調用源的文件名和行號,以 文件名,行號,函數(shù)名稱和堆棧信息 4元素元組的形式返回。堆棧信息將返回 None,除非 stack_infoTrue。

stacklevel 參數(shù)用于調用 debug() 和其他 API。如果大于 1,則多余部分將用于跳過堆棧幀,然后再確定要返回的值。當從幫助器/包裝器代碼調用日志記錄 API 時,這通常很有用,以便事件日志中的信息不是來自幫助器/包裝器代碼,而是來自調用它的代碼。

handle(record)?

通過將記錄傳遞給與此記錄器及其祖先關聯(lián)的所有處理器來處理(直到某個 propagate 值為 false)。此方法用于從套接字接收的未序列化的以及在本地創(chuàng)建的記錄。使用 filter() 進行記錄器級別過濾。

makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)?

這是一種工廠方法,可以在子類中對其進行重寫以創(chuàng)建專門的 LogRecord 實例。

hasHandlers()?

檢查此記錄器是否配置了任何處理器。通過在此記錄器及其記錄器層次結構中的父級中查找處理器完成此操作。如果找到處理器則返回 True,否則返回 False。只要找到 “propagate” 屬性設置為假值的記錄器,該方法就會停止搜索層次結構 —— 其將是最后一個檢查處理器是否存在的記錄器。

3.2 新版功能.

在 3.7 版更改: 現(xiàn)在可以對處理器進行序列化和反序列化。

日志級別?

日志記錄級別的數(shù)值在下表中給出。如果你想要定義自己的級別,并且需要它們具有相對于預定義級別的特定值,那么這你可能對以下內(nèi)容感興趣。如果你定義具有相同數(shù)值的級別,它將覆蓋預定義的值;預定義的名稱將失效。

級別

數(shù)值

CRITICAL

50

ERROR

40

WARNING

30

INFO

20

DEBUG

10

NOTSET

0

處理器對象?

Handler 有以下屬性和方法。注意不要直接實例化 Handler ;這個類用來派生其他更有用的子類。但是,子類的 __init__() 方法需要調用 Handler.__init__() 。

class logging.Handler?
__init__(level=NOTSET)?

初始化 Handler 實例時,需要設置它的級別,將過濾列表置為空,并且創(chuàng)建鎖(通過 createLock() )來序列化對 I/O 的訪問。

createLock()?

初始化一個線程鎖,用來序列化對底層的 I/O 功能的訪問,底層的 I/O 功能可能不是線程安全的。

acquire()?

獲取由 createLock() 創(chuàng)建的線程鎖。

release()?

釋放由 acquire() 獲取的線程鎖。

setLevel(level)?

給處理器設置閾值為 level 。日志級別小于 level 將被忽略。創(chuàng)建處理器時,日志級別被設置為 NOTSET (所有的消息都會被處理)。

參見 日志級別 級別列表。

在 3.2 版更改: level 形參現(xiàn)在接受像 'INFO' 這樣的字符串形式的級別表達方式,也可以使用像 INFO 這樣的整數(shù)常量。

setFormatter(fmt)?

將此處理器的 Formatter 設置為 fmt。

addFilter(filter)?

將指定的過濾器 filter 添加到此處理器。

removeFilter(filter)?

從此處理器中刪除指定的過濾器 filter 。

filter(record)?

將此處理器的過濾器應用于記錄,在要處理記錄時返回 True 。依次查詢過濾器,直到其中一個返回假值為止。如果它們都不返回假值,則將發(fā)出記錄。如果返回一個假值,則處理器將不會發(fā)出記錄。

flush()?

確保所有日志記錄從緩存輸出。此版本不執(zhí)行任何操作,并且應由子類實現(xiàn)。

close()?

回收處理器使用的所有資源。此版本不輸出,但從內(nèi)部處理器列表中刪除處理器,內(nèi)部處理器在 shutdown() 被調用時關閉 。子類應確保從重寫的 close() 方法中調用此方法。

handle(record)?

經(jīng)已添加到處理器的過濾器過濾后,有條件地發(fā)出指定的日志記錄。用獲取/釋放 I/O 線程鎖包裝了記錄的實際發(fā)出行為。

handleError(record)?

調用 emit() 期間遇到異常時,應從處理器中調用此方法。如果模塊級屬性 raiseExceptionsFalse,則異常將被靜默忽略。這是大多數(shù)情況下日志系統(tǒng)需要的 —— 大多數(shù)用戶不會關心日志系統(tǒng)中的錯誤,他們對應用程序錯誤更感興趣。但是,你可以根據(jù)需要將其替換為自定義處理器。指定的記錄是發(fā)生異常時正在處理的記錄。(raiseExceptions 的默認值是 True,因為這在開發(fā)過程中是比較有用的)。

format(record)?

如果設置了格式器則用其對記錄進行格式化。否則,使用模塊的默認格式器。

emit(record)?

執(zhí)行實際記錄給定日志記錄所需的操作。這個版本應由子類實現(xiàn),因此這里直接引發(fā) NotImplementedError 異常。

有關作為標準隨附的處理器列表,請參見 logging.handlers。

格式器對象?

Formatter 對象擁有以下的屬性和方法。一般情況下,它們負責將 LogRecord 轉換為可由人或外部系統(tǒng)解釋的字符串。基礎的 Formatter 允許指定格式字符串。如果未提供任何值,則使用默認值 '%(message)s' ,它僅將消息包括在日志記錄調用中。要在格式化輸出中包含其他信息(如時間戳),請閱讀下文。

格式器可以使用格式化字符串來初始化,該字符串利用 LogRecord 的屬性 —— 例如上述默認值,用戶的消息和參數(shù)預先格式化為 LogRecordmessage 屬性后被使用。此格式字符串包含標準的 Python %-s 樣式映射鍵。有關字符串格式的更多信息,請參見 printf 風格的字符串格式化。

LogRecord 屬性 一節(jié)中給出了 LogRecord 中有用的映射鍵。

class logging.Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)?

返回 Formatter 類的新實例。實例將使用整個消息的格式字符串以及消息的日期/時間部分的格式字符串進行初始化。如果未指定 fmt ,則使用 '%(message)s'。如果未指定 datefmt,則使用 formatTime() 文檔中描述的格式。

style 形參可以是 '%', '{' 或 '$' 之一,它決定格式字符串將如何與數(shù)據(jù)進行合并:使用 %-formatting, str.format() 或是 string.Template。 這僅適用于格式字符串 fmt (例如 '%(message)s'{message}),不適用于傳遞給 Logger.debug 的實際日志消息等;請參閱 生效于整個應用程序的格式化樣式 了解有關在日志消息中使用 {- 和 $-formatting 的更多詳情。

defaults 形參可以是一個包含在自定義字段中使用的默認值的字典。 例如: logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})

在 3.2 版更改: 加入了 style 形參。

在 3.8 版更改: 加入*validate* 參數(shù)。不正確或不匹配的樣式和格式將引發(fā) ValueError 錯誤。例如: logging.Formatter('%(asctime)s - %(message)s', style='{')。

在 3.10 版更改: 增加了 defaults 形參。

format(record)?

記錄的屬性字典被用作字符串格式化操作的操作數(shù)。 返回結果字符串。 在格式化該字典之前,會執(zhí)行幾個預備步驟。 記錄的 message 屬性是用 msg % args 來計算的。 如果格式化字符串包含 '(asctime)',則會調用 formatTime() 來格式化事件時間。 如果有異常信息,則使用 formatException() 將其格式化并添加到消息中。 請注意已格式化的異常信息會緩存在 exc_text 屬性中。 這很有用因為異常信息可以被 pickle 并通過網(wǎng)絡發(fā)送,但是如果你有不止一個對異常信息進行定制的 Formatter 子類則應當小心。 在這種情況下,你必須在一個格式化器完成格式化后清空緩存的值 (通過將 exc_text 屬性設為 None),以便下一個處理事件的格式化器不會使用緩存的值,而是重新計算它。

如果棧信息可用,它將被添加在異常信息之后,如有必要請使用 formatStack() 來轉換它。

formatTime(record, datefmt=None)?

此方法應由想要使用格式化時間的格式器中的 format() 調用??梢栽诟袷狡髦兄貙懘朔椒ㄒ蕴峁┤魏翁囟ㄒ?,但是基本行為如下:如果指定了 datefmt (字符串),則將其用于 time.strftime() 來格式化記錄的創(chuàng)建時間。否則,使用格式 '%Y-%m-%d %H:%M:%S,uuu',其中 uuu 部分是毫秒值,其他字母根據(jù) time.strftime() 文檔。這種時間格式的示例為 2003-01-23 00:29:50,411。返回結果字符串。

此函數(shù)使用一個用戶可配置函數(shù)將創(chuàng)建時間轉換為元組。 默認情況下,使用 time.localtime();要為特定格式化程序實例更改此項,請將實例的 converter 屬性設為具有與 time.localtime()time.gmtime() 相同簽名的函數(shù)。 要為所有格式化程序更改此項,例如當你希望所有日志時間都顯示為 GMT,請在 Formatter 類中設置 converter 屬性。

在 3.3 版更改: 在之前版本中,默認格式是被硬編碼的,例如這個例子: 2010-09-06 22:38:15,292 其中逗號之前的部分由 strptime 格式字符串 ('%Y-%m-%d %H:%M:%S') 處理,而逗號之后的部分為毫秒值。 因為 strptime 沒有表示毫秒的占位符,毫秒值使用了另外的格式字符串來添加 '%s,%03d' --- 這兩個格式字符串代碼都是硬編碼在該方法中的。 經(jīng)過修改,這些字符串被定義為類層級的屬性,當需要時可以在實例層級上被重載。 屬性的名稱為 default_time_format (用于 strptime 格式字符串) 和 default_msec_format (用于添加毫秒值)。

在 3.9 版更改: default_msec_format 可以為 None

formatException(exc_info)?

將指定的異常信息(由 sys.exc_info() 返回的標準異常元組)格式化為字符串。默認實現(xiàn)只是使用了 traceback.print_exception()。 結果字符串將被返回。

formatStack(stack_info)?

將指定的堆棧信息(由 traceback.print_stack() 返回的字符串,但移除末尾的換行符)格式化為字符串。 默認實現(xiàn)只是返回輸入值。

過濾器對象?

Filters 可被 HandlersLoggers 用來實現(xiàn)比按層級提供更復雜的過濾操作。 基本過濾器類只允許低于日志記錄器層級結構中低于特定層級的事件。 例如,一個用 'A.B' 初始化的過濾器將允許 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' 等日志記錄器所記錄的事件。 但 'A.BB', 'B.A.B' 等則不允許。 如果用空字符串初始化,則所有事件都會通過。

class logging.Filter(name='')?

返回一個 Filter 類的實例。 如果指定了 name,則它將被用來為日志記錄器命名,該類及其子類將通過該過濾器允許指定事件通過。 如果 name 為空字符串,則允許所有事件通過。

filter(record)?

是否要記錄指定的記錄?返回零表示否,非零表示是。如果認為合適,則可以通過此方法就地修改記錄。

請注意關聯(lián)到處理器的過濾器會在事件由處理器發(fā)出之前被查詢,而關聯(lián)到日志記錄器的過濾器則會在有事件被記錄的的任何時候(使用 debug(), info() 等等)在將事件發(fā)送給處理器之前被查詢。 這意味著由后代日志記錄器生成的事件將不會被父代日志記錄器的過濾器設置所過濾,除非該過濾器也已被應用于后代日志記錄器。

你實際上不需要子類化 Filter :你可以傳入任何一個包含有相同語義的 filter 方法的實例。

在 3.2 版更改: 你不需要創(chuàng)建專門的 Filter 類,或使用具有 filter 方法的其他類:你可以使用一個函數(shù)(或其他可調用對象)作為過濾器。 過濾邏輯將檢查過濾器對象是否具有 filter 屬性:如果有,就會將它當作是 Filter 并調用它的 filter() 方法。 在其他情況下,則會將它當作是可調用對象并將記錄作為唯一的形參進行調用。 返回值應當與 filter() 的返回值相一致。

盡管過濾器主要被用來構造比層級更復雜的規(guī)則以過濾記錄,但它們可以查看由它們關聯(lián)的處理器或記錄器所處理的每條記錄:當你想要執(zhí)行統(tǒng)計特定記錄器或處理器共處理了多少條記錄,或是在所處理的 LogRecord 中添加、修改或移除屬性這樣的任務時該特性將很有用處。 顯然改變 LogRecord 時需要相當小心,但將上下文信息注入日志確實是被允許的 (參見 使用過濾器傳遞上下文信息)。

LogRecord 屬性?

LogRecord 實例是每當有日志被記錄時由 Logger 自動創(chuàng)建的,并且可通過 makeLogRecord() 手動創(chuàng)建(例如根據(jù)從網(wǎng)絡接收的已封存事件創(chuàng)建)。

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

包含與被記錄的事件相關的所有信息。

主要信息是在 msgargs 中傳遞的,它們使用 msg % args 組合到一起以創(chuàng)建記錄的 message 字段。

參數(shù)
  • name -- 用于記錄由此 LogRecord 所表示事件的記錄器名稱。 請注意此名稱將始終為該值,即使它可能是由附加到不同(祖先)日志記錄器的處理器所發(fā)出的。

  • level -- 以數(shù)字表示的日志記錄事件層級(如 DEBUG, INFO 等)。 請注意這會轉換為 LogRecord 的 兩個 屬性: levelno 為數(shù)字值而 levelname 為對應的層級名稱。

  • pathname -- 進行日志記錄調用的文件的完整路徑名。

  • lineno -- 記錄調用所在源文件中的行號。

  • msg -- 事件描述消息,可能為帶有可變數(shù)據(jù)占位符的格式字符串。

  • args -- 要合并到 msg 參數(shù)以獲得事件描述的可變數(shù)據(jù)。

  • exc_info -- 包含當前異常信息的異常元組,或者如果沒有可用異常信息則為 None。

  • func -- 發(fā)起調用日志記錄調用的函數(shù)或方法名稱。

  • sinfo -- 一個文本字符串,表示當前線程中從堆棧底部直到日志記錄調用的堆棧信息。

getMessage()?

在將 LogRecord 實例與任何用戶提供的參數(shù)合并之后,返回此實例的消息。 如果用戶提供給日志記錄調用的消息參數(shù)不是字符串,則會在其上調用 str() 以將它轉換為字符串。 此方法允許將用戶定義的類用作消息,類的 __str__ 方法可以返回要使用的實際格式字符串。

在 3.2 版更改: 通過提供用于創(chuàng)建記錄的工廠方法已使得 LogRecord 的創(chuàng)建更易于配置。 該工廠方法可使用 getLogRecordFactory()setLogRecordFactory() (在此可查看工廠方法的簽名)來設置。

在創(chuàng)建時可使用此功能將你自己的值注入 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)

通過此模式,多個工廠方法可以被鏈接起來,并且只要它們不重載彼此的屬性或是在無意中覆蓋了上面列出的標準屬性,就不會發(fā)生意外。

LogRecord 屬性?

LogRecord 具有許多屬性,它們大多數(shù)來自于傳遞給構造器的形參。 (請注意 LogRecord 構造器形參與 LogRecord 屬性的名稱并不總是完全彼此對應的。) 這些屬性可被用于將來自記錄的數(shù)據(jù)合并到格式字符串中。 下面的表格(按字母順序)列出了屬性名稱、它們的含義以及相應的 %-style 格式字符串內(nèi)占位符。

如果是使用 {}-格式化(str.format()),你可以將 {attrname} 用作格式字符串內(nèi)的占位符。 如果是使用 $-格式化(string.Template),則會使用 ${attrname} 的形式。 當然在這兩種情況下,都應當將 attrname 替換為你想要使用的實際屬性名稱。

在 {}-格式化的情況下,你可以在屬性名稱之后放置指定的格式化旗標,并用冒號來分隔兩者。 例如,占位符 {msecs:03d} 會將毫秒值 4 格式化為 004。 請參看 str.format() 文檔了解你所能使用的選項的完整細節(jié)。

屬性名稱

格式

描述

args

此屬性不需要用戶進行格式化。

合并到 msg 以產(chǎn)生 message 的包含參數(shù)的元組,或是其中的值將被用于合并的字典(當只有一個參數(shù)且其類型為字典時)。

asctime

%(asctime)s

表示人類易讀的 LogRecord 生成時間。 默認形式為 '2003-07-08 16:49:45,896' (逗號之后的數(shù)字為時間的毫秒部分)。

created

%(created)f

LogRecord 被創(chuàng)建的時間(即 time.time() 的返回值)。

exc_info

此屬性不需要用戶進行格式化。

異常元組(例如 sys.exc_info)或者如未發(fā)生異常則為 None

filename

%(filename)s

pathname 的文件名部分。

funcName

%(funcName)s

函數(shù)名包括調用日志記錄.

levelname

%(levelname)s

消息文本記錄級別('DEBUG''INFO','WARNING','ERROR''CRITICAL')。

levelno

%(levelno)s

消息數(shù)字的記錄級別 (DEBUG, INFO, WARNING, ERROR, CRITICAL).

lineno

%(lineno)d

發(fā)出日志記錄調用所在的源行號(如果可用)。

message

%(message)s

記入日志的消息,即 msg % args 的結果。 這是在發(fā)起調用 Formatter.format() 時設置的。

module

%(module)s

模塊 (filename 的名稱部分)。

msecs

%(msecs)d

LogRecord 被創(chuàng)建的時間的毫秒部分。

msg

此屬性不需要用戶進行格式化。

在原始日志記錄調用中傳入的格式字符串。 與 args 合并以產(chǎn)生 message,或是一個任意對象 (參見 使用任意對象作為消息)。

name

%(name)s

用于記錄調用的日志記錄器名稱。

pathname

%(pathname)s

發(fā)出日志記錄調用的源文件的完整路徑名(如果可用)。

process

%(process)d

進程ID(如果可用)

processName

%(processName)s

進程名(如果可用)

relativeCreated

%(relativeCreated)d

以毫秒數(shù)表示的 LogRecord 被創(chuàng)建的時間,即相對于 logging 模塊被加載時間的差值。

stack_info

此屬性不需要用戶進行格式化。

當前線程中從堆棧底部起向上直到包括日志記錄調用并引發(fā)創(chuàng)建當前記錄堆棧幀創(chuàng)建的堆棧幀信息(如果可用)。

thread

%(thread)d

線程ID(如果可用)

threadName

%(threadName)s

線程名(如果可用)

taskName

%(taskName)s

asyncio.Task name (if available).

在 3.1 版更改: 添加了 processName

在 3.12 版更改: taskName was added.

LoggerAdapter 對象?

LoggerAdapter 實例會被用來方便地將上下文信息傳入日志記錄調用。 要獲取用法示例,請參閱 添加上下文信息到你的日志記錄輸出 部分。

class logging.LoggerAdapter(logger, extra)?

返回一個 LoggerAdapter 的實例,該實例的初始化使用了下層的 Logger 實例和一個字典類對象。

process(msg, kwargs)?

修改傳遞給日志記錄調用的消息和/或關鍵字參數(shù)以便插入上下文信息。 此實現(xiàn)接受以 extra 形式傳給構造器的對象并使用 'extra' 鍵名將其加入 kwargs。 返回值為一個 (msg, kwargs) 元組,其包含(可能經(jīng)過修改的)傳入?yún)?shù)。

在上述方法之外,LoggerAdapter 還支持 Logger 的下列方法: debug(), info(),warning(),error(), exception(), critical()log(),isEnabledFor()getEffectiveLevel(),setLevel() 以及 hasHandlers()。 這些方法具有與它們在 Logger 中的對應方法相同的簽名,因此你可以互換使用這兩種類型的實例。

在 3.2 版更改: isEnabledFor(), getEffectiveLevel(), setLevel()hasHandlers() 方法已被添加到 LoggerAdapter。 這些方法會委托給下層的日志記錄器。

在 3.6 版更改: 增加了 manager 屬性和 _log() 方法,它們會委托給下層的日志記錄器并允許適配器嵌套。

線程安全?

logging 模塊的目標是使客戶端不必執(zhí)行任何特殊操作即可確保線程安全。 它通過使用線程鎖來達成這個目標;用一個鎖來序列化對模塊共享數(shù)據(jù)的訪問,并且每個處理程序也會創(chuàng)建一個鎖來序列化對其下層 I/O 的訪問。

如果你要使用 signal 模塊來實現(xiàn)異步信號處理程序,則可能無法在這些處理程序中使用 logging。 這是因為 threading 模塊中的鎖實現(xiàn)并非總是可重入的,所以無法從此類信號處理程序發(fā)起調用。

模塊級函數(shù)?

在上述的類之外,還有一些模塊級的函數(shù)。

logging.getLogger(name=None)?

返回具有指定 name 的日志記錄器,或者當 name 為 None 時返回層級結構中的根日志記錄器。 如果指定了 name,它通常是以點號分隔的帶層級結構的名稱,如 'a'、'a.b''a.b.c.d'。 這些名稱的選擇完全取決于使用 logging 的開發(fā)者。

所有用給定的 name 對該函數(shù)的調用都將返回相同的日志記錄器實例。 這意味著日志記錄器實例不需要在應用的各部分間傳遞。

logging.getLoggerClass()?

返回標準的 Logger 類,或是最近傳給 setLoggerClass() 的類。 此函數(shù)可以從一個新的類定義中調用,以確保安裝自定義的 Logger 類不會撤銷其他代碼已經(jīng)應用的自定義操作。 例如:

class MyLogger(logging.getLoggerClass()):
    # ... override behaviour here
logging.getLogRecordFactory()?

返回一個被用來創(chuàng)建 LogRecord 的可調用對象。

3.2 新版功能: 此函數(shù)與 setLogRecordFactory() 一起提供,以允許開發(fā)者對表示日志記錄事件的 LogRecord 的構造有更好的控制。

請參閱 setLogRecordFactory() 了解有關如何調用該工廠方法的更多信息。

logging.debug(msg, *args, **kwargs)?

在根日志記錄器上記錄一條 DEBUG 級別的消息。 msg 是消息格式字符串,而 args 是要使用字符串格式化運算符合并到 msg 的參數(shù)。 (請注意這意味著你可以在格式字符串中使用關鍵字以及單個字典參數(shù)。)

kwargs 中有三個關鍵字參數(shù)會被檢查: exc_info 參數(shù)如果不為假值則會將異常信息添加到日志記錄消息。 如果提供了異常元組(為 sys.exc_info() 的返回值格式)或異常實例則它會被使用;在其他情況下,會調用 sys.exc_info() 以獲取異常信息。

第二個可選關鍵字參數(shù)是 stack_info,默認為 False。如果為 True,則將堆棧信息添加到日志消息中,包括實際的日志調用。請注意,這與通過指定 exc_info 顯示的堆棧信息不同:前者是從堆棧底部到當前線程中的日志記錄調用的堆棧幀,而后者是在搜索異常處理程序時,跟蹤異常而打開的堆棧幀的信息。

您可以獨立于 exc_info 來指定 stack_info,例如,即使在未引發(fā)任何異常的情況下,也可以顯示如何到達代碼中的特定點。堆棧幀在標題行之后打?。?/p>

Stack (most recent call last):

這模仿了顯示異常幀時所使用的 Traceback (most recent call last): 。

第三個可選關鍵字參數(shù)是 extra,它可被用來傳遞一個字典,該字典會被用來填充為日志記錄事件創(chuàng)建并附帶用戶自定義屬性的 LogRecord 的 __dict__。 之后將可按你的需要使用這些自定義屬性。 例如,可以將它們合并到已記錄的消息中。 舉例來說:

FORMAT = '%(asctime)s %(clientip)-15s %(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)

應當會打印出這樣的內(nèi)容:

2006-02-08 22:20:02,165 192.168.0.1 fbloggs  Protocol problem: connection reset

extra 中傳入的字典的鍵不應與日志系統(tǒng)使用的鍵沖突。(有關日志系統(tǒng)使用哪些鍵的更多信息,請參見 Formatter 的文檔。)

如果你選擇在已記錄的消息中使用這些屬性,則需要格外小心。 例如在上面的示例中,Formatter 已設置了格式字符串,其在 LogRecord 的屬性字典中應有 'clientip' 和 'user'。 如果缺少這些屬性,消息將不被記錄,因為會引發(fā)字符串格式化異常,你始終需要傳入帶有這些鍵的 extra 字典。

盡管這可能很煩人,但此功能旨在用于特殊情況,例如在多個上下文中執(zhí)行相同代碼的多線程服務器,并且出現(xiàn)的有趣條件取決于此上下文(例如在上面的示例中就是遠程客戶端IP地址和已驗證用戶名)。在這種情況下,很可能將專門的 Formatter 與特定的 Handler 一起使用。

This function (as well as info(), warning(), error() and critical()) will call basicConfig() if the root logger doesn't have any handler attached.

在 3.2 版更改: 增加了 stack_info 參數(shù)。

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

在根日志記錄器上記錄一條 INFO 級別的消息。 參數(shù)解釋同 debug()。

logging.warning(msg, *args, **kwargs)?

在根日志記錄器上記錄一條 WARNING 級別的消息。 參數(shù)解釋同 debug()。

備注

有一個已過時方法 warn 其功能與 warning 一致。 由于 warn 已被棄用,請不要使用它 —— 而是改用 warning。

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

在根日志記錄器上記錄一條 ERROR 級別的消息。 參數(shù)解釋同 debug()。

logging.critical(msg, *args, **kwargs)?

在根日志記錄器上記錄一條 CRITICAL 級別的消息。 參數(shù)解釋同 debug()。

logging.exception(msg, *args, **kwargs)?

在根日志記錄器上記錄一條 ERROR 級別的消息。 參數(shù)解釋同 debug()。 異常信息將被添加到日志消息中。 此函數(shù)應當僅從異常處理程序中調用。

logging.log(level, msg, *args, **kwargs)?

在根日志記錄器上記錄一條 level 級別的消息。 其他參數(shù)解釋同 debug()。

logging.disable(level=CRITICAL)?

為所有日志記錄器提供重載的級別 level,其優(yōu)先級高于日志記錄器自己的級別。 當需要臨時限制整個應用程序中的日志記錄輸出時,此功能會很有用。 它的效果是禁用所有重要程度為 level 及以下的日志記錄調用,因此如果你附帶 INFO 值調用它,則所有 INFO 和 DEBUG 事件就會被丟棄,而重要程度為 WARNING 以及上的事件將根據(jù)日志記錄器的當前有效級別來處理。 如果 logging.disable(logging.NOTSET) 被調用,它將移除這個重載的級別,因此日志記錄輸出會再次取決于單個日志記錄器的有效級別。

請注意如果你定義了任何高于 CRITICAL 的自定義日志級別(并不建議這樣做),你就將無法沿用 level 形參的默認值,而必須顯式地提供適當?shù)闹怠?/p>

在 3.7 版更改: level 形參默認級別為 CRITICAL。 請參閱 bpo-28524 了解此項改變的更多細節(jié)。

logging.addLevelName(level, levelName)?

在一個內(nèi)部字典中關聯(lián)級別 level 與文本 levelName,該字典會被用來將數(shù)字級別映射為文本表示形式,例如在 Formatter 格式化消息的時候。 此函數(shù)也可被用來定義你自己的級別。 唯一的限制是自定義的所有級別必須使用此函數(shù)來注冊,級別值必須為正整數(shù)并且其應隨嚴重程度而遞增。

備注

如果你考慮要定義你自己的級別,請參閱 自定義級別 部分。

logging.getLevelNamesMapping()?

Returns a mapping from level names to their corresponding logging levels. For example, the string "CRITICAL" maps to CRITICAL. The returned mapping is copied from an internal mapping on each call to this function.

3.11 新版功能.

logging.getLevelName(level)?

返回日志記錄級別 level 的字符串表示。

如果 level 為預定義的級別 CRITICAL, ERROR, WARNING, INFODEBUG 之一則你會得到相應的字符串。 如果你使用 addLevelName() 將級別關聯(lián)到名稱則返回你為 level 所關聯(lián)的名稱。 如果傳入了與已定義級別相對應的數(shù)字值,則返回對應的字符串表示。

level 形參也接受級別的字符串表示例如 'INFO'。 在這種情況下,此函數(shù)將返回級別所對應的數(shù)字值。

如果未傳入可匹配的數(shù)字或字符串值,則返回字符串 'Level %s' % level。

備注

級別在內(nèi)部以整數(shù)表示(因為它們在日志記錄邏輯中需要進行比較)。 此函數(shù)被用于在整數(shù)級別與通過 %(levelname)s 格式描述符方式在格式化日志輸出中顯示的級別名稱之間進行相互的轉換 (參見 LogRecord 屬性)。

在 3.4 版更改: 在早于 3.4 的 Python 版本中,此函數(shù)也可傳入一個字符串形式的級別名稱,并將返回對應的級別數(shù)字值。 此未記入文檔的行為被視為是一個錯誤,并在 Python 3.4 中被移除,但又在 3.4.2 中被恢復以保持向下兼容性。

logging.makeLogRecord(attrdict)?

創(chuàng)建并返回一個新的 LogRecord 實例,實例屬性由 attrdict 定義。 此函數(shù)適用于接受一個通過套接字傳輸?shù)姆獯婧玫?LogRecord 屬性字典,并在接收端將其重建為一個 LogRecord 實例。

logging.basicConfig(**kwargs)?

通過使用默認的 Formatter 創(chuàng)建一個 StreamHandler 并將其加入根日志記錄器來為日志記錄系統(tǒng)執(zhí)行基本配置。 如果沒有為根日志記錄器定義處理器則 debug(), info(), warning(), error()critical() 等函數(shù)將自動調用 basicConfig()。

如果根日志記錄器已配置了處理器則此函數(shù)將不執(zhí)行任何操作,除非關鍵字參數(shù) force 被設為 True

備注

此函數(shù)應當在其他線程啟動之前從主線程被調用。 在 2.7.1 和 3.2 之前的 Python 版本中,如果此函數(shù)從多個線程被調用,一個處理器(在極少的情況下)有可能被多次加入根日志記錄器,導致非預期的結果例如日志中的消息出現(xiàn)重復。

支持以下關鍵字參數(shù)。

格式

描述

filename

使用指定的文件名創(chuàng)建一個 FileHandler,而不是 StreamHandler。

filemode

如果指定了 filename,則用此 模式 打開該文件。 默認模式為 'a'。

format

使用指定的格式字符串作為處理器。 默認為屬性以冒號分隔的 levelname, namemessage。

datefmt

使用指定的日期/時間格式,與 time.strftime() 所接受的格式相同。

style

如果指定了 format,將為格式字符串使用此風格。 '%', '{''$' 分別對應于 printf 風格, str.format()string.Template。 默認為 '%'。

level

設置根記錄器級別為指定的 level.

stream

使用指定的流初始化 StreamHandler。 請注意此參數(shù)與 filename 不兼容 —— 如果兩者同時存在,則會引發(fā) ValueError。

handlers

如果指定,這應為一個包含要加入根日志記錄器的已創(chuàng)建處理器的可迭代對象。 任何尚未設置格式描述符的處理器將被設置為在此函數(shù)中創(chuàng)建的默認格式描述符。 請注意此參數(shù)與 filenamestream 不兼容 —— 如果兩者同時存在,則會引發(fā) ValueError。

force

如果將此關鍵字參數(shù)指定為 true,則在執(zhí)行其他參數(shù)指定的配置之前,將移除并關閉附加到根記錄器的所有現(xiàn)有處理器。

encoding

如果此關鍵字參數(shù)與 filename 一同被指定,則其值會在創(chuàng)建 FileHandler 時被使用,因而也會在打開輸出文件時被使用。

errors

如果此關鍵字參數(shù)與 filename 一同被指定,則其值會在創(chuàng)建 FileHandler 時被使用,因而也會在打開輸出文件時被使用。 如果未指定,則會使用值 'backslashreplace'。 請注意如果指定為 None,它將被原樣傳給 open(),這意味著它將會當作傳入 'errors' 一樣處理。

在 3.2 版更改: 增加了 style 參數(shù)。

在 3.3 版更改: 增加了 handlers 參數(shù)。 增加了額外的檢查來捕獲指定不兼容參數(shù)的情況 (例如同時指定 handlersstreamfilename,或者同時指定 streamfilename)。

在 3.8 版更改: 增加了 force 參數(shù)。

在 3.9 版更改: 增加了 encodingerrors 參數(shù)。

logging.shutdown()?

通過刷新和關閉所有處理程序來通知日志記錄系統(tǒng)執(zhí)行有序停止。 此函數(shù)應當在應用退出時被調用并且在此調用之后不應再使用日志記錄系統(tǒng)。

當 logging 模塊被導入時,它會將此函數(shù)注冊為退出處理程序 (參見 atexit),因此通常不需要手動執(zhí)行該操作。

logging.setLoggerClass(klass)?

通知日志記錄系統(tǒng)在實例化日志記錄器時使用 klass 類。 該類應當定義 __init__() 使其只要求一個 name 參數(shù),并且 __init__() 應當調用 Logger.__init__()。 此函數(shù)通常會在需要使用自定義日志記錄器行為的應用程序實例化任何日志記錄器之前被調用。 在此調用之后,在任何其他時刻都不要使用該子類來直接實例化日志記錄器:請繼續(xù)使用 logging.getLogger() API 來獲取你的日志記錄器。

logging.setLogRecordFactory(factory)?

設置一個用來創(chuàng)建 LogRecord 的可調用對象。

參數(shù)

factory -- 用來實例化日志記錄的工廠可調用對象。

3.2 新版功能: 此函數(shù)與 getLogRecordFactory() 一起提供,以便允許開發(fā)者對如何構造表示日志記錄事件的 LogRecord 有更好的控制。

可調用對象 factory 具有如下簽名:

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

name

日志記錄器名稱

level

日志記錄級別(數(shù)字)。

fn

進行日志記錄調用的文件的完整路徑名。

lno

記錄調用所在文件中的行號。

msg

日志消息。

args

日志記錄消息的參數(shù)。

exc_info

異常元組,或 None 。

func

調用日志記錄調用的函數(shù)或方法的名稱。

sinfo

traceback.print_stack() 所提供的類似的?;厮菪畔?,顯示調用的層級結構。

kwargs

其他關鍵字參數(shù)。

模塊級屬性?

logging.lastResort?

通過此屬性提供的“最后處理者”。 這是一個以 WARNING 級別寫入到 sys.stderrStreamHandler,用于在沒有任何日志記錄配置的情況下處理日志記錄事件。 最終結果就是將消息打印到 sys.stderr,這會替代先前形式為 "no handlers could be found for logger XYZ" 的錯誤消息。 如果出于某種原因你需要先前的行為,可將 lastResort 設為 None。

3.2 新版功能.

與警告模塊集成?

captureWarnings() 函數(shù)可用來將 loggingwarnings 模塊集成。

logging.captureWarnings(capture)?

此函數(shù)用于打開和關閉日志系統(tǒng)對警告的捕獲。

如果 captureTrue,則 warnings 模塊發(fā)出的警告將重定向到日志記錄系統(tǒng)。具體來說,將使用 warnings.formatwarning() 格式化警告信息,并將結果字符串使用 WARNING 等級記錄到名為 'py.warnings' 的記錄器中。

如果 captureFalse,則將停止將警告重定向到日志記錄系統(tǒng),并且將警告重定向到其原始目標(即在 captureWarnings(True) 調用之前的有效目標)。

參見

logging.config 模塊

日志記錄模塊的配置 API 。

logging.handlers 模塊

日志記錄模塊附帶的有用處理器。

PEP 282 - Logging 系統(tǒng)

該提案描述了Python標準庫中包含的這個特性。

Original Python logging package

這是該 logging 包的原始來源。該站點提供的軟件包版本適用于 Python 1.5.2、2.1.x 和 2.2.x,它們不被 logging 包含在標準庫中。