python學習筆記9--日誌模塊logging

咱們在寫程序的時候常常會打一些日誌來幫助咱們查找問題,此次學習一下logging模塊,在python裏面如何操做日誌。
介紹一下logging模塊,logging模塊就是python裏面用來操做日誌的模塊,logging模塊中主要有4個類,分別負責不一樣的工做:python

Logger 記錄器,暴露了應用程序代碼能直接使用的接口;簡單點說就是一個建立一個辦公室,讓人在裏頭工做 函數

Handler 處理器,將(記錄器產生的)日誌記錄發送至合適的目的地;這個簡單點說就是辦事的人,你能夠指定是讓在控制輸出日誌,仍是在文件裏面打印日誌,經常使用的有4種: 佈局

                StreamHandler 控制檯輸出 學習

                FileHandler 文件輸出編碼

                下面兩種須要導入線程

                        handlers
                        from logging import handlers debug

                        TimedRotatingFileHandler 按照時間自動分割日誌文件 調試

                        RotatingFileHandler 按照大小自動分割日誌文件,一旦達到指定的大小從新生成文件 日誌

                Filter
過濾器,提供了更好的粒度控制,它能夠決定輸出哪些日誌記錄。(不經常使用) orm

                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級別,通常用來打印一些錯誤信息')
能夠指定日誌的輸出格式format,這個參數能夠輸出不少有用的信息,以下面的幾種格式:
%(levelno)s: 打印日誌級別的數值
 
 
%(levelname)s: 打印日誌級別名稱
 
 
%(pathname)s: 打印當前執行程序的路徑,其實就是sys.argv[0]
 
 
%(filename)s: 打印當前執行程序名
 
 
%(funcName)s: 打印日誌的當前函數
 
 
%(lineno)d: 打印日誌的當前行號
 
 
%(asctime)s: 打印日誌的時間
 
 
%(thread)d: 打印線程ID
 
 
%(threadName)s: 打印線程名稱
 
 
%(process)d: 打印進程ID
 
 
%(message)s: 打印日誌信息
 
 
我在工做中給的經常使用格式在前面已經看到了。就是:
format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
這個格式能夠輸出日誌的打印時間,是哪一個文件第幾行輸出的,輸出的日誌級別是什麼,以及輸入的日誌內容。

加上文件名以後就會發現控制檯不會輸出日誌了,日誌文件也產生了,那麼如何既在控制檯輸出日誌,也在文件中寫入呢?

 

 

怎麼實現呢,就得有個辦公室,裏面塞倆人,一個給負責往控制檯輸出日誌,一個負責寫文件,你把他倆往辦公室一塞,他倆就能幹活了。

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 Logger(object):
    level_relations = {
        'debug':logging.DEBUG,
        'info':logging.INFO,
        'warning':logging.WARN,
        'error':logging.ERROR,
        'crit':logging.CRITICAL
    }#日誌級別關係映射
    def __init__(self,fp,level='debug',when='midnight',interval=1,backCount=5,encoding='utf-8'):
        '''
 
        :param fp:日誌文件路徑
        :param level: 日誌級別 默認是debug
        :param when: 分割日誌的單位 S 秒、M 分、 H 小時、 D 天、 W 每星期(interval==0時表明星期一)、midnight 天天凌晨
        :param interval: 時間間隔 默認天天凌晨
        :param backCount: 備份文件個數 默認5個
        :param encoding: 日誌文件編碼
        '''
        self.level = self.level_relations.get(level)
        self.logger = logging.getLogger(fp)
        self.logger.setLevel(self.level)
        fmt = logging.Formatter('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
        sh = logging.StreamHandler()
        sh.setFormatter(fmt)
        sh.setLevel(self.level)
        th = handlers.TimedRotatingFileHandler(fp,when=when,interval=interval,backupCount=backCount,encoding=encoding)
        th.setFormatter(fmt)
        th.setLevel(self.level)
        self.logger.addHandler(th)
        self.logger.addHandler(sh)
    def debug(self,msg):
        self.logger.debug(msg)
    def info(self,msg):
        self.logger.info(msg)
    def warning(self,msg):
        self.logger.warning(msg)
    def error(self,msg):
        self.logger.error(msg)
    def crit(self,msg):
        self.logger.critical(msg)
if __name__ == '__main__':
    l = Logger('a.log')#實例化
    l.info('hehehe')#調用
相關文章
相關標籤/搜索