logging模塊:
不少程序都有記錄日誌的需求,而且日誌中包含的信息既有正常的程序訪問日誌,還可能有錯誤、警告等信息輸出。Python的logging模塊提供了標準的日誌接口,你能夠經過它存儲各類格式的日誌。logging的日誌能夠分爲debug()、info()、warning()、error() and critical()5個級別(按順序,級別愈來愈高)。html
最簡單的用法:python
import logging logging.warning('User [neo] attempted wrong password more than 3 times') logging.critical('server is down') # 運行結果: # 跟print沒啥區別 # WARNING:root:User [neo] attempted wrong password more than 3 times # CRITICAL:root:server is down
日誌級別:web
把日誌寫到文件裏:網絡
import logging logging.basicConfig(filename='logging_test.log',level=logging.INFO) # Do basic configuration for the logging system. # level=logging.INFO的意思是:只有日誌是INFO或者比INFO級別更高的日誌纔會被記錄在文件裏 # 記錄日誌時,只會接着之前的日誌繼續記錄,不會把之前的記錄覆蓋掉。 logging.debug('debug test') logging.info('INFO info') logging.warning('Warning!') # 運行結果: 把logging.info和logging.warning記錄在了 ‘logging_test.log’(.log的後綴名)這個文件裏。 # 這種狀況下屏幕上沒打印,即 沒有輸出到屏幕 # 以下所示: # INFO:root:INFO info # WARNING:root:Warning!
把時間加到日誌裏面:spa
import logging logging.basicConfig(filename='logging_with_time.log', level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # 注意裏面的參數‘format’和‘datefmt’ logging.debug('debug test') logging.info('INFO info') logging.warning('Warning!') # 運行結果: INFO及其以上級別寫入了‘logging_with_time.log’文件裏面 # 以下所示: # 2018-02-09 11:37:11 INFO info # 2018-02-09 11:37:11 Warning!
除了加時間,還能夠自定義其餘的格式,下表就是全部支持的格式:debug
logging進階:日誌同時輸出到屏幕和文件:3d
Python使用logging模塊記錄日誌涉及四個主要的類:日誌
它們之間的關係以下:code
logger:orm
每一個程序在輸出信息以前都要先得到一個logger,如:
import logging # 生成 logger 對象 logger = logging.getLogger('web') # logger一般對應了程序的模塊名 # 對logger對象設置Level級別,如設置成INFO級別 logger.setLevel(logging.INFO) # 利用logger.setLevel()對生成的logger對象設置級別, logging.INFO是把級別具體設置成INFO,若是你不設置,系統會默認把Level設置成WARNING。 # 對logger對象設置level的做用: logger。setLevel()至關於一個全局變量,所須要輸出的日誌須要先通過logging.getLogger生成logger對象,因此生成logger對象以前,會先檢測所輸出的日誌級別是否符合logger.setLevel的級別,若是符合則生成logger對象;若是不符合則直接忽略、不生成logger對象。 舉例說明: 有兩個須要輸出的日誌: logger.debug('test debug') 和 logger.info('test info') , 執行這兩句代碼的時候, 因爲我已經給生成logger設置了level --- INFO:logger.setLevel(logging.INFO) ,debug的level低於INFO, 因此 logger.debug('test debug') 不會生成logger對象,但 logger.info('test info') 則會生成logger對象(至關於第一步生成logger對象時過濾了一部分數據)
handler:
handler負責發送相關的信息到指定目的地。 Python日誌系統有多種handler能夠使用。能夠把信息輸出到控制檯(屏幕),也能夠把信息輸出到文件,把信息發送到網絡上。本身也能夠編寫本身的handler。
每一個logger能夠附加多個handler。經常使用的handler以下:
用法以下:
# 生成logger對象以後,再生成handler對象,而後把handler綁定到logger上 # 生成handler對象 ch = logging.StreamHandler() # 負責往屏幕發送的handler(發送到屏幕,因此括號裏面爲空) fh = logging.FileHandler('web.log') # 負責往文件「web.log」發送的handler # 日誌文件的後綴名: .log # 把生成的handler對象綁定到logger對象 logger.addHandler(ch) # 把ch這個handler對象綁定到logger上 logger.addHandler(fh) # 把fh這個handler對象綁定到logger上 # 設置handler的level ch.setLevel(logging.INFO) # 把ch這個handler對象的level設置成INFO fh.setLevel(logging.WARNING) # 把fh這個handler對象的level設置成WARNING # 關於設置handler的level,道理跟logger的level設置相似,即: 若是你不設置, 程序會默認level是WARNING;經過這一步設置的level可以再次「過濾」數據 # 關於logger設置的level和handler設置的level,按照哪一個level呢? 效果上能夠這麼理解: 所須要輸出的日誌(如: logger.warning(xx)), 先通過logger設置的level「過濾」,而後在生成handler對象這一步, 再次通過這一步的level「過濾」:level符合,則生成相應的handler;level不符合則忽略、不生成handler對象。
formatter組件:
日誌的formatter是個獨立的組件,能夠跟handler組合, 用於設置所要發送的信息以什麼樣的格式發送到目的地。
用法:
# 生成handler對象以後,再生成formatter對象,而後將formatter對象和handler綁定 # 生成formatter對象 console_fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s') # 利用上面的logger名字表 file_fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 把formatter對象綁定到handler ch.setFormatter(console_fmt) fh.setFormatter(file_fmt)
下面把上述的代碼拼接到一塊兒看效果:
import logging # 生成logger對象 logger = logging.getLogger('web') logger.setLevel(logging.INFO) # 生成handler對象 ch = logging.StreamHandler() fh = logging.FileHandler('web.log') # 設置level ch.setLevel(logging.DEBUG) fh.setLevel(logging.WARNING) # 把handler綁定在logger上 logger.addHandler(ch) logger.addHandler(fh) # 生成formatter對象 console_fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s') file_fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # %(name)s 這個name就是生成logger時括號裏面的‘web’ # 把formatter綁定到handler ch.setFormatter(console_fmt) fh.setFormatter(file_fmt) logger.debug('debug test') logger.info('info test') logger.warning('warning test') logger.error('error test') logger.critical('critical test') # 輸出的日誌
filter的用法參考: https://www.luffycity.com/python-book/di-4-zhang-python-ji-chu-2014-chang-yong-mo-kuai/logging-mo-kuai.html