標籤:控制台 debug 列印 取值 stream 完整路徑 目前時間 dha 自動產生
logging模組
很多程式都有記錄日誌的需求,並且日誌中包含的資訊即有正常的程式訪問日誌,還可能有錯誤、警告等資訊輸出,python的logging模組提供了標準的日誌介面,你可以通過它儲存各種格式的日誌,logging的日誌可以分為:5個層級 debug() info() warning() error() critical()對於層級: notset 0 debug() 10 info() 20 warning() 30 error() 40 critical() 50 critical=fatal 只有設定大於當前日誌等級或等於的操作才會被記錄!!!
最簡單的文法:
import logging #直接輸出 logging.warning("user[HeiKe] attempted wrong password more than 3 times") #定義一個warning日誌輸出 logging.critical("server is down") #定義一個critical日誌輸出 #運行結果: WARNING:root:user[HeiKe] attempted wrong password more than 3 times CRITICAL:root:server is down
如果想把日誌寫到檔案裡:
import logginglogging.basicConfig(filename="test_log.log",level=logging.INFO)logging.debug("this is a debug log!!!")logging.info("this is a info !!!")logging.warning("this is a warning!!!")寫到檔案裡邊的內容如下: INFO:root:this is a info !!! WARNING:root:this is a warning!!!其中下面這句中的filename="test_log.log" 是設定log檔案、level=loggin.INFO意思是,把日誌紀錄層級設定為INFO,也就是說,只有比日誌是INFO或比INFO層級更高的日誌才會被紀錄到檔案裡,在這個例子, 第一條日誌是不會被紀錄的,如果希望紀錄debug的日誌,那把記錄層級改成DEBUG就行了。
記錄日誌加上時間:
import logginglogging.basicConfig(filename="test_log.log",level=logging.INFO,format="%(asctime)s %(message)s",datefmt="%Y-%m-%d %H:%M:%S %p") #%p 代表上午或者下午logging.debug("this is a debug log!!!")logging.info("this is a info !!!")logging.warning("this is a warning!!!")結果寫入檔案內容: 2018-01-23 17:41:39 PM this is a info !!! 2018-01-23 17:41:39 PM this is a warning!!!
日誌格式
%(name)s Logger的名字%(levelno)s 數字形式的記錄層級%(levelname)s 文本形式的記錄層級%(pathname)s 調用日誌輸出函數的模組的完整路徑名,可能沒有%(filename)s 調用日誌輸出函數的模組的檔案名稱%(module)s 調用日誌輸出函數的模組名%(funcName)s 調用日誌輸出函數的函數名%(lineno)d 調用日誌輸出函數的語句所在的程式碼%(created)f 目前時間,用UNIX標準的表示時間的浮 點數表示%(relativeCreated)d 輸出日誌資訊時的,自Logger建立以 來的毫秒數%(asctime)s 字串形式的目前時間。預設格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒%(thread)d 線程ID。可能沒有%(threadName)s 線程名。可能沒有%(process)d 進程ID。可能沒有%(message)s 使用者輸出的訊息
如果想同時把log列印在螢幕和檔案日誌裡,就需要瞭解一點複雜的知識了
python logging模組由幾個分類組成: logger提供了應用程式可以直接使用的介面;對外暴露介面; handler將(logger建立的)日誌記錄發送到合適的目的輸出; filter提供了過濾日誌來決定輸出哪條日誌記錄; formatter決定日誌記錄的最終輸出格式。
logger
每個程式在輸出資訊之前都要獲得一個Logger。Logger通常對應了程式的模組名,比如聊天工具的圖形介面模組可以這樣獲得它的Logger:LOG=logging.getLogger(”chat.gui”)而核心模組可以這樣:LOG=logging.getLogger(”chat.kernel”)Logger.setLevel(lel):指定最低的記錄層級,低於lel的層級將被忽略。debug是最低的內建層級,critical為最高Logger.addFilter(filt)、Logger.removeFilter(filt):添加或刪除指定的filterLogger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或刪除指定的handlerLogger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以設定的記錄層級
handler
handler對象負責發送相關的資訊到指定目的地。Python的日誌系統有多種Handler可以使用。有些Handler可以把資訊輸出到控制台,有些Logger可以把資訊輸出到檔案,還有些 Handler可以把資訊發送到網路上。如果覺得不夠用,還可以編寫自己的Handler。可以通過addHandler()方法添加多個多handler Handler.setLevel(lel):指定被處理的資訊層級,低於lel層級的資訊將被忽略 Handler.setFormatter():給這個handler選擇一個格式 Handler.addFilter(filt)、Handler.removeFilter(filt):新增或刪除一個filter對象每個Logger可以附加多個Handler。接下來我們就來介紹一些常用的Handler:1) logging.StreamHandler 使用這個Handler可以向類似與sys.stdout或者sys.stderr的任何檔案對象(file object)輸出資訊。它的建構函式是: StreamHandler([strm]) 其中strm參數是一個檔案對象。預設是sys.stderr2) logging.FileHandler 和StreamHandler類似,用於向一個檔案輸出日誌資訊。不過FileHandler會幫你開啟這個檔案。它的建構函式是: FileHandler(filename[,mode]) filename是檔案名稱,必須指定一個檔案名稱。 mode是檔案的開啟檔案。參見Python內建函數open()的用法。預設是’a‘,即添加到檔案末尾。3) logging.handlers.RotatingFileHandler 這個Handler類似於上面的FileHandler,但是它可以管理檔案大小。當檔案達到一定大小之後,它會自動將當前記錄檔改名,然後建立 一個新的同名記錄檔繼續輸出。比如記錄檔是chat.log。當chat.log達到指定的大小之後,RotatingFileHandler自動把 檔案改名為chat.log.1。不過,如果chat.log.1已經存在,會先把chat.log.1重新命名為chat.log.2。。。最後重新建立 chat.log,繼續輸出日誌資訊。它的建構函式是: RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]) 其中filename和mode兩個參數和FileHandler一樣。 maxBytes用於指定記錄檔的最大檔案大小。如果maxBytes為0,意味著記錄檔可以無限大,這時上面描述的重新命名過程就不會發生。 backupCount用於指定保留的備份檔案的個數。比如,如果指定為2,當上面描述的重新命名過程發生時,原有的chat.log.2並不會被更名,而是被刪除。4) logging.handlers.TimedRotatingFileHandler這個Handler和RotatingFileHandler類似,不過,它沒有通過判斷檔案大小來決定何時重新建立記錄檔,而是間隔一定時間就 自動建立新的記錄檔。重新命名的過程與RotatingFileHandler類似,不過新的檔案不是附加數字,而是目前時間。它的建構函式是: TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]) 其中filename參數和backupCount參數和RotatingFileHandler具有相同的意義。 interval是時間間隔。 when參數是一個字串。表示時間間隔的單位,不區分大小寫。它有以下取值: S 秒 M 分 H 小時 D 天 W 每星期(interval==0時代表星期一) midnight 每天淩晨
簡單的一個日誌輸出到 終端 和檔案的例子:
import logging#建立一個logger執行個體對象logger = logging.getLogger("own_definition")logger.setLevel(logging.DEBUG) #定義全域記錄層級#建立一個輸出到螢幕的對象screen = logging.StreamHandler()screen.setLevel(logging.INFO) #定義工作域記錄層級#建立一個輸出到檔案的對象file = logging.FileHandler("testtest.log")file.setLevel(logging.CRITICAL) #定義工作域記錄層級#建立一個日誌輸出格式log_output_format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")#把日誌輸出格式 賦予給 螢幕和檔案 對象screen.setFormatter(log_output_format)file.setFormatter(log_output_format)#把 螢幕和檔案 兩個handle 賦予給 loggerlogger.addHandler(screen)logger.addHandler(file)#使用logger手動組建記錄檔資訊logger.debug("debug is log!!")logger.info("info is log!!")logger.warn("warn is log!!")logger.error("error is log!!")logger.critical("critical is log!!")
經過多次設定 全域和工作域日誌 層級,實驗效果,得出結論:
1、當全域日誌低於工作域日誌,工作域日誌優先順序高;2、當全域日誌高於工作域日誌,全域日誌優先順序高;3、當工作域日誌沒有設定的時候,繼承全域日誌;4、當全域日誌沒有定義的時候,預設全域記錄層級為WARNING。
記錄檔自動切割:
import loggingfrom logging import handlers#建立一個logger執行個體對象logger = logging.getLogger(__name__)#定義自動產生的對象log_file = "testtesttest.log"#自動產生一:通過設定記錄檔大小 自動備份建立log檔案 如:log log.1 log.2#auto_split_file = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=2)#自動產生二:通過設定時間間隔 自動建立log檔案 如:testtesttest.log testtesttest.log.2018-01-24_14-49-47 testtesttest.log.2018-01-24_14-49-48auto_time_split_file = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=1,backupCount=2)#建立一個日誌輸出格式log_output_format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")#把日誌輸出格式 賦予給 自動組建記錄檔的 對象auto_time_split_file.setFormatter(log_output_format)#把 自動產生 handle 賦予給 loggerlogger.addHandler(auto_time_split_file)#使用logger手動組建記錄檔資訊logger.debug("debug is log!!")logger.info("info is log!!")logger.warn("warn is log!!")logger.error("error is log!!")logger.critical("critical is log!!")
python logging模組