標籤:imp 無限 byte err run 直接 wro sys 使用
logging模組
很多程式都有記錄日誌的需求,並且日誌中包含的資訊即有正常的程式訪問日誌,還可能有錯誤、警告等資訊輸出,python的logging模組提供了標準的日誌介面,你可以通過它儲存各種格式的日誌,logging的日誌可以分為 debug(), info(), warning(), error() and critical() 5個層級,下面我們看一下怎麼用。
最簡單用法
| 12345678 |
import logging logging.warning("user [alex] attempted wrong password more than 3 times")logging.critical("server is down") #輸出WARNING:root:user [alex] attempted wrong password more than 3 timesCRITICAL:root:server is down |
看一下這幾個記錄層級分別代表什麼意思
| Level |
When it’s used |
DEBUG |
Detailed information, typically of interest only when diagnosing problems. |
INFO |
Confirmation that things are working as expected. |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. |
如果想把日誌寫到檔案裡,也很簡單
| 123456 |
import logging logging.basicConfig(filename=‘example.log‘,level=logging.INFO)logging.debug(‘This message should go to the log file‘)logging.info(‘So should this‘)logging.warning(‘And this, too‘) |
其中下面這句中的level=loggin.INFO意思是,把日誌紀錄層級設定為INFO,也就是說,只有比日誌是INFO或比INFO層級更高的日誌才會被紀錄到檔案裡,在這個例子, 第一條日誌是不會被紀錄的,如果希望紀錄debug的日誌,那把記錄層級改成DEBUG就行了。
| 1 |
logging.basicConfig(filename=‘example.log‘,level=logging.INFO) |
感覺上面的日誌格式忘記加上時間啦,日誌不知道時間怎麼行呢,下面就來加上!
| 123456 |
import logginglogging.basicConfig(format=‘%(asctime)s %(message)s‘, datefmt=‘%m/%d/%Y %I:%M:%S %p‘)logging.warning(‘is when this event was logged.‘) #輸出12/12/2010 11:46:36 AM is when this event was logged. |
日誌格式
%(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):添加或刪除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或刪除指定的handler
Logger.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.stderr
2) 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 每天淩晨
| 12345678910111213141516171819202122232425262728293031 |
import logging #create loggerlogger = logging.getLogger(‘TEST-LOG‘)logger.setLevel(logging.DEBUG) # create console handler and set level to debugch = logging.StreamHandler()ch.setLevel(logging.DEBUG) # create file handler and set level to warningfh = logging.FileHandler("access.log")fh.setLevel(logging.WARNING)# create formatterformatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) # add formatter to ch and fhch.setFormatter(formatter)fh.setFormatter(formatter) # add ch and fh to loggerlogger.addHandler(ch)logger.addHandler(fh) # ‘application‘ codelogger.debug(‘debug message‘)logger.info(‘info message‘)logger.warn(‘warn message‘)logger.error(‘error message‘)logger.critical(‘critical message‘) |
檔案自動截斷例子
import loggingfrom logging import handlerslogger = logging.getLogger(__name__)log_file = "timelog.log"#fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)formatter = logging.Formatter(‘%(asctime)s %(module)s:%(lineno)d %(message)s‘)fh.setFormatter(formatter)logger.addHandler(fh)logger.warning("test1")logger.warning("test12")logger.warning("test13")logger.warning("test14")
python logging 模組