logging.config --- 日志記錄配置?

源代碼: Lib/logging/config.py


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

配置函數?

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

logging.config.dictConfig(config)?

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

如果在配置期間遇到錯誤,此函數將引發(fā) ValueError, TypeError, AttributeErrorImportError 并附帶適當的描述性消息。 下面是將會(huì )引發(fā)錯誤的(可能不完整的)條件列表:

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

  • propagate 值不是布爾類(lèi)型。

  • id 沒(méi)有對應的目標。

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

  • 無(wú)效的日志記錄器名稱(chēng)。

  • 無(wú)法解析為內部或外部對象。

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

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

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

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

3.2 新版功能.

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

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

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

  • defaults -- 要傳遞給 ConfigParser 的默認值可在此參數中指定。

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

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

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

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

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

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

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

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

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

備注

Because portions of the configuration are passed through eval(), use of this function may open its users to a security risk. While the function only binds to a socket on localhost, and so does not accept connections from remote machines, there are scenarios where untrusted code could be run under the account of the process which calls listen(). Specifically, if the process calling listen() runs on a multi-user machine where users cannot trust each other, then a malicious user could arrange to run essentially arbitrary code in a victim user's process, simply by connecting to the victim's listen() socket and sending a configuration which runs whatever code the attacker wants to have executed in the victim's process. This is especially easy to do if the default port is used, but not hard even if a different port is used. To avoid the risk of this happening, use the verify argument to listen() to prevent unrecognised configurations from being applied.

在 3.4 版更改: 添加了 verify 參數。

備注

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

logging.config.stopListening()?

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

Security considerations?

The logging configuration functionality tries to offer convenience, and in part this is done by offering the ability to convert text in configuration files into Python objects used in logging configuration - for example, as described in 用戶(hù)定義對象. However, these same mechanisms (importing callables from user-defined modules and calling them with parameters from the configuration) could be used to invoke any code you like, and for this reason you should treat configuration files from untrusted sources with extreme caution and satisfy yourself that nothing bad can happen if you load them, before actually loading them.

配置字典架構?

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

字典架構細節?

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

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

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

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

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

    • format

    • datefmt

    • style

    • validate (從版本 >=3.8 起)

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

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

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

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

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

    • class (強制)。 這是處理器類(lèi)的完整限定名稱(chēng)。

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

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

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

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

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

    handlers:
      console:
        class : logging.StreamHandler
        formatter: brief
        level   : INFO
        filters: [allow_foo]
        stream  : ext://sys.stdout
      file:
        class : logging.handlers.RotatingFileHandler
        formatter: precise
        filename: logconfig.log
        maxBytes: 1024
        backupCount: 3
    

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

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

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

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

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

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

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

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

    指定的記錄器將根據指定的級別、傳播、過(guò)濾器和處理器來(lái)配置。

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

  • incremental - 配置是否要被解讀為在現有配置上新增。 該值默認為 False,這意味著(zhù)指定的配置將以與當前 fileConfig() API 所使用的相同語(yǔ)義來(lái)替代現有的配置。

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

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

增量配置?

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

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

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

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

對象連接?

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

因此,舉例來(lái)說(shuō),考慮以下 YAML 代碼段:

formatters:
  brief:
    # configuration for formatter with id 'brief' goes here
  precise:
    # configuration for formatter with id 'precise' goes here
handlers:
  h1: #This is an id
   # configuration of handler with id 'h1' goes here
   formatter: brief
  h2: #This is another id
   # configuration of handler with id 'h2' goes here
   formatter: precise
loggers:
  foo.bar.baz:
    # other configuration for logger 'foo.bar.baz'
    handlers: [h1, h2]

(注:這里使用 YAML 是因為它的可讀性比表示字典的等價(jià) Python 源碼形式更好。)

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

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

用戶(hù)定義對象?

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

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

formatters:
  brief:
    format: '%(message)s'
  default:
    format: '%(asctime)s %(levelname)-8s %(name)-15s %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
  custom:
      (): my.package.customFormatterFactory
      bar: baz
      spam: 99.9
      answer: 42

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

{
  'format' : '%(message)s'
}

和:

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

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

{
  '()' : 'my.package.customFormatterFactory',
  'bar' : 'baz',
  'spam' : 99.9,
  'answer' : 42
}

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

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

'()' 用作特殊鍵是因為它不是一個(gè)有效的關(guān)鍵字形參名稱(chēng),這樣就不會(huì )與調用中使用的關(guān)鍵字參數發(fā)生沖突。 '()' 還被用作表明對應值為可調用對象的助記符。

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

訪(fǎng)問(wèn)外部對象?

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

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

訪(fǎng)問(wèn)內部對象?

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

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

handlers:
  file:
    # configuration of file handler goes here

  custom:
    (): my.package.MyHandler
    alternate: cfg://handlers.file

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

handlers:
  email:
    class: logging.handlers.SMTPHandler
    mailhost: localhost
    fromaddr: my_app@domain.tld
    toaddrs:
      - support_team@domain.tld
      - dev_team@domain.tld
    subject: Houston, we have a problem.

在該配置中,字符串 'cfg://handlers' 將解析為帶有 handlers 鍵的字典,字符串 'cfg://handlers.email 將解析為具有 email 鍵的 handlers 字典中的字典,依此類(lèi)推。 字符串 '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]' 來(lái)訪(fǎng)問(wèn)。 后一種形式僅在鍵包含空格或非字母類(lèi)數字類(lèi)字符的情況下才需要使用。 如果一個(gè)索引僅由十進(jìn)制數碼構成,則將嘗試使用相應的整數值來(lái)訪(fǎng)問(wèn),如果有必要則將回退為字符串值。

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

導入解析與定制導入器?

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

from importlib import import_module
from logging.config import BaseConfigurator

BaseConfigurator.importer = staticmethod(import_module)

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

配置文件格式?

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

備注

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

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

[loggers]
keys=root,log02,log03,log04,log05,log06,log07

[handlers]
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09

[formatters]
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09

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

[logger_root]
level=NOTSET
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 條目是以逗號分隔的處理器名稱(chēng)列表,它必須出現于 [handlers] 小節并且在配置文件中有相應的小節。

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

[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser

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

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

[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)

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

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

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 {}.

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form02
args=('python.log', 'w')

[handler_hand03]
class=handlers.SocketHandler
level=INFO
formatter=form03
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)

[handler_hand04]
class=handlers.DatagramHandler
level=WARN
formatter=form04
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)

[handler_hand05]
class=handlers.SysLogHandler
level=ERROR
formatter=form05
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)

[handler_hand06]
class=handlers.NTEventLogHandler
level=CRITICAL
formatter=form06
args=('Python Application', '', 'Application')

[handler_hand07]
class=handlers.SMTPHandler
level=WARN
formatter=form07
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
kwargs={'timeout': 10.0}

[handler_hand08]
class=handlers.MemoryHandler
level=NOTSET
formatter=form08
target=
args=(10, ERROR)

[handler_hand09]
class=handlers.HTTPHandler
level=NOTSET
formatter=form09
args=('localhost:9022', '/log', 'GET')
kwargs={'secure': True}

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

[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
style=%
validate=True
class=logging.Formatter

用于格式化器配置的參數與字典規范 格式化器部分 中的鍵相同。

備注

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

參見(jiàn)

模塊 logging

日志記錄模塊的 API 參考。

logging.handlers 模塊

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