?
?
一、常用日志記錄場景及最佳解決方案:
?
日志記錄方式 | 最佳記錄日志方案 |
普通情況下,在控制臺顯示輸出 | print() |
報告正常程序操作過程中發生的事件 | logging.info()(或者更詳細的logging.debug()) |
發出有關特定事件的警告 | warnings.warn()或者logging.warning() |
報告錯誤 | 彈出異常 |
在不引發異常的情況下報告錯誤 | logging.error(), logging.exception()或者logging.critical() |
?
?
?
二、日志等級:
?
logging模塊定義了下表所示的日志級別,按事件嚴重程度由低到高排列(注意是全部大寫!因為它們是常量。):
級別 | 級別數值 | 使用時機 |
DEBUG | 10 | 詳細信息,常用于調試 |
INFO | 20 | 程序正常運行過程中產生的一些信息 |
WARNING | 30 | 警告用戶,雖然程序還在正常工作,但有可能發生錯誤 |
ERROR | 40 | 由于更嚴重的問題,程序已不能執行一些功能了 |
CRITICAL | 50 | 嚴重錯誤,程序已不能繼續運行 |
?
?
?
三、logging基本使用方法:
?
產生五種日志級別(WARING、ERROR和CRITICAL會直接輸出()內的提示語至屏幕):
logging.info('info')
logging.debug('debug')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
?
?
日志系統配置文件(定義日志一些規則):
?
logging.basicConfig(filename='test.log', level=logging.INFO, filemode='a', format='%(levelname)s:%(asctime)s:%(message)s')
?
filename:日志要保存至哪個文件中(定義了這個后日志將不再在屏幕上打印)
level:什么級別以上的日志需要保存
filemode:有"w"、"a"兩種模式,同open一樣,"a"追加,"w"覆蓋
format:定義日志格式(后面提供日志元素表,建議通過":"將各種日志元素連接成合理的日志格式)
format定義格式時用的日志元素表:
?
日志元素 | 描述 |
%(asctime)s | 日志產生的時間,默認格式為2003-07-08 16:49:45,896 |
%(created)f | time.time()生成的日志創建時間戳 |
%(filename)s | 生成日志的程序名 |
%(funcName)s | 調用日志的函數名 |
%(levelname)s | 日志級別 ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') |
%(levelno)s | 日志級別對應的數值 |
%(lineno)d | 日志所針對的代碼行號(如果可用的話) |
%(module)s | 生成日志的模塊名 |
%(msecs)d | 日志生成時間的毫秒部分 |
%(message)s | 具體的日志信息 |
%(name)s | 日志調用者 |
%(pathname)s | 生成日志的文件的完整路徑 |
%(process)d | 生成日志的進程ID(如果可用) |
%(processName)s | 進程名(如果可用) |
%(thread)d | 生成日志的線程ID(如果可用) |
%(threadName)s | 線程名(如果可用) |
?
?
?
?
四、logging高級用法(讓日志即能寫入文件又能在屏幕打印):
?
包含關系(左邊包含右邊):
記錄器<——處理器<——格式化器
?
import logging
"""
????logging模塊采用了模塊化設計,主要包含四種組件:
????
????Loggers:記錄器,提供應用程序代碼能直接使用的接口;
????Handlers:處理器,將記錄器產生的日志發送至目的地;
????Filters:過濾器,提供更好的粒度控制,決定哪些日志會被輸出;
????Formatters:格式化器,設置日志內容的組成結構和消息字段。
?
"""
# 創建一個記錄器loggers,并設置默認等級
logger = logging.getLogger('jack') ?# ‘jack’位置定義了日志調用者的名字
logger.setLevel(logging.INFO)
?
# 創建兩個處理器handlers(一個發往日志文件、一個發往屏幕),并分別設置他們的日志等級
stream = logging.StreamHandler() ????# 發往屏幕
stream.setLevel(logging.DEBUG) ?????# 定義什么樣級別以上的日志發往屏幕
?
file = logging.FileHandler('test.log') ???# 發往日志文件(需指定文件名稱)
file.setLevel(logging.ERROR) ??# 定義什么樣級別以上的日志發往日志文件
?
# 分別為兩個處理器handlers創建格式化器formatters(可以讓其在屏幕和日志文件中以不同的格式輸出)
formatter_stream = logging.Formatter('%(levelname)s:%(asctime)s:%(message)s')
formatter_file = logging.Formatter('%(name)s:%(levelname)s:%(asctime)s:%(message)s')
?
# 為各個處理器handlers設置相應的格式化器
stream.setFormatter(formatter_stream)
file.setFormatter(formatter_file)
?
# 將所有的處理器handler加入自定義的記錄器logger內
logger.addHandler(stream)
logger.addHandler(file)
?
# 測試日志功能
logger.debug('debug')
logger.info('info')
logger.warning('warn')
logger.error('error')
logger.critical('critical')
?
?