模塊 logging --- Python 的日志記錄工具?
這個(gè)模塊為應(yīng)用與庫(kù)定義了實(shí)現(xiàn)靈活的事件日志系統(tǒng)的函數(shù)與類.
使用標(biāo)準(zhǔn)庫(kù)提提供的 logging API 最主要的好處是,所有的 Python 模塊都可能參與日志輸出,包括你的日志消息和第三方模塊的日志消息。
這個(gè)模塊提供許多強(qiáng)大而靈活的功能。如果你對(duì) logging 不太熟悉的話, 掌握它最好的方式就是查看它對(duì)應(yīng)的教程(詳見右側(cè)的鏈接)。
該模塊定義的基礎(chǔ)類和函數(shù)都列在下面。
記錄器暴露了應(yīng)用程序代碼直接使用的接口。
處理程序?qū)⑷罩居涗洠ㄓ捎涗浧鲃?chuàng)建)發(fā)送到適當(dāng)?shù)哪繕?biāo)。
過濾器提供了更精細(xì)的附加功能,用于確定要輸出的日志記錄。
格式化程序指定最終輸出中日志記錄的樣式。
Logger 對(duì)象?
Loggers 有以下的屬性和方法。注意 永遠(yuǎn) 不要直接實(shí)例化 Loggers,應(yīng)當(dāng)通過模塊級(jí)別的函數(shù) logging.getLogger(name) 。多次使用相同的名字調(diào)用 getLogger() 會(huì)一直返回相同的 Logger 對(duì)象的引用。
name 是潛在的周期分割層級(jí)值, 像``foo.bar.baz`` (例如, 拋出的可以只是明文的``foo``)。Loggers是進(jìn)一步在子層次列表的更高loggers列表。例如,有個(gè)名叫``foo``的logger,名叫``foo.bar``,foo.bar.baz, 和 foo.bam 都是 foo``的衍生logger. logger的名字分級(jí)類似Python 包的層級(jí), 并且相同的如果你組織你的loggers在每模塊級(jí)別基本上使用推薦的結(jié)構(gòu)``logging.getLogger(__name__)。這是因?yàn)樵谀K里,在Python包的命名空間的模塊名為``__name__``。
-
class
logging.Logger? -
propagate? 如果這個(gè)屬性為真,記錄到這個(gè)記錄器的事件將會(huì)傳遞給這個(gè)高級(jí)別管理器的記錄器(原型),此外任何關(guān)聯(lián)到這個(gè)記錄器的管理器。消息會(huì)直接傳遞給原型記錄器的管理器 - 既不是這個(gè)原型記錄器的級(jí)別也不是過濾器是在考慮的問題。
如果等于假,記錄消息將不會(huì)傳遞給這個(gè)原型記錄器的管理器。
構(gòu)造器將這個(gè)屬性初始化為
True。注解
如果你關(guān)聯(lián)了一個(gè)管理器*并且*到它自己的一個(gè)或多個(gè)記錄器,它可能發(fā)出多次相同的記錄。總體來說,你不需要關(guān)聯(lián)管理器到一個(gè)或多個(gè)記錄器 - 如果你只是關(guān)聯(lián)它到一個(gè)合適的記錄器等級(jí)中的最高級(jí)別記錄器,它將會(huì)看到子記錄器所有記錄的事件,他們的傳播剩下的設(shè)置為``True``。一個(gè)通用場(chǎng)景是只關(guān)聯(lián)管理器到根記錄器,并且讓傳播照顧剩下的.
-
setLevel(level)? 給 logger 設(shè)置閾值為 level 。日志等級(jí)小于 level 會(huì)被忽略。嚴(yán)重性為 level 或更高的日志消息將由該 logger 的任何一個(gè)或多個(gè) handler 發(fā)出,除非將處理程序的級(jí)別設(shè)置為比 level 更高的級(jí)別。
創(chuàng)建一個(gè) logger 時(shí),設(shè)置級(jí)別為
NOTSET(當(dāng) logger 是根 logger 時(shí),將處理所有消息;當(dāng) logger 是非根 logger 時(shí),所有消息會(huì)委派給父級(jí))。注意根 logger 創(chuàng)建時(shí)使用的是WARNING級(jí)別。委派給父級(jí)的意思是如果一個(gè)記錄器的級(jí)別設(shè)置為NOTSET,遍歷其祖先記錄器鏈,直到找到另一個(gè)NOTSET級(jí)別的祖先或到達(dá)根為止。
如果發(fā)現(xiàn)某個(gè)父級(jí)的級(jí)別 不是NOTSET ,那么該父級(jí)的級(jí)別將被視為發(fā)起搜索的記錄器的有效級(jí)別,并用于確定如何處理日志事件。
如果到達(dá)根 logger ,并且其級(jí)別為NOTSET,則將處理所有消息。否則,將使用根記錄器的級(jí)別作為有效級(jí)別。
參見 日志級(jí)別 級(jí)別列表。
在 3.2 版更改: 現(xiàn)在 level 參數(shù)可以接受形如 'INFO' 的級(jí)別字符串表示形式,以代替形如
INFO的整數(shù)常量。 但是請(qǐng)注意,級(jí)別在內(nèi)部存儲(chǔ)為整數(shù),并且getEffectiveLevel()和isEnabledFor()等方法的傳入/返回值也為整數(shù)。
-
isEnabledFor(level)? 指示此記錄器是否將處理級(jí)別為 level 的消息。此方法首先檢查由
logging.disable(level)設(shè)置的模塊級(jí)的級(jí)別,然后檢查由getEffectiveLevel()確定的記錄器的有效級(jí)別。
-
getEffectiveLevel()? 指示此記錄器的有效級(jí)別。如果通過
setLevel()設(shè)置了除NOTSET以外的值,則返回該值。否則,將層次結(jié)構(gòu)遍歷到根,直到找到除NOTSET以外的其他值,然后返回該值。返回的值是一個(gè)整數(shù),通常為logging.DEBUG、logging.INFO等等。
-
getChild(suffix)? 返回由后綴確定的,是該記錄器的后代的記錄器。 因此,
logging.getLogger('abc').getChild('def.ghi')與logging.getLogger('abc.def.ghi')將返回相同的記錄器。 這是一個(gè)便捷方法,當(dāng)使用如__name__而不是字符串字面值命名父記錄器時(shí)很有用。3.2 新版功能.
-
debug(msg, *args, **kwargs)? Logs a message with level
DEBUGon this logger. The msg is the message format string, and the args are the arguments which are merged into msg using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.)There are three keyword arguments in kwargs which are inspected: exc_info, stack_info, and extra.
如果 exc_info 的求值結(jié)果不為 false,則它將異常信息添加到日志消息中。如果提供了一個(gè)異常元組(按照
sys.exc_info()返回的格式)或一個(gè)異常實(shí)例,則將其使用;否則,調(diào)用sys.exc_info()以獲取異常信息。第二個(gè)可選關(guān)鍵字參數(shù)是 stack_info,默認(rèn)為
False。如果為True,則將堆棧信息添加到日志消息中,包括實(shí)際的日志調(diào)用。請(qǐng)注意,這與通過指定 exc_info 顯示的堆棧信息不同:前者是從堆棧底部到當(dāng)前線程中的日志記錄調(diào)用的堆棧幀,而后者是在搜索異常處理程序時(shí),跟蹤異常而打開的堆棧幀的信息。您可以獨(dú)立于 exc_info 來指定 stack_info,例如,即使在未引發(fā)任何異常的情況下,也可以顯示如何到達(dá)代碼中的特定點(diǎn)。堆棧幀在標(biāo)題行之后打印:
Stack (most recent call last):
這模仿了顯示異常幀時(shí)所使用的
Traceback (most recent call last):。The third keyword argument is extra which can be used to pass a dictionary which is used to populate the __dict__ of the LogRecord created for the logging event with user-defined attributes. These custom attributes can then be used as you like. For example, they could be incorporated into logged messages. For example:
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
The keys in the dictionary passed in extra should not clash with the keys used by the logging system. (See the
Formatterdocumentation for more information on which keys are used by the logging system.)如果你選擇在已記錄的消息中使用這些屬性,則需要格外小心。 例如在上面的示例中,
Formatter已設(shè)置了格式字符串,其在 LogRecord 的屬性字典中應(yīng)有 'clientip' 和 'user'。 如果缺少這些屬性,消息將不被記錄,因?yàn)闀?huì)引發(fā)字符串格式化異常,你始終需要傳入帶有這些鍵的 extra 字典。盡管這可能很煩人,但此功能旨在用于特殊情況,例如在多個(gè)上下文中執(zhí)行相同代碼的多線程服務(wù)器,并且出現(xiàn)的有趣條件取決于此上下文(例如在上面的示例中就是遠(yuǎn)程客戶端IP地址和已驗(yàn)證用戶名)。在這種情況下,很可能將專門的
Formatter與特定的Handler一起使用。3.2 新版功能: 增加了 stack_info 參數(shù)。
在 3.5 版更改: The exc_info parameter can now accept exception instances.
-
warning(msg, *args, **kwargs)? 在此記錄器上記錄
WARNING級(jí)別的消息。參數(shù)解釋同debug()。注解
有一個(gè)功能上與
warning一致的方法warn。由于warn已被棄用,請(qǐng)不要使用它 —— 改為使用warning。
-
exception(msg, *args, **kwargs)? 在此記錄器上記錄
ERROR級(jí)別的消息。參數(shù)解釋同debug()。異常信息將添加到日志消息中。僅應(yīng)從異常處理程序中調(diào)用此方法。
-
addFilter(filter)? 將指定的過濾器 filter 添加到此記錄器。
-
removeFilter(filter)? 從此記錄器中刪除指定的處理程序 filter。
-
filter(record)? 將此記錄器的過濾器應(yīng)用于記錄,如果記錄能被處理則返回
True。過濾器會(huì)被依次使用,直到其中一個(gè)返回假值為止。如果它們都不返回假值,則記錄將被處理(傳遞給處理器)。如果返回任一為假值,則不會(huì)對(duì)該記錄做進(jìn)一步處理。
-
addHandler(hdlr)? 將指定的處理程序 hdlr 添加到此記錄器。
-
removeHandler(hdlr)? 從此記錄器中刪除指定的處理器 hdlr。
-
findCaller(stack_info=False)? 查找調(diào)用源的文件名和行號(hào),以 文件名,行號(hào),函數(shù)名稱和堆棧信息 4元素元組的形式返回。堆棧信息將返回
None``除非 *stack_info* 為 ``True。
-
handle(record)? 通過將記錄傳遞給與此記錄器及其祖先關(guān)聯(lián)的所有處理器來處理(直到某個(gè) propagate 值為 false)。此方法用于從套接字接收的未序列化的以及在本地創(chuàng)建的記錄。使用
filter()進(jìn)行記錄程序級(jí)別過濾。
-
makeRecord(name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None)? 這是一種工廠方法,可以在子類中對(duì)其進(jìn)行重寫以創(chuàng)建專門的
LogRecord實(shí)例。
-
hasHandlers()? 檢查此記錄器是否配置了任何處理器。通過在此記錄器及其記錄器層次結(jié)構(gòu)中的父級(jí)中查找處理器完成此操作。如果找到處理器則返回
True,否則返回``False``。只要找到 “propagate” 屬性設(shè)置為 false的記錄器,該方法就會(huì)停止搜索層次結(jié)構(gòu) —— 其將是最后一個(gè)檢查處理器是否存在的記錄器。3.2 新版功能.
在 3.7 版更改: 現(xiàn)在可以對(duì)處理器進(jìn)行序列化和反序列化。
-
日志級(jí)別?
日志記錄級(jí)別的數(shù)值在下表中給出。如果你想要定義自己的級(jí)別,并且需要它們具有相對(duì)于預(yù)定義級(jí)別的特定值,那么這些內(nèi)容可能是你感興趣的。如果你定義具有相同數(shù)值的級(jí)別,它將覆蓋預(yù)定義的值; 預(yù)定義的名稱丟失。
級(jí)別 |
數(shù)值 |
|---|---|
|
50 |
|
40 |
|
30 |
|
20 |
|
10 |
|
0 |
處理器對(duì)象?
Handler 有以下屬性和方法。注意不要直接實(shí)例化 Handler ;這個(gè)類用來派生其他更有用的子類。但是,子類的 __init__() 方法需要調(diào)用 Handler.__init__() 。
-
class
logging.Handler? -
__init__(level=NOTSET)? 初始化
Handler實(shí)例時(shí),需要設(shè)置它的級(jí)別,將過濾列表置為空,并且創(chuàng)建鎖(通過createLock())來序列化對(duì) I/O 的訪問。
-
createLock()? 初始化一個(gè)線程鎖,用來序列化對(duì)底層的 I/O 功能的訪問,底層的 I/O 功能可能不是線程安全的。
-
acquire()? 使用
createLock()獲取線程鎖。
-
setLevel(level)? 給處理器設(shè)置閾值為 level 。日志級(jí)別小于 level 將被忽略。創(chuàng)建處理器時(shí),日志級(jí)別被設(shè)置為
NOTSET(所有的消息都會(huì)被處理)。參見 日志級(jí)別 級(jí)別列表。
在 3.2 版更改: level 形參現(xiàn)在接受像 'INFO' 這樣的字符串形式的級(jí)別表達(dá)方式,也可以使用像
INFO這樣的整數(shù)常量。
-
addFilter(filter)? 將指定的過濾器 filter 添加到此處理器。
-
removeFilter(filter)? 從此處理器中刪除指定的過濾器 filter 。
-
filter(record)? 將此處理器的過濾器應(yīng)用于記錄,在要處理記錄時(shí)返回
True。依次查詢過濾器,直到其中一個(gè)返回假值為止。如果它們都不返回假值,則將發(fā)出記錄。如果返回一個(gè)假值,則處理器將不會(huì)發(fā)出記錄。
-
flush()? 確保所有日志記錄從緩存輸出。此版本不執(zhí)行任何操作,并且應(yīng)由子類實(shí)現(xiàn)。
-
close()? 整理處理器使用的所有資源。此版本不輸出,但從內(nèi)部處理器列表中刪除處理器,內(nèi)部處理器在
shutdown()被調(diào)用時(shí)關(guān)閉 。子類應(yīng)確保從重寫的close()方法中調(diào)用此方法。
-
handle(record)? 經(jīng)已添加到處理器的過濾器過濾后,有條件地發(fā)出指定的日志記錄。用獲取/釋放 I/O 線程鎖包裝記錄的實(shí)際發(fā)出行為。
-
handleError(record)? 調(diào)用
emit()期間遇到異常時(shí),應(yīng)從處理器中調(diào)用此方法。如果模塊級(jí)屬性raiseExceptions是False,則異常將被靜默忽略。這是大多數(shù)情況下日志系統(tǒng)需要的 —— 大多數(shù)用戶不會(huì)關(guān)心日志系統(tǒng)中的錯(cuò)誤,他們對(duì)應(yīng)用程序錯(cuò)誤更感興趣。但是,你可以根據(jù)需要將其替換為自定義處理器。指定的記錄是發(fā)生異常時(shí)正在處理的記錄。(raiseExceptions的默認(rèn)值是True,因?yàn)檫@在開發(fā)過程中是比較有用的)。
-
format(record)? 如果設(shè)置了格式器則用其對(duì)記錄進(jìn)行格式化。否則,使用模塊的默認(rèn)格式器。
-
emit(record)? 執(zhí)行實(shí)際記錄給定日志記錄所需的操作。這個(gè)版本應(yīng)由子類實(shí)現(xiàn),因此這里直接引發(fā)
NotImplementedError異常。
-
有關(guān)作為標(biāo)準(zhǔn)隨附的處理程序,請(qǐng)參見 logging.handlers。
格式器對(duì)象?
Formatter 對(duì)象擁有以下的屬性和方法。一般情況下,它們負(fù)責(zé)將 LogRecord 轉(zhuǎn)換為可由人或外部系統(tǒng)解釋的字符串。基礎(chǔ)的 Formatter 允許指定格式字符串。如果未提供任何值,則使用默認(rèn)值 '%(message)s' ,它僅將消息包括在日志記錄調(diào)用中。要在格式化輸出中包含其他信息(如時(shí)間戳),請(qǐng)閱讀下文。
格式器可以使用格式化字符串來初始化,該字符串利用 LogRecord 的屬性 —— 例如上述默認(rèn)值,用戶的消息和參數(shù)預(yù)先格式化為 LogRecord 的 message 屬性后被使用。此格式字符串包含標(biāo)準(zhǔn)的 Python %-s 樣式映射鍵。有關(guān)字符串格式的更多信息,請(qǐng)參見 printf 風(fēng)格的字符串格式化。
The useful mapping keys in a LogRecord are given in the section on
LogRecord 屬性.
-
class
logging.Formatter(fmt=None, datefmt=None, style='%')? 返回
Formatter類的新實(shí)例。實(shí)例將使用整個(gè)消息的格式字符串以及消息的日期/時(shí)間部分的格式字符串進(jìn)行初始化。如果未指定 fmt ,則使用'%(message)s'。如果未指定 datefmt,則使用formatTime()文檔中描述的格式。style 形參可以是 '%', '{' 或 '$' 之一,它決定格式字符串如何與數(shù)據(jù)進(jìn)行合并:使用 %-formatting,
str.format()或string.Template之一。 請(qǐng)參閱 生效于整個(gè)應(yīng)用程序的格式化樣式 了解有關(guān)在日志消息中使用 {- 和 $-formatting 的更多信息。在 3.2 版更改: style 參數(shù)已加入.
-
format(record)? 記錄的屬性字典用作字符串格式化操作的參數(shù)。返回結(jié)果字符串。在格式化字典之前,需要執(zhí)行幾個(gè)準(zhǔn)備步驟。 使用 msg % args 計(jì)算記錄的 message 屬性。如果格式化字符串包含
'(asctime)',則調(diào)用formatTime()來格式化事件時(shí)間。如果有異常信息,則使用formatException()將其格式化并附加到消息中。請(qǐng)注意,格式化的異常信息緩存在屬性 exc_text 中。這很有用,因?yàn)榭梢詫?duì)異常信息進(jìn)行序列化并通過網(wǎng)絡(luò)發(fā)送,但是如果您有不止一個(gè)定制了異常信息格式的Formatter子類,則應(yīng)格外小心。在這種情況下,您必須在格式器完成格式化后清除緩存的值,以便下一個(gè)處理事件的格式化程序不使用緩存的值,而是重新計(jì)算它。如果棧信息可用,它將被添加在異常信息之后,如有必要請(qǐng)使用
formatStack()來轉(zhuǎn)換它。
-
formatTime(record, datefmt=None)? 此方法應(yīng)由想要使用格式化時(shí)間的格式器中的
format()調(diào)用。可以在格式器中重寫此方法以提供任何特定要求,但是基本行為如下:如果指定了 datefmt (字符串),則將其用于time.strftime()來格式化記錄的創(chuàng)建時(shí)間。否則,使用格式 '%Y-%m-%d %H:%M:%S,uuu',其中 uuu 部分是毫秒值,其他字母根據(jù)time.strftime()文檔。這種時(shí)間格式的示例為2003-01-23 00:29:50,411。返回結(jié)果字符串。此函數(shù)使用一個(gè)用戶可配置函數(shù)將創(chuàng)建時(shí)間轉(zhuǎn)換為元組。 默認(rèn)情況下,使用
time.localtime();要為特定格式化程序?qū)嵗拇隧?xiàng),請(qǐng)將實(shí)例的converter屬性設(shè)為具有與time.localtime()或time.gmtime()相同簽名的函數(shù)。 要為所有格式化程序更改此項(xiàng),例如當(dāng)你希望所有日志時(shí)間都顯示為 GMT,請(qǐng)?jiān)?Formatter類中設(shè)置converter屬性。在 3.3 版更改: 在之前版本中,默認(rèn)格式為寫死的代碼,例如這個(gè)例子:
2010-09-06 22:38:15,292其中逗號(hào)之前的部分由 strptime 格式字符串 ('%Y-%m-%d %H:%M:%S') 處理,而逗號(hào)之后的部分為毫秒值。 因?yàn)?strptime 沒有表示毫秒的占位符,毫秒值使用了另外的格式字符串來添加'%s,%03d'--- 這兩個(gè)格式字符串代碼都是寫死在該方法中的。 經(jīng)過修改,這些字符串被定義為類層級(jí)的屬性,當(dāng)需要時(shí)可以在實(shí)例層級(jí)上被重載。 屬性的名稱為default_time_format(用于 strptime 格式字符串) 和default_msec_format(用于添加毫秒值)。
-
formatException(exc_info)? 將指定的異常信息(由
sys.exc_info()返回的標(biāo)準(zhǔn)異常元組)格式化為字符串。 這個(gè)默認(rèn)實(shí)現(xiàn)只使用了traceback.print_exception()。 結(jié)果字符串將被返回。
-
formatStack(stack_info)? 將指定的堆棧信息(由
traceback.print_stack()返回的字符串,但移除末尾的換行符)格式化為字符串。 這個(gè)默認(rèn)實(shí)現(xiàn)只是返回輸入值。
-
Filter 對(duì)象?
Filters 可被 Handlers 和 Loggers 用來實(shí)現(xiàn)比按層級(jí)提供更復(fù)雜的過濾操作。 基本過濾器類只允許低于日志記錄器層級(jí)結(jié)構(gòu)中低于特定層級(jí)的事件。 例如,一個(gè)用 'A.B' 初始化的過濾器將允許 'A.B', 'A.B.C', 'A.B.C.D', 'A.B.D' 等日志記錄器所記錄的事件。 但 'A.BB', 'B.A.B' 等則不允許。 如果用空字符串初始化,則所有事件都會(huì)被略過。
-
class
logging.Filter(name='')? 返回一個(gè)
Filter類的實(shí)例。 如果指定了 name,則它將被用來為日志記錄器命名,該類及其子類將通過該過濾器允許指定事件通過。 如果 name 為空字符串,則允許所有事件通過。-
filter(record)? 是否要記錄指定的記錄?返回零表示否,非零表示是。如果認(rèn)為合適,則可以通過此方法就地修改記錄。
-
請(qǐng)注意關(guān)聯(lián)到處理程序的過濾器會(huì)在事件由處理程序發(fā)出之前被查詢,而關(guān)聯(lián)到日志記錄器的過濾器則會(huì)在有事件被記錄的的任何時(shí)候(使用 debug(), info() 等等)在將事件發(fā)送給處理程序之前被查詢。 這意味著由后代日志記錄器生成的事件將不會(huì)被日志記錄器的過濾器設(shè)置所過濾,除非該過濾器也已被應(yīng)用于后代日志記錄器。
你實(shí)際上不需要子類化 Filter: 你可以將傳入任何包含 filter 方法的具有相同語(yǔ)義的的實(shí)例。
在 3.2 版更改: 你不需要?jiǎng)?chuàng)建專門的 Filter 類,或使用具有 filter 方法的其他類:你可以使用一個(gè)函數(shù)(或其他可調(diào)用對(duì)象)作為過濾器。 過濾邏輯將檢查過濾器對(duì)象是否文化的 filter 屬性:如果有,就會(huì)將它當(dāng)作是 Filter 并調(diào)用它的 filter() 方法。 在其他情況下,則會(huì)將它當(dāng)作是可調(diào)用對(duì)象并附帶記錄作為單一形參進(jìn)行調(diào)用。 返回值應(yīng)當(dāng)與 filter() 的返回值相一致。
Although filters are used primarily to filter records based on more sophisticated criteria than levels, they get to see every record which is processed by the handler or logger they're attached to: this can be useful if you want to do things like counting how many records were processed by a particular logger or handler, or adding, changing or removing attributes in the LogRecord being processed. Obviously changing the LogRecord needs to be done with some care, but it does allow the injection of contextual information into logs (see 使用過濾器傳遞上下文信息).
LogRecord 屬性?
LogRecord 實(shí)例是每當(dāng)有日志被記錄時(shí)由 Logger 自動(dòng)創(chuàng)建的,并且可通過 makeLogRecord() 手動(dòng)創(chuàng)建(例如根據(jù)從網(wǎng)絡(luò)接收的已封存事件創(chuàng)建)。
-
class
logging.LogRecord(name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None)? 包含與被記錄的事件相關(guān)的所有信息。
主要信息是在
msg和args中傳遞的,它們使用msg % args組合到一起以創(chuàng)建記錄的message字段。- 參數(shù)
name -- 用于記錄由此 LogRecord 所表示 的事件的日志記錄器名稱。 請(qǐng)注意此名稱將始終為該值,即使它可以是由附加到不同(祖先)日志記錄器的處理程序所發(fā)出的。
level -- 以數(shù)字表示的日志記錄事件層級(jí)(如 DEBUG, INFO 等)。 請(qǐng)注意這會(huì)轉(zhuǎn)換為 LogRecord 的 兩個(gè) 屬性:
levelno為數(shù)字值而levelname為對(duì)應(yīng)的層級(jí)名稱。pathname -- 進(jìn)行日志記錄調(diào)用的文件的完整路徑名。
lineno -- 記錄調(diào)用所在源文件中的行號(hào)。
msg -- 事件描述消息,可能為帶有可變數(shù)據(jù)占位符的格式字符串。
args -- 要合并到 msg 參數(shù)以獲得事件描述的可變數(shù)據(jù)。
exc_info -- 包含當(dāng)前異常信息的異常元組,或者如果沒有可用異常信息則為
None。func -- 發(fā)起調(diào)用日志記錄調(diào)用的函數(shù)或方法名稱。
sinfo -- 一個(gè)文本字符串,表示當(dāng)前線程中從堆棧底部直到日志記錄調(diào)用的堆棧信息。
-
getMessage()? 在將
LogRecord實(shí)例與任何用戶提供的參數(shù)合并之后,返回此實(shí)例的消息。 如果用戶提供給日志記錄調(diào)用的消息參數(shù)不是字符串,則會(huì)在其上調(diào)用str()以將它轉(zhuǎn)換為字符串。 此方法允許將用戶定義的類用作消息,類的__str__方法可以返回要使用的實(shí)際格式字符串。
在 3.2 版更改: The creation of a
LogRecordhas been made more configurable by providing a factory which is used to create the record. The factory can be set usinggetLogRecordFactory()andsetLogRecordFactory()(see this for the factory's signature).This functionality can be used to inject your own values into a LogRecord at creation time. You can use the following pattern:
old_factory = logging.getLogRecordFactory() def record_factory(*args, **kwargs): record = old_factory(*args, **kwargs) record.custom_attribute = 0xdecafbad return record logging.setLogRecordFactory(record_factory)
通過此模式,多個(gè)工廠方法可以被鏈接起來,并且只要它們不重載彼此的屬性或是在無意中覆蓋了上面列出的標(biāo)準(zhǔn)屬性,就不會(huì)發(fā)生意外。
LogRecord 屬性?
LogRecord 具有許多屬性,它們大多數(shù)來自于傳遞給構(gòu)造器的形參。 (請(qǐng)注意 LogRecord 構(gòu)造器形參與 LogRecord 屬性的名稱并不總是完全彼此對(duì)應(yīng)的。) 這些屬性可被用于將來自記錄的數(shù)據(jù)合并到格式字符串中。 下面的表格(按字母順序)列出了屬性名稱、它們的含義以及相應(yīng)的 %-style 格式字符串內(nèi)占位符。
如果是使用 {}-格式化 (str.format()),你可以將 {attrname} 用作格式字符串內(nèi)的占位符。 如果是使用 $-格式化 (string.Template),則會(huì)使用 ${attrname} 的形式。 當(dāng)然在這兩種情況下,都應(yīng)當(dāng)將 attrname 替換為你想要使用的實(shí)際屬性名稱。
在 {}-格式化的情況下,你可以在屬性名稱之后放置指定的格式化旗標(biāo),并用冒號(hào)來分隔兩者。 例如,占位符 {msecs:03d} 會(huì)將毫秒值 4 格式化為 004。 請(qǐng)參看 str.format() 文檔了解你所能使用的選項(xiàng)的完整細(xì)節(jié)。
屬性名稱 |
格式 |
描述 |
|---|---|---|
args |
不需要格式化。 |
合并到 |
asctime |
|
表示 |
created |
|
|
exc_info |
不需要格式化。 |
異常元組 (例如 |
filename |
|
|
funcName |
|
函數(shù)名包括調(diào)用日志記錄. |
levelname |
|
消息文本記錄級(jí)別 ( |
levelno |
|
消息數(shù)字記錄級(jí)別 ( |
lineno |
|
發(fā)出日志記錄調(diào)用所在的源行號(hào)(如果可用)。 |
message |
|
記入日志的消息,即 |
module 模塊 |
|
模塊 ( |
msecs |
|
|
msg |
不需要格式化。 |
在原始日志記錄調(diào)用中傳入的格式字符串。 與 |
名稱 |
|
用于記錄調(diào)用的日志記錄器名稱。 |
pathname |
|
發(fā)出日志記錄調(diào)用的源文件的完整路徑名(如果可用)。 |
process |
|
進(jìn)程ID(如果可用) |
processName |
|
進(jìn)程名(如果可用) |
relativeCreated |
|
以毫秒數(shù)表示的 LogRecord 被創(chuàng)建的時(shí)間,即相對(duì)于 logging 模塊被加載時(shí)間的差值。 |
stack_info |
不需要格式化。 |
當(dāng)前線程中從堆棧底部起向上直到包括日志記錄調(diào)用并導(dǎo)致創(chuàng)建此記錄的堆棧幀的堆棧幀信息(如果可用)。 |
thread |
|
線程ID(如果可用) |
threadName |
|
線程名(如果可用) |
在 3.1 版更改: 添加了 processName
LoggerAdapter 對(duì)象?
LoggerAdapter 實(shí)例會(huì)被用來方便地將上下文信息傳入日志記錄調(diào)用。 要獲取用法示例,請(qǐng)參閱 添加上下文信息到你的日志記錄輸出 部分。
-
class
logging.LoggerAdapter(logger, extra)? 返回一個(gè)
LoggerAdapter的實(shí)例,該實(shí)例的初始化帶有一個(gè)下層的Logger實(shí)例和一個(gè)字典類對(duì)象。-
process(msg, kwargs)? 修改傳遞給日志記錄調(diào)用的消息和/或關(guān)鍵字參數(shù)以便插入上下文信息。 此實(shí)現(xiàn)接受以 extra 形式傳給構(gòu)造器的對(duì)象并使用 'extra' 鍵名將其加入 kwargs。 返回值為一個(gè) (msg, kwargs) 元組,其中傳入了(可能經(jīng)過修改的)參數(shù)版本。
-
在上述方法之外,LoggerAdapter 還支持 Logger 的下列方法: debug(), info(), warning(), error(), exception(), critical(), log(), isEnabledFor(), getEffectiveLevel(), setLevel() 以及 hasHandlers()。 這些方法具有與它們?cè)?Logger 中的對(duì)應(yīng)方法相同的簽名,因此你可以互換使用這兩種類型的實(shí)例。
在 3.2 版更改: isEnabledFor(), getEffectiveLevel(), setLevel() 和 hasHandlers() 方法已被添加到 LoggerAdapter。 這些方法會(huì)委托給下層的日志記錄器。
線程安全?
logging 模塊的目標(biāo)是使客戶端不必執(zhí)行任何特殊操作即可確保線程安全。 它通過使用線程鎖來達(dá)成這個(gè)目標(biāo);用一個(gè)鎖來序列化對(duì)模塊共享數(shù)據(jù)的訪問,并且每個(gè)處理程序也會(huì)創(chuàng)建一個(gè)鎖來序列化對(duì)其下層 I/O 的訪問。
如果你要使用 signal 模塊來實(shí)現(xiàn)異步信號(hào)處理程序,則可能無法在這些處理程序中使用 logging。 這是因?yàn)?threading 模塊中的鎖實(shí)現(xiàn)并非總是可重入的,所以無法從此類信號(hào)處理程序發(fā)起調(diào)用。
模塊級(jí)別函數(shù)?
在上述的類之外,還有一些模塊層級(jí)的函數(shù)。
-
logging.getLogger(name=None)? 返回具有指定 name 的日志記錄器,或者當(dāng) name 為
None時(shí)返回層級(jí)結(jié)構(gòu)中作為根日志記錄器的日志記錄器。 如果指定了 name,它通常是以點(diǎn)號(hào)分隔的帶層級(jí)結(jié)構(gòu)的名稱如 'a', 'a.b' 或 'a.b.c.d'。 這些名稱的選擇完全取決于使用 logging 的開發(fā)者。附帶給定 name 的所有對(duì)此函數(shù)的調(diào)用都將返回相同的日志記錄器實(shí)例。 這意味著日志記錄器實(shí)例不需要在應(yīng)用的不同部分間傳遞。
-
logging.getLoggerClass()? 返回標(biāo)準(zhǔn)的
Logger類,或是最近傳給setLoggerClass()的類。 此函數(shù)可以從一個(gè)新的類定義中調(diào)用,以確保安裝自定義的Logger類不會(huì)撤銷其他代碼已經(jīng)應(yīng)用的自定義操作。 例如:class MyLogger(logging.getLoggerClass()): # ... override behaviour here
-
logging.getLogRecordFactory()? 返回一個(gè)被用來創(chuàng)建
LogRecord的可調(diào)用對(duì)象。3.2 新版功能: 此函數(shù)與
setLogRecordFactory()一起提供,以便允許開發(fā)者對(duì)如何構(gòu)造表示日志記錄事件的LogRecord有更好的控制。請(qǐng)參閱
setLogRecordFactory()了解有關(guān)如何調(diào)用該工廠方法的更多信息。
-
logging.debug(msg, *args, **kwargs)? 在根日志記錄器上記錄一條
DEBUG級(jí)別的消息。 msg 是消息格式字符串,而 args 是要使用字符串格式化運(yùn)算符合并到 msg 的參數(shù)。 (請(qǐng)注意這意味著你可以在格式字符串中使用關(guān)鍵字以及單個(gè)字典參數(shù)。)在 kwargs 中有三個(gè)關(guān)鍵字參數(shù)會(huì)被檢查: exc_info 參數(shù)如果不為假值則會(huì)將異常信息添加到日志記錄消息。 如果提供了異常元組(為
sys.exc_info()的返回值格式)或異常實(shí)例則它會(huì)被使用;在其他情況下,會(huì)調(diào)用sys.exc_info()以獲取異常信息。第二個(gè)可選關(guān)鍵字參數(shù)是 stack_info,默認(rèn)為
False。如果為True,則將堆棧信息添加到日志消息中,包括實(shí)際的日志調(diào)用。請(qǐng)注意,這與通過指定 exc_info 顯示的堆棧信息不同:前者是從堆棧底部到當(dāng)前線程中的日志記錄調(diào)用的堆棧幀,而后者是在搜索異常處理程序時(shí),跟蹤異常而打開的堆棧幀的信息。您可以獨(dú)立于 exc_info 來指定 stack_info,例如,即使在未引發(fā)任何異常的情況下,也可以顯示如何到達(dá)代碼中的特定點(diǎn)。堆棧幀在標(biāo)題行之后打印:
Stack (most recent call last):
這模仿了顯示異常幀時(shí)所使用的
Traceback (most recent call last):。第三個(gè)可選關(guān)鍵字參數(shù)是 extra,它可被用來傳遞一個(gè)字典,該字典會(huì)被用來填充為日志記錄事件創(chuàng)建并附帶用戶自定義屬性的 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)
應(yīng)當(dāng)會(huì)打印出這樣的內(nèi)容:
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
The keys in the dictionary passed in extra should not clash with the keys used by the logging system. (See the
Formatterdocumentation for more information on which keys are used by the logging system.)如果你選擇在已記錄的消息中使用這些屬性,則需要格外小心。 例如在上面的示例中,
Formatter已設(shè)置了格式字符串,其在 LogRecord 的屬性字典中應(yīng)有 'clientip' 和 'user'。 如果缺少這些屬性,消息將不被記錄,因?yàn)闀?huì)引發(fā)字符串格式化異常,你始終需要傳入帶有這些鍵的 extra 字典。盡管這可能很煩人,但此功能旨在用于特殊情況,例如在多個(gè)上下文中執(zhí)行相同代碼的多線程服務(wù)器,并且出現(xiàn)的有趣條件取決于此上下文(例如在上面的示例中就是遠(yuǎn)程客戶端IP地址和已驗(yàn)證用戶名)。在這種情況下,很可能將專門的
Formatter與特定的Handler一起使用。3.2 新版功能: 增加了 stack_info 參數(shù)。
-
logging.warning(msg, *args, **kwargs)? 在根日志記錄器上記錄一條
WARNING級(jí)別的消息。 參數(shù)解釋同debug()。注解
有一個(gè)已過時(shí)方法
warn其功能與warning一致。 由于warn已被棄用,請(qǐng)不要使用它 —— 而要改用warning。
-
logging.exception(msg, *args, **kwargs)? 在根日志記錄器上記錄一條
ERROR級(jí)別的消息。 參數(shù)解釋同debug()。 異常信息將被添加到日志消息中。 此函數(shù)應(yīng)當(dāng)僅從異常處理程序中調(diào)用。
-
logging.log(level, msg, *args, **kwargs)? 在根日志記錄器上記錄一條 level 級(jí)別的消息。 其他參數(shù)解釋同
debug()。注解
上述模塊層級(jí)的便捷函數(shù)均委托給根日志記錄器,它們會(huì)調(diào)用
basicConfig()以確保至少有一個(gè)處理程序可用。 因此,它們 不應(yīng) 在線程中使用,在 Python 2.7.1 和 3.2 之前的版本中,除非線程啟動(dòng) 之前 已向根日志記錄器添加了至少一個(gè)處理程序方可使用。 在較早的 Python 版本中,由于basicConfig()中存在線程安全性的不足,這(在少數(shù)情況下)可能導(dǎo)致處理程序被多次加入根日志記錄器,這會(huì)進(jìn)一步導(dǎo)致同一事件出現(xiàn)多條消息。
-
logging.disable(level=CRITICAL)? 為所有日志記錄器提供重載的級(jí)別 level,其優(yōu)先級(jí)高于日志記錄器自己的級(jí)別。 當(dāng)需要臨時(shí)限制整個(gè)應(yīng)用程序中的日志記錄輸出時(shí),此功能會(huì)很有用。 它的效果是禁用所有重要程度為 level 及以下的日志記錄調(diào)用,因此如果你附帶 INFO 值調(diào)用它,則所有 INFO 和 DEBUG 事件就會(huì)被丟棄,而重要程度為 WARNING 以及上的事件將根據(jù)日志記錄器的當(dāng)前有效級(jí)別來處理。 如果
logging.disable(logging.NOTSET)被調(diào)用,它將在實(shí)際上移除這個(gè)重載的級(jí)別,因此日志記錄輸出會(huì)再次取決于單個(gè)日志記錄器的有效級(jí)別。請(qǐng)注意如果你定義了任何高于
CRITICAL的自定義日志級(jí)別(并不建議這樣做),你就將無法沿用 level 形參的默認(rèn)值,而必須顯式地提供適當(dāng)?shù)闹怠?/p>在 3.7 版更改: level 形參默認(rèn)為
CRITICAL級(jí)別。 請(qǐng)參閱問題 #28524 了解此項(xiàng)改變的更多細(xì)節(jié)。
-
logging.addLevelName(level, levelName)? 在一個(gè)內(nèi)部字典中關(guān)聯(lián)級(jí)別 level 與文本 levelName,該字典會(huì)被用來將數(shù)字級(jí)別映射為文本表示形式,例如在
Formatter格式化消息的時(shí)候。 此函數(shù)也可被用來定義你自己的級(jí)別。 唯一的限制是所用的所有級(jí)別必須使用此函數(shù)來注冊(cè),級(jí)別值必須為正整數(shù)并且它們應(yīng)當(dāng)按嚴(yán)重程度遞增順序逐一遞增。注解
如果你考慮要定義你自己的級(jí)別,請(qǐng)參閱 自定義級(jí)別 部分。
-
logging.getLevelName(level)? 返回日志記錄級(jí)別 level 的文本表示形式。 如果級(jí)別為預(yù)定義的級(jí)別
CRITICAL,ERROR,WARNING,INFO或DEBUG之一則你會(huì)得到相應(yīng)的字符串。 如果你使用addLevelName()將級(jí)別關(guān)聯(lián)到名稱則會(huì)返回你為 level 所關(guān)聯(lián)的名稱。 如果傳入了與已定義級(jí)別相對(duì)應(yīng)的數(shù)字值,則會(huì)返回相應(yīng)的字符串表示形式。 在其他情況下,則返回級(jí)別字符串 'Level %s' % level。注解
級(jí)別在內(nèi)部為整數(shù)(它們需要在日志記錄邏輯中相互比較)。 此函數(shù)被用于在整數(shù)級(jí)別與通過
%(levelname)s格式描述符方式格式化的日志輸出中顯示的級(jí)別名稱之間進(jìn)行轉(zhuǎn)換 (參見 LogRecord 屬性)。在 3.4 版更改: 在早于 3.4 的 Python 版本中,此函數(shù)也可傳入一個(gè)文本級(jí)別名稱,并將返回對(duì)應(yīng)的級(jí)別數(shù)字值。 此未記入文檔的行為被視為是一個(gè)錯(cuò)誤,并在 Python 3.4 中被移除,但又在 3.4.2 中被恢復(fù)以保持向下兼容性。
-
logging.makeLogRecord(attrdict)? 創(chuàng)建并返回一個(gè)新的
LogRecord實(shí)例,實(shí)例屬性由 attrdict 定義。 此函數(shù)適用于接受一個(gè)封存的LogRecord屬性字典,通過套接字傳輸,并在接收端將其重建為一個(gè)LogRecord實(shí)例。
-
logging.basicConfig(**kwargs)? 通過使用默認(rèn)的
Formatter創(chuàng)建一個(gè)StreamHandler并將其加入根日志記錄器來為日志記錄系統(tǒng)執(zhí)行基本配置。 如果沒有為根日志記錄器定義處理程序則debug(),info(),warning(),error()和critical()等函數(shù)將自動(dòng)調(diào)用basicConfig()。This function does nothing if the root logger already has handlers configured for it.
注解
此函數(shù)應(yīng)當(dāng)在其他線程啟動(dòng)之前從主線程被調(diào)用。 在 2.7.1 和 3.2 之前的 Python 版本中,如果此函數(shù)從多個(gè)線程被調(diào)用,一個(gè)處理程序(在極少的情況下)有可能被多次加入根日志記錄器,導(dǎo)致非預(yù)期的結(jié)果例如日志中的消息出現(xiàn)重復(fù)。
支持以下關(guān)鍵字參數(shù)。
格式
描述
filename
使用指定的文件名而不是 StreamHandler 創(chuàng)建 FileHandler。
filemode
如果指定了 filename,則用此 模式 打開該文件。 默認(rèn)模式為
'a'。format
處理器使用的指定格式字符串。
datefmt
使用指定的日期/時(shí)間格式,與
time.strftime()所接受的格式相同。style
如果指定了 format,將為格式字符串使用此風(fēng)格。
'%','{'或'$'分別對(duì)應(yīng)于 printf 風(fēng)格,str.format()或string.Template。 默認(rèn)為'%'。level
設(shè)置根記錄器級(jí)別去指定 level.
stream
使用指定的流初始化 StreamHandler。 請(qǐng)注意此參數(shù)與 filename 是不兼容的 - 如果兩者同時(shí)存在,則會(huì)引發(fā)
ValueError。handlers
如果指定,這應(yīng)為一個(gè)包含要加入根日志記錄器的已創(chuàng)建處理程序的可迭代對(duì)象。 任何尚未設(shè)置格式描述符的處理程序?qū)⒈辉O(shè)置為在此函數(shù)中創(chuàng)建的默認(rèn)格式描述符。 請(qǐng)注意此參數(shù)與 filename 或 stream 不兼容 —— 如果兩者同時(shí)存在,則會(huì)引發(fā)
ValueError。在 3.2 版更改: 增加了 style 參數(shù)。
在 3.3 版更改: 增加了 handlers 參數(shù)。 增加了額外的檢查來捕獲指定不兼容參數(shù)的情況 (例如同時(shí)指定 handlers 與 stream 或 filename,或者同時(shí)指定 stream 與 filename)。
-
logging.shutdown()? 通過刷新和關(guān)閉所有處理程序來通知日志記錄系統(tǒng)執(zhí)行有序停止。 此函數(shù)應(yīng)當(dāng)在應(yīng)用退出時(shí)被調(diào)用并且在此調(diào)用之后不應(yīng)再使用日志記錄系統(tǒng)。
-
logging.setLoggerClass(klass)? 通知日志記錄系統(tǒng)在實(shí)例化日志記錄器時(shí)使用 klass 類。 該類應(yīng)當(dāng)定義
__init__()使其只要求一個(gè) name 參數(shù),并且__init__()應(yīng)當(dāng)調(diào)用Logger.__init__()。 此函數(shù)通常會(huì)在需要使用自定義日志記錄器行為的應(yīng)用程序?qū)嵗魏稳罩居涗浧髦氨徽{(diào)用。 在此調(diào)用之后,在任何其他時(shí)刻都不要使用該子類來直接實(shí)例化日志記錄器:請(qǐng)繼續(xù)使用logging.getLogger()API 來獲取你的日志記錄器。
-
logging.setLogRecordFactory(factory)? 設(shè)置一個(gè)用來創(chuàng)建
LogRecord的可調(diào)用對(duì)象。- 參數(shù)
factory -- 用來實(shí)例化日志記錄的工廠可調(diào)用對(duì)象。
3.2 新版功能: 此函數(shù)與
getLogRecordFactory()一起提供,以便允許開發(fā)者對(duì)如何構(gòu)造表示日志記錄事件的LogRecord有更好的控制。可調(diào)用對(duì)象 factory 具有如下簽名:
factory(name, level, fn, lno, msg, args, exc_info, func=None, sinfo=None, **kwargs)- 名稱
日志記錄器名稱
- level
日志記錄級(jí)別(數(shù)字)。
- fn
進(jìn)行日志記錄調(diào)用的文件的完整路徑名。
- lno
記錄調(diào)用所在文件中的行號(hào)。
- msg
日志消息。
- args
日志記錄消息的參數(shù)。
- exc_info
異常元組,或
None。- func
調(diào)用日志記錄調(diào)用的函數(shù)或方法的名稱。
- sinfo
與
traceback.print_stack()所提供的類似的棧回溯信息,顯示調(diào)用的層級(jí)結(jié)構(gòu)。- kwargs
其他關(guān)鍵字參數(shù)。
模塊級(jí)屬性?
-
logging.lastResort? 通過此屬性提供的“最后處理者”。 這是一個(gè)以
WARNING級(jí)別寫入到sys.stderr的StreamHandler,用于在沒有任何日志記錄配置的情況下處理日志記錄事件。 最終結(jié)果就是將消息打印到sys.stderr,這會(huì)替代先前形式為 "no handlers could be found for logger XYZ" 的錯(cuò)誤消息。 如果出于某種原因你需要先前的行為,可將lastResort設(shè)為None。3.2 新版功能.
與警告模塊集成?
captureWarnings() 函數(shù)可用來將 logging 和 warnings 模塊集成。
-
logging.captureWarnings(capture)? 此函數(shù)用于打開和關(guān)閉日志系統(tǒng)對(duì)警告的捕獲。
如果 capture 是
True,則warnings模塊發(fā)出的警告將重定向到日志記錄系統(tǒng)。具體來說,將使用warnings.formatwarning()格式化警告信息,并將結(jié)果字符串使用WARNING等級(jí)記錄到名為'py.warnings'的記錄器中。如果 capture 是
False,則將停止將警告重定向到日志記錄系統(tǒng),并且將警告重定向到其原始目標(biāo)(即在captureWarnings(True)調(diào)用之前的有效目標(biāo))。
參見
- 模塊
logging.config 日志記錄模塊的配置 API 。
- 模塊
logging.handlers 日志記錄模塊附帶的有用處理程序。
- PEP 282 - Logging 系統(tǒng)
該提案描述了Python標(biāo)準(zhǔn)庫(kù)中包含的這個(gè)特性。
- Original Python logging package
這是該
logging包的原始來源。該站點(diǎn)提供的軟件包版本適用于 Python 1.5.2、2.1.x 和 2.2.x,它們不被logging包含在標(biāo)準(zhǔn)庫(kù)中。
