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

源代碼: Lib/logging/config.py


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

配置函數(shù)?

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

logging.config.dictConfig(config)?

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

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

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

  • propagate 值不是布爾類型。

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

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

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

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

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

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

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

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

3.2 新版功能.

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

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

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

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

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

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

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

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

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

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

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

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

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

備注

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 參數(shù)。

備注

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

logging.config.stopListening()?

停止通過對 listen() 的調(diào)用所創(chuàng)建的監(jiān)聽服務(wù)器。 此函數(shù)的調(diào)用通常會先于在 listen() 的返回值上調(diào)用 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 用戶定義對象. 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.

配置字典架構(gòu)?

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

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

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

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

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

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

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

    • format

    • datefmt

    • style

    • validate (從版本 >=3.8 起)

    可選的 class 鍵指定格式化器類的名稱(形式為帶點號的模塊名和類名)。 實例化的參數(shù)與 Formatter 的相同,因此這個鍵對于實例化自定義的 Formatter 子類最為有用。 如果,替代類可能 會以擴展和精簡格式呈現(xiàn)異常回溯信息。 如果你的格式化器需要不同的或額外的配置鍵,你應(yīng)當使用 用戶定義對象。

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

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

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

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

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

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

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

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

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

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

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

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

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

    • 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)有配置上新增。 該值默認為 False,這意味著指定的配置將以與當前 fileConfig() API 所使用的相同語義來替代現(xiàn)有的配置。

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

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

增量配置?

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

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

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

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

對象連接?

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

因此,舉例來說,考慮以下 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 是因為它的可讀性比表示字典的等價 Python 源碼形式更好。)

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

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

用戶定義對象?

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

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

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 代碼片段定義了三個格式化器。 第一個的 ID 為 brief,是帶有特殊格式字符串的標準 logging.Formatter 實例。 第二個的 ID 為 default,具有更長的格式同時還顯式地定義了時間格式,并將最終實例化一個帶有這兩個格式字符串的 logging.Formatter。 以 Python 源代碼形式顯示的 briefdefault 格式化器分別具有下列配置子字典:

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

和:

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

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

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

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

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

'()' 用作特殊鍵是因為它不是一個有效的關(guān)鍵字形參名稱,這樣就不會與調(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.

訪問外部對象?

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

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

訪問內(nèi)部對象?

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

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

handlers:
  file:
    # configuration of file handler goes here

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

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

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

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

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

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

from importlib import import_module
from logging.config import BaseConfigurator

BaseConfigurator.importer = staticmethod(import_module)

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

配置文件格式?

fileConfig() 所能理解的配置文件格式是基于 configparser 功能的。 該文件必須包含 [loggers], [handlers][formatters] 等小節(jié),它們通過名稱來標識文件中定義的每種類型的實體。 對于每個這樣的實體,都有單獨的小節(jié)來標識實體的配置方式。 因此,對于 [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 的實例,你將必須使用 dictConfig()。 請注意未來還將向 dictConfig() 添加對配置功能的強化,因此值得考慮在方便的時候轉(zhuǎn)換到這個新 API。

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

[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

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

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

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

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

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

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

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

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

formatter 條目指明此處理器的格式化器的鍵名稱。 如為空白,則會使用默認的格式化器 (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 {}.

[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}

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

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

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

備注

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

參見

模塊 logging

日志記錄模塊的 API 參考。

logging.handlers 模塊

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