日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)Python教程:logging.config—-日志記錄配置

logging.config —- 日志記錄配置

源代碼: Lib/logging/config.py

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)服務(wù)商,為中小企業(yè)提供網(wǎng)站制作、成都網(wǎng)站建設(shè)服務(wù),網(wǎng)站設(shè)計(jì),網(wǎng)站托管運(yùn)營等一站式綜合服務(wù)型公司,專業(yè)打造企業(yè)形象網(wǎng)站,讓您在眾多競爭對手中脫穎而出創(chuàng)新互聯(lián)。

Important

此頁面僅包含參考信息。有關(guān)教程,請參閱

  • 基礎(chǔ)教程

  • 進(jìn)階教程

  • 日志記錄操作手冊


這一節(jié)描述了用于配置 logging 模塊的 API。

配置函數(shù)

下列函數(shù)可配置 logging 模塊。 它們位于 logging.config 模塊中。 它們的使用是可選的 —- 要配置 logging 模塊你可以使用這些函數(shù),也可以通過調(diào)用主 API (在 logging 本身定義) 并定義在 logging 或 logging.handlers 中聲明的處理器。

logging.config.dictConfig(config)

從一個(gè)字典獲取日志記錄配置。 字典的內(nèi)容描述見下文的 配置字典架構(gòu)。

如果在配置期間遇到錯(cuò)誤,此函數(shù)將引發(fā) ValueError, TypeError, AttributeError 或 ImportError 并附帶適當(dāng)?shù)拿枋鲂韵ⅰ?下面是將會(huì)引發(fā)錯(cuò)誤的(可能不完整的)條件列表:

  • level 不是字符串或者不是對應(yīng)于實(shí)際日志記錄級別的字符串。

  • propagate 值不是布爾類型。

  • id 沒有對應(yīng)的目標(biāo)。

  • 在增量調(diào)用期間發(fā)現(xiàn)不存在的處理器 id。

  • 無效的日志記錄器名稱。

  • 無法解析為內(nèi)部或外部對象。

解析由 DictConfigurator 類執(zhí)行,該類的構(gòu)造器可傳入用于配置的字典,并且具有 configure() 方法。 logging.config 模塊具有可調(diào)用屬性 dictConfigClass,其初始值設(shè)為 DictConfigurator。 你可以使用你自己的適當(dāng)實(shí)現(xiàn)來替換 dictConfigClass 的值。

dictConfig() 會(huì)調(diào)用 dictConfigClass 并傳入指定的字典,然后在所返回的對象上調(diào)用 configure() 方法以使配置生效:

 
 
 
 
  1. def dictConfig(config):
  2. dictConfigClass(config).configure()

例如,DictConfigurator 的子類可以在它自己的 __init__() 中調(diào)用 DictConfigurator.__init__(),然后設(shè)置可以在后續(xù) configure() 調(diào)用中使用的自定義前綴。 dictConfigClass 將被綁定到這個(gè)新的子類,然后就可以與在默認(rèn)的未定制狀態(tài)下完全相同的方式調(diào)用 dictConfig()。

3.2 新版功能.

logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=None)

從一個(gè) configparser 格式文件中讀取日志記錄配置。 文件格式應(yīng)當(dāng)與 配置文件格式 中的描述一致。 此函數(shù)可在應(yīng)用程序中被多次調(diào)用,以允許最終用戶在多個(gè)預(yù)設(shè)配置中進(jìn)行選擇(如果開發(fā)者提供了展示選項(xiàng)并加載選定配置的機(jī)制)。

  • 參數(shù)

    • fname — 一個(gè)文件名,或一個(gè)文件類對象,或是一個(gè)派生自 RawConfigParser 的實(shí)例。 如果傳入了一個(gè)派生自 RawConfigParser 的實(shí)例,它會(huì)被原樣使用。 否則,將會(huì)實(shí)例化一個(gè) Configparser,并且它會(huì)從作為 fname 傳入的對象中讀取配置。 如果存在 readline() 方法,則它會(huì)被當(dāng)作一個(gè)文件類對象并使用 read_file() 來讀??;在其它情況下,它會(huì)被當(dāng)作一個(gè)文件名并傳遞給 read()。

    • defaults — 要傳遞給 ConfigParser 的默認(rèn)值可在此參數(shù)中指定。

    • disable_existing_loggers — 如果指定為 False,則當(dāng)執(zhí)行此調(diào)用時(shí)已存在的日志記錄器會(huì)被保持啟用。 默認(rèn)值為 True 因?yàn)檫@將以向下兼容的方式啟用舊有行為。 此行為是禁用任何已存在的非根日志記錄器除非它們或它們的上級在日志配置中被顯式地指定。 :param encoding: 當(dāng) fname 為文件名時(shí)用于打開文件的編碼格式。

在 3.4 版更改: 現(xiàn)在接受 RawConfigParser 子類的實(shí)例作為 fname 的值。 這有助于:

  • 使用一個(gè)配置文件,其中日志記錄配置只是全部應(yīng)用程序配置的一部分。

  • 使用從一個(gè)文件讀取的配置,它隨后會(huì)在被傳給 fileConfig 之前由使用配置的應(yīng)用程序來修改(例如基于命令行參數(shù)或運(yùn)行時(shí)環(huán)境的其他部分)。

3.10 新版功能: 增加了 encoding 形參。

logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)

在指定的端口上啟動(dòng)套接字服務(wù)器,并監(jiān)聽新的配置。 如果未指定端口,則會(huì)使用模塊默認(rèn)的 DEFAULT_LOGGING_CONFIG_PORT。 日志記錄配置將作為適合由 dictConfig() 或 fileConfig() 進(jìn)行處理的文件來發(fā)送。 返回一個(gè) Thread 實(shí)例,你可以在該實(shí)例上調(diào)用 start() 來啟動(dòng)服務(wù)器,對該服務(wù)器你可以在適當(dāng)?shù)臅r(shí)候執(zhí)行 join()。 要停止該服務(wù)器,請調(diào)用 stopListening()。

如果指定 verify 參數(shù),則它應(yīng)當(dāng)是一個(gè)可調(diào)用對象,該對象應(yīng)當(dāng)驗(yàn)證通過套接字接收的字節(jié)數(shù)據(jù)是否有效且應(yīng)被處理。 這可以通過對通過套接字發(fā)送的內(nèi)容進(jìn)行加密和/或簽名來完成,這樣 verify 可調(diào)用對象就能執(zhí)行簽名驗(yàn)證和/或解密。 verify 可調(diào)用對象的調(diào)用會(huì)附帶一個(gè)參數(shù) —— 通過套接字接收的字節(jié)數(shù)據(jù) —— 并應(yīng)當(dāng)返回要處理的字節(jié)數(shù)據(jù),或者返回 None 來指明這些字節(jié)數(shù)據(jù)應(yīng)當(dāng)被丟棄。 返回的字節(jié)數(shù)據(jù)可以與傳入的字節(jié)數(shù)據(jù)相同(例如在只執(zhí)行驗(yàn)證的時(shí)候),或者也可以完全不同(例如在可能執(zhí)行了解密的時(shí)候)。

要將配置發(fā)送到套接字,請讀取配置文件并將其作為字節(jié)序列發(fā)送到套接字,字節(jié)序列要以使用 struct.pack('>L', n) 打包為二進(jìn)制格式的四字節(jié)長度的字符串打頭。

備注

因?yàn)榕渲玫母鞑糠质峭ㄟ^ eval() 傳遞的,使用此函數(shù)可能讓用戶面臨安全風(fēng)險(xiǎn)。雖然此函數(shù)僅綁定到 localhost 上的套接字,因此并不接受來自遠(yuǎn)端機(jī)器的連接,但在某些場景中不受信任的代碼可以在調(diào)用 listen() 的進(jìn)程的賬戶下運(yùn)行。具體來說,如果如果調(diào)用 listen() 的進(jìn)程在用戶無法彼此信任的多用戶機(jī)器上運(yùn)行,則惡意用戶就能簡單地通過連接到受害者的 listen() 套接字并發(fā)送運(yùn)行攻擊者想在受害者的進(jìn)程上執(zhí)行的任何代碼的配置的方式,安排運(yùn)行幾乎任意的代碼。如果是使用默認(rèn)端口這會(huì)特別容易做到,即便使用了不同端口也不難做到。要避免發(fā)生這種情況的風(fēng)險(xiǎn),請?jiān)?listen() 中使用 verify 參數(shù)來防止未經(jīng)認(rèn)可的配置被應(yīng)用。

在 3.4 版更改: 添加了 verify 參數(shù)。

備注

如果你希望將配置發(fā)送給未禁用現(xiàn)有日志記錄器的監(jiān)聽器,你將需要使用 JSON 格式的配置,該格式將使用 dictConfig() 進(jìn)行配置。 此方法允許你在你發(fā)送的配置中將 disable_existing_loggers 指定為 False。

logging.config.stopListening()

停止通過對 listen() 的調(diào)用所創(chuàng)建的監(jiān)聽服務(wù)器。 此函數(shù)的調(diào)用通常會(huì)先于在 listen() 的返回值上調(diào)用 join()。

安全考量

日志配置功能試圖提供便利,從某種角度來說,這是通過將配置文件中的文本轉(zhuǎn)換為日志配置中使用的 python 對象來完成的 —— 如 用戶定義對象 中所述。但是,這些相同的機(jī)制(從用戶定義的模塊中導(dǎo)入可調(diào)用對象并使用配置中的參數(shù)調(diào)用它們)可用于調(diào)用您指定的任何代碼,因此您應(yīng)該*非常謹(jǐn)慎*地處理來自非信任源的配置文件。并且在實(shí)際加載前,您應(yīng)該確信加載不會(huì)導(dǎo)致壞事情。

配置字典架構(gòu)

描述日志記錄配置需要列出要?jiǎng)?chuàng)建的不同對象及它們之間的連接;例如,你可以創(chuàng)建一個(gè)名為 ‘console’ 的處理器,然后名為 ‘startup’ 的日志記錄器將可以把它的消息發(fā)送給 ‘console’ 處理器。 這些對象并不僅限于 logging 模塊所提供的對象,因?yàn)槟氵€可以編寫你自己的格式化或處理器類。 這些類的形參可能還需要包括 sys.stderr 這樣的外部對象。 描述這些對象和連接的語法會(huì)在下面的 對象連接 中定義。

字典架構(gòu)細(xì)節(jié)

傳給 dictConfig() 的字典必須包含以下的鍵:

  • version - 應(yīng)設(shè)為代表架構(gòu)版本的整數(shù)值。 目前唯一有效的值是 1,使用此鍵可允許架構(gòu)在繼續(xù)演化的同時(shí)保持向下兼容性。

所有其他鍵都是可選項(xiàng),但如存在它們將根據(jù)下面的描述來解讀。 在下面提到 ‘configuring dict’ 的所有情況下,都將檢查它的特殊鍵 '()' 以確定是否需要自定義實(shí)例化。 如果需要,則會(huì)使用下面 用戶定義對象 所描述的機(jī)制來創(chuàng)建一個(gè)實(shí)例;否則,會(huì)使用上下文來確定要實(shí)例化的對象。

  • formatters - 對應(yīng)的值將是一個(gè)字典,其中每個(gè)鍵是一個(gè)格式器 ID 而每個(gè)值則是一個(gè)描述如何配置相應(yīng) Formatter 實(shí)例的字典。

    在配置字典中搜索以下可選鍵,這些鍵對應(yīng)于創(chuàng)建 Formatter 對象時(shí)傳入的參數(shù)。:

    • format

    • datefmt

    • style

    • validate (從版本 >=3.8 起)

    可選的 class 鍵指定格式化器類的名稱(形式為帶點(diǎn)號的模塊名和類名)。 實(shí)例化的參數(shù)與 Formatter 的相同,因此這個(gè)鍵對于實(shí)例化自定義的 Formatter 子類最為有用。 如果,替代類可能 會(huì)以擴(kuò)展和精簡格式呈現(xiàn)異?;厮菪畔ⅰ?如果你的格式化器需要不同的或額外的配置鍵,你應(yīng)當(dāng)使用 用戶定義對象。

  • filters - 對應(yīng)的值將是一個(gè)字典,其中每個(gè)鍵是一個(gè)過濾器 ID 而每個(gè)值則是一個(gè)描述如何配置相應(yīng) Filter 實(shí)例的字典。

    將在配置字典中搜索鍵 name (默認(rèn)值為空字符串) 并且該鍵會(huì)被用于構(gòu)造 logging.Filter 實(shí)例。

  • handlers - 對應(yīng)的值將是一個(gè)字典,其中每個(gè)鍵是一個(gè)處理器 ID 而每個(gè)值則是一個(gè)描述如何配置相應(yīng) Handler 實(shí)例的字典。

    將在配置字典中搜索下列鍵:

    • class (強(qiáng)制)。 這是處理器類的完整限定名稱。

    • level (可選)。 處理器的級別。

    • formatter (可選)。 處理器所對應(yīng)格式化器的 ID。

    • filters (可選)。 由處理器所對應(yīng)過濾器的 ID 組成的列表。

      在 3.11 版更改: filters can take filter instances in addition to ids.

    所有 其他 鍵會(huì)被作為關(guān)鍵字參數(shù)傳遞給處理器類的構(gòu)造器。 例如,給定如下配置:

       
       
       
       
    1. handlers:
    2. console:
    3. class : logging.StreamHandler
    4. formatter: brief
    5. level : INFO
    6. filters: [allow_foo]
    7. stream : ext://sys.stdout
    8. file:
    9. class : logging.handlers.RotatingFileHandler
    10. formatter: precise
    11. filename: logconfig.log
    12. maxBytes: 1024
    13. backupCount: 3

    ID 為 console 的處理器會(huì)被實(shí)例化為 logging.StreamHandler,并使用 sys.stdout 作為下層流。 ID 為 file 的處理器會(huì)被實(shí)例化為 logging.handlers.RotatingFileHandler,并附帶關(guān)鍵字參數(shù) filename='logconfig.log', maxBytes=1024, backupCount=3。

  • loggers - 對應(yīng)的值將是一個(gè)字典,其中每個(gè)鍵是一個(gè)日志記錄器名稱而每個(gè)值則是一個(gè)描述如何配置相應(yīng) Logger 實(shí)例的字典。

    將在配置字典中搜索下列鍵:

    • level (可選)。 日志記錄器的級別。

    • propagate (可選)。 日志記錄器的傳播設(shè)置。

    • filters (可選)。 由日志記錄器對應(yīng)過濾器的 ID 組成的列表。

      在 3.11 版更改: filters can take filter instances in addition to ids.

    • handlers (可選)。 由日志記錄器對應(yīng)處理器的 ID 組成的列表。

    指定的記錄器將根據(jù)指定的級別、傳播、過濾器和處理器來配置。

  • root - 這將成為根日志記錄器對應(yīng)的配置。 配置的處理方式將與所有日志記錄器一致,除了 propagate 設(shè)置將不可用之外。

  • incremental - 配置是否要被解讀為在現(xiàn)有配置上新增。 該值默認(rèn)為 False,這意味著指定的配置將以與當(dāng)前 fileConfig() API 所使用的相同語義來替代現(xiàn)有的配置。

    如果指定的值為 True,配置會(huì)按照 增量配置 部分所描述的方式來處理。

  • disable_existing_loggers - 是否要禁用任何現(xiàn)有的非根日志記錄器。 該設(shè)置對應(yīng)于 fileConfig() 中的同名形參。 如果省略,則此形參默認(rèn)為 True。 如果 incrementalTrue 則該省會(huì)被忽略。

增量配置

為增量配置提供完全的靈活性是很困難的。 例如,由于過濾器和格式化器這樣的對象是匿名的,一旦完成配置,在增加配置時(shí)就不可能引用這些匿名對象。

此外,一旦完成了配置,在運(yùn)行時(shí)任意改變?nèi)罩居涗浧?、處理器、過濾器、格式化器的對象圖就不是很有必要;日志記錄器和處理器的詳細(xì)程度只需通過設(shè)置級別即可實(shí)現(xiàn)控制(對于日志記錄器則可設(shè)置傳播旗標(biāo))。 在多線程環(huán)境中以安全的方式任意改變對象圖也許會(huì)導(dǎo)致問題;雖然并非不可能,但這樣做的好處不足以抵銷其所增加的實(shí)現(xiàn)復(fù)雜度。

這樣,當(dāng)配置字典的 incremental 鍵存在且為 True 時(shí),系統(tǒng)將完全忽略任何 formattersfilters 條目,并僅會(huì)處理 handlers 條目中的 level 設(shè)置,以及 loggersroot 條目中的 levelpropagate 設(shè)置。

使用配置字典中的值可讓配置以封存字典對象的形式通過線路傳送給套接字監(jiān)聽器。 這樣,長時(shí)間運(yùn)行的應(yīng)用程序的日志記錄的詳細(xì)程度可隨時(shí)間改變而無須停止并重新啟動(dòng)應(yīng)用程序。

對象連接

該架構(gòu)描述了一組日志記錄對象 —— 日志記錄器、處理器、格式化器、過濾器 —— 它們在對象圖中彼此連接。 因此,該架構(gòu)需要能表示對象之間的連接。 例如,在配置完成后,一個(gè)特定的日志記錄器關(guān)聯(lián)到了一個(gè)特定的處理器。 出于討論的目的,我們可以說該日志記錄器代表兩者間連接的源頭,而處理器則代表對應(yīng)的目標(biāo)。 當(dāng)然在已配置對象中這是由包含對處理器的引用的日志記錄器來代表的。 在配置字典中,這是通過給每個(gè)目標(biāo)對象一個(gè) ID 來無歧義地標(biāo)識它,然后在源頭對象中使用該 ID 來實(shí)現(xiàn)的。

因此,舉例來說,考慮以下 YAML 代碼段:

 
 
 
 
  1. formatters:
  2. brief:
  3. # configuration for formatter with id 'brief' goes here
  4. precise:
  5. # configuration for formatter with id 'precise' goes here
  6. handlers:
  7. h1: #This is an id
  8. # configuration of handler with id 'h1' goes here
  9. formatter: brief
  10. h2: #This is another id
  11. # configuration of handler with id 'h2' goes here
  12. formatter: precise
  13. loggers:
  14. foo.bar.baz:
  15. # other configuration for logger 'foo.bar.baz'
  16. handlers: [h1, h2]

(注:這里使用 YAML 是因?yàn)樗目勺x性比表示字典的等價(jià) Python 源碼形式更好。)

日志記錄器 ID 就是日志記錄器的名稱,它會(huì)在程序中被用來獲取對日志記錄器的引用,例如 foo.bar.baz。 格式化器和過濾器的 ID 可以是任意字符串值 (例如上面的 brief, precise) 并且它們是瞬態(tài)的,因?yàn)樗鼈儍H對處理配置字典有意義并會(huì)被用來確定對象之間的連接,而當(dāng)配置調(diào)用完成時(shí)不會(huì)在任何地方保留。

上面的代碼片段指明名為 foo.bar.baz 的日志記錄器應(yīng)當(dāng)關(guān)聯(lián)到兩個(gè)處理器,它們的 ID 是 h1h2。 h1 的格式化器的 ID 是 brief,而 h2 的格式化器的 ID 是 precise。

用戶定義對象

此架構(gòu)支持用戶定義對象作為處理器、過濾器和格式化器。 (日志記錄器的不同實(shí)例不需要具有不同類型,因此這個(gè)配置架構(gòu)并不支持用戶定義日志記錄器類。)

要配置的對象是由字典描述的,其中包含它們的配置詳情。 在某些地方,日志記錄系統(tǒng)將能夠從上下文中推斷出如何實(shí)例化一個(gè)對象,但是當(dāng)要實(shí)例化一個(gè)用戶自定義對象時(shí),系統(tǒng)將不知道要如何做。 為了提供用戶自定義對象實(shí)例化的完全靈活性,用戶需要提供一個(gè)‘工廠’函數(shù) —— 即在調(diào)用時(shí)傳入配置字典并返回實(shí)例化對象的可調(diào)用對象。 這是用一個(gè)通過特殊鍵 '()' 來訪問的工廠函數(shù)的絕對導(dǎo)入路徑來標(biāo)示的。 下面是一個(gè)實(shí)際的例子:

 
 
 
 
  1. formatters:
  2. brief:
  3. format: '%(message)s'
  4. default:
  5. format: '%(asctime)s %(levelname)-8s %(name)-15s %(message)s'
  6. datefmt: '%Y-%m-%d %H:%M:%S'
  7. custom:
  8. (): my.package.customFormatterFactory
  9. bar: baz
  10. spam: 99.9
  11. answer: 42

上面的 YAML 代碼片段定義了三個(gè)格式化器。 第一個(gè)的 ID 為 brief,是帶有特殊格式字符串的標(biāo)準(zhǔn) logging.Formatter 實(shí)例。 第二個(gè)的 ID 為 default,具有更長的格式同時(shí)還顯式地定義了時(shí)間格式,并將最終實(shí)例化一個(gè)帶有這兩個(gè)格式字符串的 logging.Formatter。 以 Python 源代碼形式顯示的 briefdefault 格式化器分別具有下列配置子字典:

 
 
 
 
  1. {
  2. 'format' : '%(message)s'
  3. }

和:

 
 
 
 
  1. {
  2. 'format' : '%(asctime)s %(levelname)-8s %(name)-15s %(message)s',
  3. 'datefmt' : '%Y-%m-%d %H:%M:%S'
  4. }

并且由于這些字典不包含特殊鍵 '()',實(shí)例化方式是從上下文中推斷出來的:結(jié)果會(huì)創(chuàng)建標(biāo)準(zhǔn)的 logging.Formatter 實(shí)例。 第三個(gè)格式器的 ID 為 custom,對應(yīng)配置子字典為:

 
 
 
 
  1. {
  2. '()' : 'my.package.customFormatterFactory',
  3. 'bar' : 'baz',
  4. 'spam' : 99.9,
  5. 'answer' : 42
  6. }

并且它包含特殊鍵 '()',這意味著需要用戶自定義實(shí)例化方式。 在此情況下,將使用指定的工廠可調(diào)用對象。 如果它本身就是一個(gè)可調(diào)用對象則將被直接使用 —— 否則如果你指定了一個(gè)字符串(如這個(gè)例子所示)則將使用正常的導(dǎo)入機(jī)制來定位實(shí)例的可調(diào)用對象。 調(diào)用該可調(diào)用對象將傳入配置子字典中 剩余的 條目作為關(guān)鍵字參數(shù)。 在上面的例子中,調(diào)用將預(yù)期返回 ID 為 custom 的格式化器:

 
 
 
 
  1. my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)

'()' 用作特殊鍵是因?yàn)樗皇且粋€(gè)有效的關(guān)鍵字形參名稱,這樣就不會(huì)與調(diào)用中使用的關(guān)鍵字參數(shù)發(fā)生沖突。 '()' 還被用作表明對應(yīng)值為可調(diào)用對象的助記符。

在 3.11 版更改: The filters member of handlers and loggers can take filter instances in addition to ids.

You can also specify a special key '.' whose value is a dictionary is a mapping of attribute names to values. If found, the specified attributes will be set on the user-defined object before it is returned. Thus, with the following configuration:

 
 
 
 
  1. {
  2. '()' : 'my.package.customFormatterFactory',
  3. 'bar' : 'baz',
  4. 'spam' : 99.9,
  5. 'answer' : 42,
  6. '.' {
  7. 'foo': 'bar',
  8. 'baz': 'bozz'
  9. }
  10. }

the returned formatter will have attribute foo set to 'bar' and attribute baz set to 'bozz'.

訪問外部對象

有時(shí)一個(gè)配置需要引用配置以外的對象,例如 sys.stderr。 如果配置字典是使用 Python 代碼構(gòu)造的,這會(huì)很直觀,但是當(dāng)配置是通過文本文件(例如 JSON, YAML)提供的時(shí)候就會(huì)引發(fā)問題。 在一個(gè)文本文件中,沒有將 sys.stderr 與字符串字面值 'sys.stderr' 區(qū)分開來的標(biāo)準(zhǔn)方式。 為了實(shí)現(xiàn)這種區(qū)分,配置系統(tǒng)會(huì)在字符串值中查找規(guī)定的特殊前綴并對其做特殊處理。 例如,如果在配置中將字符串字面值 'ext://sys.stderr' 作為一個(gè)值來提供,則 ext:// 將被去除而該值的剩余部分將使用正常導(dǎo)入機(jī)制來處理。

此類前綴的處理方式類似于協(xié)議處理:存在一種通用機(jī)制來查找與正則表達(dá)式 ^(?P[a-z]+)://(?P.*)$ 相匹配的前綴,如果識別出了 prefix,則 suffix 會(huì)以與前綴相對應(yīng)的方式來處理并且處理的結(jié)果將替代原字符串值。 如果未識別出前綴,則原字符串將保持不變。

訪問內(nèi)部對象

除了外部對象,有時(shí)還需要引用配置中的對象。 這將由配置系統(tǒng)針對它所了解的內(nèi)容隱式地完成。 例如,在日志記錄器或處理器中表示 level 的字符串值 'DEBUG' 將被自動(dòng)轉(zhuǎn)換為值 logging.DEBUG,而 handlers, filtersformatter 條目將接受一個(gè)對象 ID 并解析為適當(dāng)?shù)哪繕?biāo)對象。

但是,對于 logging 模塊所不了解的用戶自定義對象則需要一種更通用的機(jī)制。 例如,考慮 logging.handlers.MemoryHandler,它接受一個(gè) target 參數(shù)即其所委托的另一個(gè)處理器。 由于系統(tǒng)已經(jīng)知道存在該類,因而在配置中,給定的 target 只需為相應(yīng)目標(biāo)處理器的的對象 ID 即可,而系統(tǒng)將根據(jù)該 ID 解析出處理器。 但是,如果用戶定義了一個(gè)具有 alternate 處理器的 my.package.MyHandler,則配置程序?qū)⒉恢?alternate 指向的是一個(gè)處理器。 為了應(yīng)對這種情況,通用解析系統(tǒng)允許用戶指定:

 
 
 
 
  1. handlers:
  2. file:
  3. # configuration of file handler goes here
  4. custom:
  5. (): my.package.MyHandler
  6. alternate: cfg://handlers.file

字符串字面值 'cfg://handlers.file' 將按照與 ext:// 前綴類似的方式被解析為結(jié)果字符串,但查找操作是在配置自身而不是在導(dǎo)入命名空間中進(jìn)行。 該機(jī)制允許按點(diǎn)號或按索引來訪問,與 str.format 所提供的方式類似。 這樣,給定以下代碼段:

 
 
 
 
  1. handlers:
  2. email:
  3. class: logging.handlers.SMTPHandler
  4. mailhost: localhost
  5. fromaddr: my_app@domain.tld
  6. toaddrs:
  7. - support_team@domain.tld
  8. - dev_team@domain.tld
  9. subject: Houston, we have a problem.

在該配置中,字符串 'cfg://handlers' 將解析為帶有 handlers 鍵的字典,字符串 'cfg://handlers.email 將解析為具有 email 鍵的 handlers 字典中的字典,依此類推。 字符串 'cfg://handlers.email.toaddrs[1] 將解析為 'dev_team@domain.tld' 而字符串 'cfg://handlers.email.toaddrs[0]' 將解析為值 'support_team@domain.tld'subject 值 可以使用 'cfg://handlers.email.subject' 或者等價(jià)的 'cfg://handlers.email[subject]' 來訪問。 后一種形式僅在鍵包含空格或非字母類數(shù)字類字符的情況下才需要使用。 如果一個(gè)索引僅由十進(jìn)制數(shù)碼構(gòu)成,則將嘗試使用相應(yīng)的整數(shù)值來訪問,如果有必要?jiǎng)t將回退為字符串值。

給定字符串 cfg://handlers.myhandler.mykey.123,這將解析為 config_dict['handlers']['myhandler']['mykey']['123']。 如果字符串被指定為 cfg://handlers.myhandler.mykey[123],系統(tǒng)將嘗試從 config_dict['handlers']['myhandler']['mykey'][123] 中提取值,并在嘗試失敗時(shí)回退為 config_dict['handlers']['myhandler']['mykey']['123']

導(dǎo)入解析與定制導(dǎo)入器

導(dǎo)入解析默認(rèn)使用內(nèi)置的 __import__() 函數(shù)來執(zhí)行導(dǎo)入。 你可能想要將其替換為你自己的導(dǎo)入機(jī)制:如果是這樣的話,你可以替換 DictConfigurator 或其超類 BaseConfigurator 類的 importer 屬性。 但是你必須小心謹(jǐn)慎,因?yàn)楹瘮?shù)是從類中通過描述器方式來訪問的。 如果你使用 Python 可調(diào)用對象來執(zhí)行導(dǎo)入,并且你希望在類層級而不是在實(shí)例層級上定義它,則你需要用 staticmethod() 來裝飾它。 例如:

 
 
 
 
  1. from importlib import import_module
  2. from logging.config import BaseConfigurator
  3. BaseConfigurator.importer = staticmethod(import_module)

如果你是在一個(gè)配置器的 實(shí)例 上設(shè)置導(dǎo)入可調(diào)用對象則你不需要用 staticmethod() 來裝飾。

配置文件格式

fileConfig() 所能理解的配置文件格式是基于 configparser 功能的。 該文件必須包含 [loggers], [handlers][formatters] 等小節(jié),它們通過名稱來標(biāo)識文件中定義的每種類型的實(shí)體。 對于每個(gè)這樣的實(shí)體,都有單獨(dú)的小節(jié)來標(biāo)識實(shí)體的配置方式。 因此,對于 [loggers] 小節(jié)中名為 log01 的日志記錄器,相應(yīng)的配置詳情保存在 [logger_log01] 小節(jié)中。 類似地,對于 [handlers] 小節(jié)中名為 hand01 的處理器,其配置將保存在名為 [handler_hand01] 的小節(jié)中,而對于 [formatters] 小節(jié)中名為 form01 的格式化器,其配置將在名為 [formatter_form01] 的小節(jié)中指定。 根日志記錄器的配置必須在名為 [logger_root] 的小節(jié)中指定。

備注

fileConfig() API 比 dictConfig() API 更舊因而沒有提供涵蓋日志記錄特定方面的功能。 例如,你無法配置 Filter 對象,該對象使用 fileConfig() 提供超出簡單整數(shù)級別的消息過濾功能。 如果你想要在你的日志記錄配置中包含 Filter 的實(shí)例,你將必須使用 dictConfig()。 請注意未來還將向 dictConfig() 添加對配置功能的強(qiáng)化,因此值得考慮在方便的時(shí)候轉(zhuǎn)換到這個(gè)新 API。

在文件中這些小節(jié)的例子如下所示。

 
 
 
 
  1. [loggers]
  2. keys=root,log02,log03,log04,log05,log06,log07
  3. [handlers]
  4. keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09
  5. [formatters]
  6. keys=form01,form02,form03,form04,form05,form06,form07,form08,form09

根日志記錄器必須指定一個(gè)級別和一個(gè)處理器列表。 根日志小節(jié)的例子如下所示。

 
 
 
 
  1. [logger_root]
  2. level=NOTSET
  3. handlers=hand01

The level entry can be one of DEBUG, INFO, WARNING, ERROR, CRITICAL or NOTSET. For the root logger only, NOTSET means that all messages will be logged. Level values are evaluated in the context of the logging package’s namespace.

handlers 條目是以逗號分隔的處理器名稱列表,它必須出現(xiàn)于 [handlers] 小節(jié)并且在配置文件中有相應(yīng)的小節(jié)。

對于根日志記錄器以外的日志記錄器,還需要某些附加信息。 下面的例子演示了這些信息。

 
 
 
 
  1. [logger_parser]
  2. level=DEBUG
  3. handlers=hand01
  4. propagate=1
  5. qualname=compiler.parser

levelhandlers 條目的解釋方式與根日志記錄器的一致,不同之處在于如果一個(gè)非根日志記錄器的級別被指定為 NOTSET,則系統(tǒng)會(huì)咨詢更高層級的日志記錄器來確定該日志記錄器的有效級別。 propagate 條目設(shè)為 1 表示消息必須從此日志記錄器傳播到更高層級的處理器,設(shè)為 0 表示消息 不會(huì) 傳播到更高層級的處理器。 qualname 條目是日志記錄器的層級通道名稱,也就是應(yīng)用程序獲取日志記錄器所用的名稱。

指定處理器配置的小節(jié)說明如下。

 
 
 
 
  1. [handler_hand01]
  2. class=StreamHandler
  3. level=NOTSET
  4. formatter=form01
  5. args=(sys.stdout,)

class 條目指明處理器的類(由 logging 包命名空間中的 eval() 來確定)。 level 會(huì)以與日志記錄器相同的方式來解讀,NOTSET 會(huì)被視為表示‘記錄一切消息’。

formatter 條目指明此處理器的格式化器的鍵名稱。 如為空白,則會(huì)使用默認(rèn)的格式化器 (logging._defaultFormatter)。 如果指定了名稱,則它必須出現(xiàn)于 [formatters] 小節(jié)并且在配置文件中有相應(yīng)的小節(jié)。

The args entry, when evaluated in the context of the logging package’s namespace, is the list of arguments to the constructor for the handler class. Refer to the constructors for the relevant handlers, or to the examples below, to see how typical entries are constructed. If not provided, it defaults to ().

The optional kwargs entry, when evaluated in the context of the logging package’s namespace, is the keyword argument dict to the constructor for the handler class. If not provided, it defaults to {}.

 
 
 
 
  1. [handler_hand02]
  2. class=FileHandler
  3. level=DEBUG
  4. formatter=form02
  5. args=('python.log', 'w')
  6. [handler_hand03]
  7. class=handlers.SocketHandler
  8. level=INFO
  9. formatter=form03
  10. args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
  11. [handler_hand04]
  12. class=handlers.DatagramHandler
  13. level=WARN
  14. formatter=form04
  15. args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
  16. [handler_hand05]
  17. class=handlers.SysLogHandler
  18. level=ERROR
  19. formatter=form05
  20. args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
  21. [handler_hand06]
  22. class=handlers.NTEventLogHandler
  23. level=CRITICAL
  24. formatter=form06
  25. args=('Python Application', '', 'Application')
  26. [handler_hand07]
  27. class=handlers.SMTPHandler
  28. level=WARN
  29. formatter=form07
  30. args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
  31. kwargs={'timeout': 10.0}
  32. [handler_hand08]
  33. class=handlers.MemoryHandler
  34. level=NOTSET
  35. formatter=form08
  36. target=
  37. args=(10, ERROR)
  38. [handler_hand09]
  39. class=handlers.HTTPHandler
  40. level=NOTSET
  41. formatter=form09
  42. args=('localhost:9022', '/log', 'GET')
  43. kwargs={'secure': True}

指定格式化器配置的小節(jié)說明如下。

 
 
 
 
  1. [formatter_form01]
  2. format=F1 %(asctime)s %(levelname)s %(message)s
  3. datefmt=
  4. style=%
  5. validate=True
  6. class=logging.Formatter

用于格式化器配置的參數(shù)與字典規(guī)范 格式化器部分 中的鍵相同。

備注

由于如上所述使用了 eval(),因此使用 listen() 通過套接字來發(fā)送和接收配置會(huì)導(dǎo)致潛在的安全風(fēng)險(xiǎn)。 此風(fēng)險(xiǎn)僅限于相互間沒有信任的多個(gè)用戶在同一臺機(jī)器上運(yùn)行代碼的情況;請參閱 listen() 了解更多信息。

參見

模塊 logging

日志記錄模塊的 API 參考。

logging.handlers 模塊

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


文章標(biāo)題:創(chuàng)新互聯(lián)Python教程:logging.config—-日志記錄配置
本文鏈接:http://www.dlmjj.cn/article/ccspihs.html