Python的logging模塊提供了通用的日誌系統,可以方便第三方模塊或者是應用使用。這個模塊提供不同的日誌級別,並可以採用不同的方式記錄日誌。
logging的日誌可以分爲debug(),info(),warning(),error()和critical 五個級別
最簡單用法
#!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.debug('debug message') logging.info('info message') logging.warn('warn message') logging.error('error message') logging.critical('critical message') WARNING:root:warn message ERROR:root:error message CRITICAL:root:critical message
默認情況下,logging模塊將日誌打印到屏幕上(stdout),日誌級別爲WARNING(即只有日誌級別高於WARNING的日誌信息纔會輸出)日誌格式如:
WARNING : root: warn message 日誌級別 logger實例名 日誌消息內容
日誌級別
級別 | 應用 |
DEBUG | 詳細信息,典型地調試問題時會感興趣 |
INFO | 證明事情按預期工作 |
WARNING | 表明發生了一些意外,或者不久的將來會發生問題(如‘磁盤滿了’)。軟件還是在正常工作 |
ERROR | 由於更嚴重的問題,軟件已不能執行一些功能了 |
CRITICAL | 嚴重錯誤,表明軟件已不能繼續運行了 |
把日誌寫到文件裏,簡單配置
#!/usr/local/bin/python # -*- coding:utf-8 -*- import logging logging.basicConfig(filename='logger.log', level=logging.INFO) logging.debug('debug message') logging.info('info message') logging.warn('warn message') logging.error('error message') logging.critical('critical message') INFO:root:info message WARNING:root:warn message ERROR:root:error message CRITICAL:root:critical message
標準輸出(屏幕)未顯示任何信息,發現當前工作目錄下生成了logger.log
其中下面這句level=loggin.INFO意思是,把日誌紀錄級別設置爲INFO,也就是說,只有比日誌是INFO或比INFO級別更高的日誌纔會被紀錄到文件裏,在這個例子, 第一條日誌是不會被紀錄的,如果希望紀錄debug的日誌,那把日誌級別改成DEBUG就行了
如果想同時把log打印在屏幕和文件日誌裏,就需要了解一點複雜的知識了
幾個重要的概念
Logger | 記錄器,暴露了應用程序代碼能直接使用的接口 |
Handler | 處理器,將(記錄器產生的)日誌記錄發送至合適的目的地 |
Filter | 過濾器,提供了更好的粒度控制,它可以決定輸出哪些日誌記錄 |
Formatter | 格式化器,指明瞭最終輸出中日誌記錄的佈局 |
Logger 記錄器
Logger是一個樹形層級結構,在使用接口debug,info,warn,error,critical之前必須創建Logger實例,即創建一個記錄器,如果沒有顯式的進行創建,則默認創建一個root logger,並應用默認的日誌級別(WARN),處理器Handler(StreamHandler,即將日誌信息打印輸出在標準輸出上),和格式化器Formatter(默認的格式即爲第一個簡單使用程序中輸出的格式)。
# 創建方法 logger = logging.getLogger(logger_name)
創建Logger實例後,可以使用以下方法進行日誌級別設置,增加處理器Handler
·logger.setLevel(logging.ERROR) # 設置日誌級別爲ERROR,即只有日誌級別大於等於ERROR的日誌纔會輸出
·logger.addHandler(handler_name) # 爲Logger實例增加一個處理器
·logger.removeHandler(handler_name) # 爲Logger實例刪除一個處理器
Handler 處理器
Handler處理器類型有很多種,比較常用的有三個,StreamHandler,FileHandler,NullHandler
# 創建方法 sh = logging.StreamHandler(stream=None) fh = logging.FileHandler(filename, mode='a', encoding=None, delay=False)
創建StreamHandler之後,可以通過使用以下方法設置日誌級別,設置格式化器Formatter,增加或刪除過濾器Filter
·ch.setLevel(logging.WARN) # 指定日誌級別,低於WARN級別的日誌將被忽略
·ch.setFormatter(formatter_name) # 設置一個格式化器formatter
·ch.addFilter(filter_name) # 增加一個過濾器,可以增加多個
·ch.removeFilter(filter_name) # 刪除一個過濾器
NullHandler類位於核心logging包,不做任何的格式化或者輸出。
本質上它是個“什麼都不做”的handler,由庫開發者使用
Formatter 格式化器
使用Formatter對象設置日誌信息最後的規則、結構和內容,默認的時間格式爲%Y-%m-%d %H:%M:%S
# 創建方法 formatter = logging.Formatter(fmt=None, datefmt=None)
其中,fmt是消息的格式化字符串,datefmt是日期字符串。如果不指明fmt,將使用'%(message)s'。如果不指明datefmt,將使用ISO8601日期格式
Filter 過濾器
暫且略過
basicConfig關鍵字參數
關鍵字 | 描述 |
filename | 創建一個FileHandler,使用指定的文件名,而不是使用StreamHandler |
filemode | 如果指明瞭文件名,指明打開文件的模式(如果沒有指明filemode,默認爲'a') |
format | handler使用指明的格式化字符串 |
datefmt | 使用指明的日期/時間格式 |
level | 指明根logger的級別 |
stream | 使用指明的流來初始化StreamHandler。該參數與'filename'不兼容,如果兩個都有,'stream'被忽略 |
format格式
格式 | 描述 |
%(levelno)s | 打印日誌級別的數值 |
%(levelname)s | 打印日誌級別名稱 |
%(pathname)s | 打印當前執行程序的路徑 |
%(filename)s | 打印當前執行程序名稱 |
%(funcName)s | 打印日誌的當前函數 |
%(lineno)d | 打印日誌的當前行號 |
%(asctime)s | 打印日誌的時間 |
%(thread)d | 打印線程id |
%(threadName)s | 打印線程名稱 |
%(process)d | 打印進程ID |
%(message)s | 打印日誌信息 |
配置示例
顯式配置
# -*- encoding:utf-8 -*- import logging # create logger logger_name = "le" logger = logging.getLogger(logger_name) logger.setLevel(logging.DEBUG) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # create file handler and set level to warning log_path = "./log.log" fh = logging.FileHandler(log_path) fh.setLevel(logging.WARN) # create formatter fmt = "%(asctime)-15s %(levelname)s %(filename)s %(lineno)d %(process)d %(message)s" datefmt = "%a %d %b %Y %H:%M:%S" formatter = logging.Formatter(fmt, datefmt) # add handler and formatter to logger ch.setFormatter(formatter) fh.setFormatter(formatter) logger.addHandler(ch) logger.addHandler(fh) # print log info logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
源自作者,好吃的野菜&alex大王