logging.config --- 日志記錄配置?
這一節描述了用于配置 logging 模塊的 API。
配置函數?
下列函數可配置 logging 模塊。 它們位于 logging.config 模塊中。 它們的使用是可選的 --- 要配置 logging 模塊你可以使用這些函數,也可以通過調用主 API (在 logging 本身定義) 并定義在 logging 或 logging.handlers 中聲明的處理程序。
-
logging.config.dictConfig(config)? 從一個字典獲取日志記錄配置。 字典的內容描述見下文的 配置字典架構。
如果在配置期間遇到錯誤,此函數將引發
ValueError,TypeError,AttributeError或ImportError并附帶適當的描述性消息。 下面是將會引發錯誤的(可能不完整的)條件列表:level不是字符串或者不是對應于實際日志記錄級別的字符串。propagate值不是布爾類型。id 沒有對應的目標。
在增量調用期間發現不存在的處理程序 id。
無效的日志記錄器名稱。
無法解析為內部或外部對象。
解析由
DictConfigurator類執行,該類的構造器可傳入用于配置的字典,并且具有configure()方法。logging.config模塊具有可調用屬性dictConfigClass,其初始值設為DictConfigurator。 你可以使用你自己的適當實現來替換dictConfigClass的值。dictConfig()會調用dictConfigClass并傳入指定的字典,然后在所返回的對象上調用configure()方法以使配置生效:def dictConfig(config): dictConfigClass(config).configure()
例如,
DictConfigurator的子類可以在它自己的__init__()中調用DictConfigurator.__init__(),然后設置可以在后續configure()調用中使用的自定義前綴。dictConfigClass將被綁定到這個新的子類,然后就可以與在默認的未定制狀態下完全相同的方式調用dictConfig()。3.2 新版功能.
-
logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)? 從一個
configparser格式文件中讀取日志記錄配置。 文件格式應當與 配置文件格式 中的描述一致。 此函數可在應用程序中被多次調用,以允許最終用戶在多個預設配置中進行選擇(如果開發者提供了展示選項并加載選定配置的機制)。- 參數
fname -- 一個文件名,或一個文件類對象,或是一個派生自
RawConfigParser的實例。 如果傳入了一個派生自RawConfigParser的實例,它會被原樣使用。 否則,將會實例化一個Configparser,并且它會從作為fname傳入的對象中讀取配置。 如果存在readline()方法,則它會被當作一個文件類對象并使用read_file()來讀取;在其它情況下,它會被當作一個文件名并傳遞給read()。defaults -- 要傳遞給 ConfigParser 的默認值可在此參數中指定。
disable_existing_loggers -- 如果指定為
False,則當執行此調用時已存在的日志記錄器會保持啟用。 默認值為True因為這將以向下兼容方式啟用舊行為。 此行為是禁用任何現有的非根日志記錄器除非它們或它們的上級在日志記錄配置中被顯式地命名。
在 3.4 版更改: 現在接受
RawConfigParser子類的實例作為fname的值。 這有助于:使用一個配置文件,其中日志記錄配置只是全部應用程序配置的一部分。
使用從一個文件讀取的配置,它隨后會在被傳給
fileConfig之前由使用配置的應用程序來修改(例如基于命令行參數或運行時環境的其他部分)。
-
logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)? 在指定的端口上啟動套接字服務器,并監聽新的配置。 如果未指定端口,則會使用模塊默認的
DEFAULT_LOGGING_CONFIG_PORT。 日志記錄配置將作為適合由dictConfig()或fileConfig()進行處理的文件來發送。 返回一個Thread實例,你可以在該實例上調用start()來啟動服務器,對該服務器你可以在適當的時候執行join()。 要停止該服務器,請調用stopListening()。如果指定
verify參數,則它應當是一個可調用對象,該對象應當驗證通過套接字接收的字節數據是否有效且應被處理。 這可以通過對通過套接字發送的內容進行加密和/或簽名來完成,這樣verify可調用對象就能執行簽名驗證和/或解密。verify可調用對象的調用會附帶一個參數 —— 通過套接字接收的字節數據 —— 并應當返回要處理的字節數據,或者返回None來指明這些字節數據應當被丟棄。 返回的字節數據可以與傳入的字節數據相同(例如在只執行驗證的時候),或者也可以完全不同(例如在可能執行了解密的時候)。要將配置發送到套接字,請讀取配置文件并將其作為字節序列發送到套接字,字節序列要以使用
struct.pack('>L', n)打包為二進制格式的四字節長度的字符串打頭。注解
因為配置的各部分是通過
eval()傳遞的,使用此函數可能讓用戶面臨安全風險。 雖然此函數僅綁定到localhost上的套接字,因此并不接受來自遠端機器的連接,但在某些場景中不受信任的代碼可以在調用listen()的進程的賬戶下運行。 具體來說,如果如果調用listen()的進程在用戶無法彼此信任的多用戶機器上運行,則惡意用戶就能簡單地通過連接到受害者的listen()套接字并發送運行攻擊者想在受害者的進程上執行的任何代碼的配置的方式,安排運行幾乎任意的代碼。 如果是使用默認端口這會特別容易做到,即便使用了不同端口也不難做到。 要避免發生這種情況的風險,請在listen()中使用verify參數來防止未經認可的配置被應用。在 3.4 版更改: 添加了
verify參數。注解
如果你希望將配置發送給未禁用現有日志記錄器的監聽器,你將需要使用 JSON 格式的配置,該格式將使用
dictConfig()進行配置。 此方法允許你在你發送的配置中將disable_existing_loggers指定為False。
配置字典架構?
描述日志記錄配置需要列出要創建的不同對象及它們之間的連接;例如,你可以創建一個名為 'console' 的處理程序,然后名為 'startup' 的日志記錄器將可以把它的消息發送給 'console' 處理程序。 這些對象并不僅限于 logging 模塊所提供的對象,因為你還可以編寫你自己的格式化或處理程序類。 這些類的形參可能還需要包括 sys.stderr 這樣的外部對象。 描述這些對象和連接的語法會在下面的 對象連接 中定義。
字典架構細節?
傳給 dictConfig() 的字典必須包含以下的鍵:
version - 應設為代表架構版本的整數值。 目前唯一有效的值是 1,使用此鍵可允許架構在繼續演化的同時保持向下兼容性。
所有其他鍵都是可選項,但如存在它們將根據下面的描述來解讀。 在下面提到 'configuring dict' 的所有情況下,都將檢查它的特殊鍵 '()' 以確定是否需要自定義實例化。 如果需要,則會使用下面 用戶定義對象 所描述的機制來創建一個實例;否則,會使用上下文來確定要實例化的對象。
formatters - 對應的值將是一個字典,其中每個鍵是一個格式器 ID 而每個值則是一個描述如何配置相應
Formatter實例的字典。將在配置字典中搜索鍵
format和datefmt(默認值均為None) 并且這些鍵會被用于構造Formatter實例。filters - 對應的值將是一個字典,其中每個鍵是一個過濾器 ID 而每個值則是一個描述如何配置相應 Filter 實例的字典。
將在配置字典中搜索鍵
name(默認值為空字符串) 并且該鍵會被用于構造logging.Filter實例。handlers - 對應的值將是一個字典,其中每個鍵是一個處理程序 ID 而每個值則是一個描述如何配置相應 Handler 實例的字典。
將在配置字典中搜索下列鍵:
class(強制)。 這是處理程序類的完整限定名稱。level(可選)。 處理程序的級別。formatter(可選)。 處理程序所對應格式化器的 ID。filters(可選)。 由處理程序所對應過濾器的 ID 組成的列表。
所有 其他 鍵會被作為關鍵字參數傳遞給處理程序類的構造器。 例如,給定如下代碼段:
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,并附帶關鍵字參數filename='logconfig.log', maxBytes=1024, backupCount=3。loggers - 對應的值將是一個字典,其中每個鍵是一個日志記錄器名稱而每個值則是一個描述如何配置相應 Logger 實例的字典。
將在配置字典中搜索下列鍵:
level(可選)。 日志記錄器的級別。propagate(可選)。 日志記錄器的傳播設置。filters(可選)。 由日志記錄器對應過濾器的 ID 組成的列表。handlers(可選)。 由日志記錄器對應處理程序的 ID 組成的列表。
指定的日志記錄器將根據指定的級別、傳播、過濾器和處理程序來配置。
root - 這將成為根日志記錄器對應的配置。 配置的處理方式將與所有日志記錄器一致,除了
propagate設置將不可用之外。incremental - 配置是否要被解讀為在現有配置上新增。 該值默認為
False,這意味著指定的配置將以與當前fileConfig()API 所使用的相同語義來替代現有的配置。如果指定的值為
True,配置會按照 增量配置 部分所描述的方式來處理。disable_existing_loggers - 是否要禁用任何現有的非根日志記錄器。 該設置對應于
fileConfig()中的同名形參。 如果省略,則此形參默認為True。 如果 incremental 為True則該省會被忽略。
增量配置?
為增量配置提供完全的靈活性是很困難的。 例如,由于過濾器和格式化器這樣的對象是匿名的,一旦完成配置,在增加配置時就不可能引用這些匿名對象。
此外,一旦完成了配置,在運行時任意改變日志記錄器、處理程序、過濾器、格式化器的對象圖就不是很有必要;日志記錄器和處理程序的詳細程度只需通過設置級別即可實現控制(對于日志記錄器則可設置傳播旗標)。 在多線程環境中以安全的方式任意改變對象圖也許會導致問題;雖然并非不可能,但這樣做的好處不足以抵銷其所增加的實現復雜度。
這樣,當配置字典的 incremental 鍵存在且為 True 時,系統將完全忽略任何 formatters 和 filters 條目,并僅會處理 handlers 條目中的 level 設置,以及 loggers 和 root 條目中的 level 和 propagate 設置。
使用配置字典中的值可讓配置以封存字典對象的形式通過線路傳送給套接字監聽器。 這樣,長時間運行的應用程序的日志記錄的詳細程度可隨時間改變而無須停止并重新啟動應用程序。
對象連接?
該架構描述了一組日志記錄對象 —— 日志記錄器、處理程序、格式化器、過濾器 —— 它們在對象圖中彼此連接。 因此,該架構需要能表示對象之間的連接。 例如,在配置完成后,一個特定的日志記錄器關聯到了一個特定的處理程序。 出于討論的目的,我們可以說該日志記錄器代表兩者間連接的源頭,而處理程序則代表對應的目標。 當然在已配置對象中這是由包含對處理程序的引用的日志記錄器來代表的。 在配置字典中,這是通過給每個目標對象一個 ID 來無歧義地標識它,然后在源頭對象中使用該 ID 來實現的。
因此,舉例來說,考慮以下 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) 并且它們是瞬態的,因為它們僅對處理配置字典有意義并會被用來確定對象之間的連接,而當配置調用完成時不會在任何地方保留。
上面的代碼片段指明名為 foo.bar.baz 的日志記錄器應當關聯到兩個處理程序,它們的 ID 是 h1 和 h2。 h1 的格式化器的 ID 是 brief,而 h2 的格式化器的 ID 是 precise。
用戶定義對象?
此架構支持用戶定義對象作為處理程序、過濾器和格式化器。 (日志記錄器的不同實例不需要具有不同類型,因此這個配置架構并不支持用戶定義日志記錄器類。)
要配置的對象是由字典描述的,其中包含它們的配置詳情。 在某些地方,日志記錄系統將能夠從上下文中推斷出如何實例化一個對象,但是當要實例化一個用戶自定義對象時,系統將不知道要如何做。 為了提供用戶自定義對象實例化的完全靈活性,用戶需要提供一個‘工廠’函數 —— 即在調用時傳入配置字典并返回實例化對象的可調用對象。 這是用一個通過特殊鍵 '()' 來訪問的工廠函數的絕對導入路徑來標示的。 下面是一個實際的例子:
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 源代碼形式顯示的 brief 和 default 格式化器具有下列配置子字典:
{
'format' : '%(message)s'
}
和:
{
'format' : '%(asctime)s %(levelname)-8s %(name)-15s %(message)s',
'datefmt' : '%Y-%m-%d %H:%M:%S'
}
并且由于這些字典不包含特殊鍵 '()',實例化方式是從上下文中推斷出來的:結果會創建標準的 logging.Formatter 實例。 第三個格式器的 ID 為 custom,對應配置子字典為:
{
'()' : 'my.package.customFormatterFactory',
'bar' : 'baz',
'spam' : 99.9,
'answer' : 42
}
并且它包含特殊鍵 '()',這意味著需要用戶自定義實例化方式。 在此情況下,將使用指定的工廠可調用對象。 如果它本身就是一個可調用對象則將被直接使用 —— 否則如果你指定了一個字符串(如這個例子所示)則將使用正常的導入機制來定位實例的可調用對象。 調用該可調用對象將傳入配置子字典中 剩余的 條目作為關鍵字參數。 在上面的例子中,調用將預期返回 ID 為 custom 的格式化器:
my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)
將 '()' 用作特殊鍵是因為它不是一個有效的關鍵字形參名稱,這樣就不會與調用中使用的關鍵字參數發生沖突。 '()' 還被用作表明對應值為可調用對象的助記符。
訪問外部對象?
有時一個配置需要引用配置以外的對象,例如 sys.stderr。 如果配置字典是使用 Python 代碼構造的,這會很直觀,但是當配置是通過文本文件(例如 JSON, YAML)提供的時候就會引發問題。 在一個文本文件中,沒有將 sys.stderr 與字符串字面值 'sys.stderr' 區分開來的標準方式。 為了實現這種區分,配置系統會在字符串值中查找規定的特殊前綴并對其做特殊處理。 例如,如果在配置中將字符串字面值 'ext://sys.stderr' 作為一個值來提供,則 ext:// 將被去除而該值的剩余部分將使用正常導入機制來處理。
此類前綴的處理方式類似于協議處理:存在一種通用機制來查找與正則表達式 ^(?P<prefix>[a-z]+)://(?P<suffix>.*)$ 相匹配的前綴,如果識別出了 prefix,則 suffix 會以與前綴相對應的方式來處理并且處理的結果將替代原字符串值。 如果未識別出前綴,則原字符串將保持不變。
訪問內部對象?
除了外部對象,有時還需要引用配置中的對象。 這將由配置系統針對它所了解的內容隱式地完成。 例如,在日志記錄器或處理程序中表示 level 的字符串值 'DEBUG' 將被自動轉換為值 logging.DEBUG,而 handlers, filters 和 formatter 條目將接受一個對象 ID 并解析為適當的目標對象。
但是,對于 logging 模塊所不了解的用戶自定義對象則需要一種更通用的機制。 例如,考慮 logging.handlers.MemoryHandler,它接受一個 target 參數即其所委托的另一個處理程序。 由于系統已經知道存在該類,因而在配置中,給定的 target 只需為相應目標處理程序的的對象 ID 即可,而系統將根據該 ID 解析出處理程序。 但是,如果用戶定義了一個具有 alternate 處理程序的 my.package.MyHandler,則配置程序將不知道 alternate 指向的是一個處理程序。 為了應對這種情況,通用解析系統允許用戶指定:
handlers:
file:
# configuration of file handler goes here
custom:
(): my.package.MyHandler
alternate: cfg://handlers.file
字符串字面值 'cfg://handlers.file' 將按照與 ext:// 前綴類似的方式被解析為結果字符串,但查找操作是在配置自身而不是在導入命名空間中進行。 該機制允許按點號或按索引來訪問,與 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 將解析為 handlers 字典中帶有 email 鍵的字典,依此類推。 字符串 '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]' 來訪問。 后一種形式僅在鍵包含空格或非字母數字類字符的情況下才需要使用。 如果一個索引僅由十進制數碼構成,則將嘗試使用相應的整數值來訪問,如果有必要則將回退為字符串值。
給定字符串 cfg://handlers.myhandler.mykey.123,這將解析為 config_dict['handlers']['myhandler']['mykey']['123']。 如果字符串被指定為 cfg://handlers.myhandler.mykey[123],系統將嘗試從 config_dict['handlers']['myhandler']['mykey'][123] 中提取值,并在嘗試失敗時回退為 config_dict['handlers']['myhandler']['mykey']['123']。
導入解析與定制導入器?
導入解析默認使用內置的 __import__() 函數來執行導入。 你可能想要將其替換為你自己的導入機制:如果是這樣的話,你可以替換 DictConfigurator 或其超類 BaseConfigurator 類的 importer 屬性。 但是你必須小心謹慎,因為函數是從類中通過描述器方式來訪問的。 如果你使用 Python 可調用對象來執行導入,并且你希望在類層級而不是在實例層級上定義它,則你需要用 staticmethod() 來裝飾它。 例如:
from importlib import import_module
from logging.config import BaseConfigurator
BaseConfigurator.importer = staticmethod(import_module)
如果你是在一個配置器的 實例 上設置導入可調用對象則你不需要用 staticmethod() 來裝飾。
配置文件格式?
fileConfig() 所能理解的配置文件格式是基于 configparser 功能的。 該文件必須包含 [loggers], [handlers] 和 [formatters] 等小節,它們通過名稱來標識文件中定義的每種類型的實體。 對于每個這樣的實體,都有單獨的小節來標識實體的配置方式。 因此,對于 [loggers] 小節中名為 log01 的日志記錄器,相應的配置詳情保存在 [logger_log01] 小節中。 類似地,對于 [handlers] 小節中名為 hand01 的處理程序,其配置將保存在名為 [handler_hand01] 的小節中,而對于 [formatters] 小節中名為 form01 的格式化器,其配置將在名為 [formatter_form01] 的小節中指定。 根日志記錄器的配置必須在名為 [logger_root] 的小節中指定。
注解
fileConfig() API 比 dictConfig() API 更舊因而沒有提供涵蓋日志記錄特定方面的功能。 例如,你無法配置 Filter 對象,該對象使用 fileConfig() 提供超出簡單整數級別的消息過濾功能。 如果你想要在你的日志記錄配置中包含 Filter 的實例,你將必須使用 dictConfig()。 請注意未來還將向 dictConfig() 添加對配置功能的強化,因此值得考慮在方便的時候轉換到這個新 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
根日志記錄器必須指定一個級別和一個處理程序列表。 根日志小節的例子如下所示。
[logger_root]
level=NOTSET
handlers=hand01
level 條目可以為 DEBUG, INFO, WARNING, ERROR, CRITICAL 或 NOTSET 之一。 其中 NOTSET 僅適用于根日志記錄器,表示將會記錄所有消息。 級別值會在 logging 包命名空間的上下文中通過 eval() 來得出。
handlers 條目是以逗號分隔的處理程序名稱列表,它必須出現于 [handlers] 小節并且在配置文件中有相應的小節。
對于根日志記錄器以外的日志記錄器,還需要某些附加信息。 下面的例子演示了這些信息。
[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser
level 和 handlers 條目的解釋方式與根日志記錄器的一致,不同之處在于如果一個非根日志記錄器的級別被指定為 NOTSET,則系統會咨詢更高層級的日志記錄器來確定該日志記錄器的有效級別。 propagate 條目設為 1 表示消息必須從此日志記錄器傳播到更高層級的處理程序,設為 0 表示消息 不會 傳播到更高層級的處理程序。 qualname 條目是日志記錄器的層級通道名稱,也就是應用程序獲取日志記錄器所用的名稱。
指定處理程序配置的小節說明如下。
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)
class 條目指明處理程序的類(由 logging 包命名空間中的 eval() 來確定)。 level 會以與日志記錄器相同的方式來解讀,NOTSET 會被視為表示‘記錄一切消息’。
formatter 條目指明此處理程序的格式化器的鍵名稱。 如為空白,則會使用默認的格式化器 (logging._defaultFormatter)。 如果指定了名稱,則它必須出現于 [formatters] 小節并且在配置文件中有相應的小節。
args 條目,當在 logging 包命名空間的上下文中執行 eval() 時將是傳給處理程序類構造器的參數列表。 請參閱相應處理程序的構造器說明或者下面的示例,以了解典型的條目是如何構造的。 如果未提供,則默認為 ()。
可選的 kwargs 條目,當在 logging 包命名空間的上下文中執行 eval() 時將是傳給處理程序的構造器的關鍵字參數字典。 如果未提供,則默認為 {}。
[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}
指定格式化器配置的小節說明如下。
[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
class=logging.Formatter
format 是整個格式字符串,而 datefmt 條目則是兼容 strftime() 的日期/時間格式字符串。 如果為空,此包將替換任何接近于日期格式字符串 '%Y-%m-%d %H:%M:%S' 的內容。 此格式還指定了毫秒,并使用逗號分隔符將其附加到結果當中。 此格式的時間示例如 2003-01-23 00:29:50,411。
class 條目是可選的。 它指明格式化器類的名稱(形式為帶點號的模塊名加類名。) 此選項適用于實例化 Formatter 的子類。 Formatter 的子類可通過擴展或收縮格式來顯示異常回溯信息。
注解
由于如上所述使用了 eval(),因此使用 listen() 通過套接字來發送和接收配置會導致潛在的安全風險。 此風險僅限于相互間沒有信任的多個用戶在同一臺機器上運行代碼的情況;請參閱 listen() 了解更多信息。
參見
- 模塊
logging 日志記錄模塊的 API 參考。
- 模塊
logging.handlers 日志記錄模塊附帶的有用處理程序。
