標籤:而且 bug 日誌記錄 何事 def root copy 控制 時間格式
本文出處:https://www.cnblogs.com/goodhacker/p/3355660.html#undefined
python的標準庫裡的日誌系統從Python2.3開始支援。只要import logging這個模組即可使用。如果你想開發一個日誌系統, 既要把日誌輸出到控制台, 還要寫入記錄檔,只要這樣使用:
1 import logging 2 3 # 建立一個logger 4 logger = logging.getLogger(‘mylogger‘) 5 logger.setLevel(logging.DEBUG) 6 7 # 建立一個handler,用於寫入記錄檔 8 fh = logging.FileHandler(‘test.log‘) 9 fh.setLevel(logging.DEBUG)10 11 # 再建立一個handler,用於輸出到控制台12 ch = logging.StreamHandler()13 ch.setLevel(logging.DEBUG)14 15 # 定義handler的輸出格式16 formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)17 fh.setFormatter(formatter)18 ch.setFormatter(formatter)19 20 # 給logger添加handler21 logger.addHandler(fh)22 logger.addHandler(ch)23 24 # 記錄一條日誌25 logger.info(‘foorbar‘)
結合上面的例子,我們說下幾個最常使用的API:
logging.getLogger([name])
返回一個logger執行個體,如果沒有指定name,返回root logger。只要name相同,返回的logger執行個體都是同一個而且只有一個,即name和logger執行個體是一一對應的。這意味著,無需把logger執行個體在各個模組中傳遞。只要知道name,就能得到同一個logger執行個體。
Logger.setLevel(lvl)
設定logger的level, level有以下幾個層級:
層級高低順序:NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
如果把looger的層級設定為INFO, 那麼小於INFO層級的日誌都不輸出, 大於等於INFO層級的日誌都輸出
1 logger.debug("foobar") # 不輸出 2 logger.info("foobar") # 輸出 3 logger.warning("foobar") # 輸出 4 logger.error("foobar") # 輸出 5 logger.critical("foobar") # 輸出
Logger.addHandler(hdlr)
通過handler對象可以把日誌內容寫到不同的地方。比如簡單的StreamHandler就是把日誌寫到類似檔案的地方。python提供了十幾種實用handler,比較常用有:
1 StreamHandler: 輸出到控制台2 FileHandler: 輸出到檔案3 BaseRotatingHandler 可以按時間寫入到不同的日誌中。比如將日誌按天寫入不同的日期結尾的檔案檔案。4 SocketHandler 用TCP網路連接寫LOG5 DatagramHandler 用UDP網路連接寫LOG6 SMTPHandler 把LOG寫成EMAIL郵寄出去
logging.basicConfig([**kwargs])* 這個函數用來配置root logger, 為root logger建立一個StreamHandler,設定預設的格式。* 這些函數: logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical() 如果調用的時候發現root logger沒有任何handler,會自動調用basicConfig添加一個handler* 如果root logger已有handler,這個函數不做任何事情使用basicConfig來配置root logger的輸出格式和level:
1 import logging2 logging.basicConfig(format=‘%(levelname)s:%(message)s‘, level=logging.DEBUG)3 logging.debug(‘This message should appear on the console‘)
logger對象直接提供日誌介面。formatter描述日誌的格式。handler把日誌寫到不同的地方,你可以把日誌儲存成本地檔案,也可以每個小時寫一個記錄檔,還可以把日誌通過socket傳到別的機器上。
從最簡單的formatter對象來看。formatter指定的是每一條日誌記錄的抬頭資訊,也就是你可以指定日誌記錄的時間格式、進程號、檔案名稱、函數名等資訊。可以用這個方法來建立一個formatter對象:
logging.Formatter.__init__( fmt=None, datefmt=None)
fmt參數指定進程號、檔案名稱、函數名等資訊是否出現以及格式, datefmt為日期時間格式,預設的日期格式精確到微秒,例如‘2003-07-08 16:49:45,896’。fmt中可以指定多個欄位,每個欄位的格式為“%(<dictionary key>)s”, 例如你想列印時間、記錄層級、日誌資訊可以用下面的format:
‘%(asctime)s - %(levelname)s - %(message)s‘
所有的可以使用的欄位如下表:
在記錄爬蟲系統日誌的時候需要定義記錄日誌的層級,層級越高表示打出來的日誌越詳細。我們可以用一個字典來設定不同層級對應的不同日誌資訊:
1 #用字典儲存記錄層級2 format_dict = {3 1 : logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘),4 2 : logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘),5 3 : logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘),6 4 : logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘),7 5 : logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)8 }
將本文開始的代碼封裝在一個類中
1 #開發一個日誌系統, 既要把日誌輸出到控制台, 還要寫入記錄檔 2 class Logger(): 3 def __init__(self, logname, loglevel, logger): 4 ‘‘‘ 5 指定儲存日誌的檔案路徑,記錄層級,以及調用檔案 6 將日誌存入到指定的檔案中 7 ‘‘‘ 8 9 # 建立一個logger10 self.logger = logging.getLogger(logger)11 self.logger.setLevel(logging.DEBUG)12 13 # 建立一個handler,用於寫入記錄檔14 fh = logging.FileHandler(logname)15 fh.setLevel(logging.DEBUG)16 17 # 再建立一個handler,用於輸出到控制台18 ch = logging.StreamHandler()19 ch.setLevel(logging.DEBUG)20 21 # 定義handler的輸出格式22 #formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)23 formatter = format_dict[int(loglevel)]24 fh.setFormatter(formatter)25 ch.setFormatter(formatter)26 27 # 給logger添加handler28 self.logger.addHandler(fh)29 self.logger.addHandler(ch)30 31 32 def getlog(self):33 return self.logger
再通過以下方式調用,便是一個簡單的日誌系統了
logger = Logger(logname=‘log.txt‘, loglevel=1, logger="fox").getlog()
python 標準日誌模組loging 及日誌系統執行個體