我們在寫程序的時候經常會打一些日志來幫助我們查找問題,這次學習一下logging模塊,在python里面如何操作日志。
介紹一下logging模塊,logging模塊就是python里面用來操作日志的模塊,logging模塊中主要有4個類,分別負責不同的工作:
Logger 記錄器,暴露了應用程序代碼能直接使用的接口;簡單點說就是一個創建一個辦公室,讓人在里頭工作?
Handler 處理器,將(記錄器產生的)日志記錄發送至合適的目的地;這個簡單點說就是辦事的人,你可以指定是讓在控制輸出日志,還是在文件里面打印日志,常用的有4種:?
????????????????StreamHandler 控制臺輸出?
????????????????FileHandler 文件輸出
????????????????下面兩種需要導入
? ? ? ? ? ? ? ? ? ? ? ? handlers
? ? ? ? ? ? ? ? ? ? ? ? from logging import handlers?
? ? ? ? ? ? ? ? ? ? ? ? TimedRotatingFileHandler 按照時間自動分割日志文件?
? ? ? ? ? ? ? ? ? ? ? ? RotatingFileHandler 按照大小自動分割日志文件,一旦達到指定的大小重新生成文件?
? ? ? ? ? ? ? ? ? ? ? ? Filter過濾器,提供了更好的粒度控制,它可以決定輸出哪些日志記錄。(不常用)?
? ? ? ? ? ? ? ? ? ? ? ? Formatter格式化器,指明了最終輸出中日志記錄的布局。指定輸出日志的格式
import logging from logging import handlers #只在控制臺打印日志 logging.basicConfig(level=logging.ERROR,#控制臺打印的日志級別format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'#日志格式) logging.debug('debug級別,最低級別,一般開發人員用來打印一些調試信息') logging.info('info級別,正常輸出信息,一般用來打印一些正常的操作') logging.warning('waring級別,一般用來打印警信息') logging.error('error級別,一般用來打印一些錯誤信息') logging.critical('critical級別,一般用來打印一些致命的錯誤信息')
日志級別 debug < info < warning < error < critical
設置了日志級別之后,會打印該級別以及比該級別高的所有日志,舉個例子,如果日志級別是warning,那么就會打印warning、error、critical,這三個級別的日志,不會打印debug和info級別的,如果是debug,最低級別的日志,那么所有的日志都會打印。
上面的只是在控制臺打印日志,并沒有把日志寫在文件里面,一般我們都會把日志寫在日志文件里面,也很簡單,只需要加個參數指定文件名就行了。
logging.basicConfig(level=logging.ERROR,#控制臺打印的日志級別filename='log.txt',#文件名filemode='a',#模式,有w和a,w就是寫模式,每次都會重新寫日志,覆蓋之前的日志#a是追加模式,默認如果不寫的話,就是追加模式format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'#工作中常用的日志格式) logging.debug('debug級別,最低級別,一般開發人員用來打印一些調試信息') logging.info('info級別,正常輸出信息,一般用來打印一些正常的操作') logging.warning('waring級別,一般用來打印警信息') logging.error('error級別,一般用來打印一些錯誤信息') logging.critical('critical級別,一般用來打印一些致命的錯誤信息')
加上文件名之后就會發現控制臺不會輸出日志了,日志文件也產生了,那么如何既在控制臺輸出日志,也在文件中寫入呢?
怎么實現呢,就得有個辦公室,里面塞倆人,一個給負責往控制臺輸出日志,一個負責寫文件,你把他倆往辦公室一塞,他倆就能干活了。
import logging from logging import handlers logger = logging.getLogger('my_log') #先創建一個logger對象,相當于這個辦公室,也就是上面說的Logger logger.setLevel(logging.INFO)#設置日志的總級別 fh = logging.FileHandler('test.log',mode='a',encoding='utf-8')#創建一個文件處理器,也就是把日志寫到文件里頭 fh.setLevel(logging.INFO)#設置文件輸出的級別 sh = logging.StreamHandler()#創建一個控制臺輸出的處理器,這兩個就是上面說的Handler sh.setLevel(logging.INFO) #設置控制臺輸出的日志級別,這兩個級別都可以單獨設置,他們倆和logger的級別區別是如果logger設置的級別比里面的handler級別設置的高,那么就以logger的級別為準 th = handlers.TimedRotatingFileHandler('time',when='S',interval=1,backupCount=2) #指定間隔時間自動生成文件的處理器 #interval是時間間隔,backupCount是備份文件的個數,如果超過這個超過這個個數,就會自動刪除,when是間隔的時間單位,單位有以下幾種:# S 秒# M 分# H 小時、# D 天、# W 每星期(interval==0時代表星期一)# midnight 每天凌晨 th.setLevel(logging.INFO) formater = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') #指定日志格式,上面咱們寫了常用的格式,直接指定了就行了,這也就是咱們上面說的Formatter sh.setFormatter(formater) fh.setFormatter(formater) th.setFormatter(formater) #設置兩個處理器的日志格式logger.addHandler(sh) logger.addHandler(fh) logger.addHandler(th) #把兩個handler加入容器里頭,相當于把工作人員培訓完了,你們可以上班了 logger.debug('debug級別,最低級別,一般開發人員用來打印一些調試信息') logger.info('info級別,正常輸出信息,一般用來打印一些正常的操作') logger.warning('waring級別,一般用來打印警信息') logger.error('error級別,一般用來打印一些錯誤信息') logger.critical('critical級別,一般用來打印一些致命的錯誤信息')
這樣logger這個日志辦公室已經搞好了,咱們就可以直接用了,運行完發現文件也產生了,控制臺也有日志。如果不設置日志級別的話,默認級別是waring。
下面我們自己封裝一個類來使用logging模塊,方便使用,默認加一些配置
import logging from logging import handlers class MyLogger():def __init__(self,file_name,level='info',backCount=5,when='M'):logger = logging.getLogger() # 先實例化一個logger對象,先創建一個辦公室logger.setLevel(self.get_level(level)) # 設置日志的級別的人cl = logging.StreamHandler() # 負責往控制臺輸出的人bl = handlers.TimedRotatingFileHandler(filename=file_name, when=when, interval=1, backupCount=backCount, encoding='utf-8')fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s') #時間 #打印哪個python文件的第幾行 #日志級別 #打印的信息cl.setFormatter(fmt) # 設置控制臺輸出的日志格式bl.setFormatter(fmt) # 設置文件里面寫入的日志格式logger.addHandler(cl)logger.addHandler(bl)self.logger = loggerdef get_level(self,str):level = {'debug':logging.DEBUG,'info':logging.INFO,'warn':logging.WARNING,'error':logging.ERROR}str = str.lower()return level.get(str) if __name__ == '__main__':lw_log = MyLogger('lw.log','debug',when='M')lw_log.logger.warning('哈哈哈')
由于logging模塊用起來實在是費勁,所以牛教授自己封裝了一個日志模塊供大家使用,非常方便,只需要直接pip install nnlog即可
使用例子如下代碼:
import nnlog log = nnlog.Logger(file_name='my.log',level='debug',when='D',backCount=5,interval=1) #file_name是日志文件名 #level是日志級別,如果不傳的話默認是debug級別 #when是日志文件多久生成一個,默認是按天,S 秒、M 分、 H 小時、 D 天、 W 每星期 #backCount是備份幾個日志文件,默認保留5天的 #interval是間隔多久生成一個日志文件,默認是1天 log.debug('默認日志級別是debug') log.info('info級別') log.warning('waring級別') log.error('error級別')log2 = nnlog.Logger(file_name='nn.log') #直接傳入文件名也是ok的,其他的就取默認值了 log2.debug('test')
?