logging模塊

1、簡述

  不少程序都有記錄日誌的需求,而且日誌中包含的信息即有正常的程序訪問日誌,還可能有錯誤,警告等信息輸出,python的logging模塊提供了標準的日誌接口,你能夠經過它存儲各類格式的日誌,logging的日誌能夠分爲debug,info,warning,error和critical 5個級別,下面咱們就來看看這個日誌模塊logging怎麼用python

2、簡單用法

一、簡單用法網絡

說明:日誌級別有五個,分別是:debug,info,warning,error和critical,其中debug級別最低,critical級別最高,級別越低,打印的日誌等級越多。app

import logging
logging.debug("test debug")
logging.info("test info")
logging.warning("user [seven] attempted wrong password more than 3 times")
logging.error("test error")
logging.critical("server id down")

#輸出
ERROR:root:test error
WARNING:root:user [seven] attempted wrong password more than 3 times
CRITICAL:root:server id down

注:從上面能夠看出,一個模塊默認的日誌級別是warning函數

二、日誌級別工具

看一下這幾個日誌級別分別表明什麼意思,如表:ui

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.

三、日誌寫入文件spa

logging.basicConfig(filename="app.log",level=logging.INFO) #定義文件名和日誌輸出級別
logging.debug("test debug")
logging.info("test info")
logging.warning("user [seven] attempted wrong password more than 3 times")
logging.error("test error")
logging.critical("server id down")

#日誌內容
INFO:root:test info
WARNING:root:user [seven] attempted wrong password more than 3 times
ERROR:root:test error
CRITICAL:root:server id down

注: 這句中的level=loggin.INFO意思是,把日誌紀錄級別設置爲INFO,也就是說,只有比日誌是INFO或比INFO級別更高的日誌纔會被紀錄到文件裏,因此debug日誌沒有記錄,若是想記錄,則級別設置成debug也就是level=loggin.DEBUG線程

四、加入日期格式debug

說明:感受上面的日誌格式忘記加上時間啦,日誌不知道時間怎麼行呢,下面就來加上rest

logging.basicConfig(filename="app.log",
                    level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s',
                    datefmt="%m/%d/%Y %H:%M:%S %p") #須要加上format和datefmt
logging.debug("test debug")
logging.info("test info")
logging.warning("user [seven] attempted wrong password more than 3 times")
logging.error("test error")
logging.critical("server id down")

#日誌輸出
01/17/2018 17:49:05 PM INFO test info
01/17/2018 17:49:05 PM WARNING user [seven] attempted wrong password more than 3 times
01/17/2018 17:49:05 PM ERROR test error
01/17/2018 17:49:05 PM CRITICAL server id down

五、 format的日誌格式

%(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

用戶輸出的消息

 

3、複雜日誌輸出

  以前的寫法感受要麼就輸入在屏幕上,要麼就是輸入在日誌裏面,那咱們有沒有既能夠輸出在日誌上,又輸出在日誌裏面呢?很明顯,固然能夠。下面咱們就來討論一下,如何使用複雜的日誌輸出。

一、簡介

python使用logging模塊記錄日誌涉及的四個主要類:

①logger:提供了應用程序能夠直接使用的接口。

②handler:將(logger建立的)日誌記錄發送到合適的目的輸出。

③filter:提供了細度設備來決定輸出哪條日誌記錄。

④formatter:決定日誌記錄的最終輸出格式。

二、logger

①每一個程序在輸出信息以前都須要得到一個logger。logger一般對應了程序的模塊名,好比聊天工具的圖形界面模塊能夠這樣得到它的logger:

logger = logging.getLogger("chat.gui")

核心模塊能夠這樣寫:

logger = logging.getLogger("chat.kernel")

②logger.setLevel(lel)

說明:指定最低的日誌級別,低於lel的級別將被忽略(debug是最低的內置級別,critical爲最高)

logger.setLevel(logging.DEBUG)  #設置級別爲debug級別

③Logger.addFilter(filt)、Logger.removeFilter(filt)

說明:添加或刪除指定的filter

④logger.addHandler(hdlr)、logger.removeHandler(hdlr)

說明:增長或刪除指定的handler

logger.addHandler(ch)#添加handler
 
logger.removeHandler(ch) #刪除handler

⑤Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()

說明:能夠設置的日誌級別

logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

⑥獲取handler個數

handler_len = len(logger.handlers)
print(handler_len)
 
#輸出
1

三、hander

  handler對象負責發送相關的信息到指定目的地。Python的日誌系統有多種Handler可使用。有些Handler能夠把信息輸出到控制檯,有些Logger能夠把信息輸出到文件,還有些 Handler能夠把信息發送到網絡上。若是以爲不夠用,還能夠編寫本身的Handler。能夠經過addHandler()方法添加多個多handler 。

①Handler.setLevel(lel)

說明:指定被處理的信息級別,低於lel級別的信息將被忽略。

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

②Handler.setFormatter()

說明:給這個handler選擇一個格式

ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") #生成格式
 
ch.setFormatter(ch_formatter) #設置格式

③Handler.addFilter(filt)、Handler.removeFilter(filt)

說明:新增或刪除一個filter對象

4、handler詳解

一、logging.StreamHandler

說明:使用這個Handler能夠向相似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息,也就是屏幕輸出。

它的構造函數是:StreamHandler([strm]),其中strm參數是一個文件對象,默認是sys.stderr。

import logging
 
logger = logging.getLogger("TEST-LOG")
logger.setLevel(logging.DEBUG)
 
ch = logging.StreamHandler() #建立一個StreamHandler對象
ch.setLevel(logging.DEBUG) #設置輸出StreamHandler日誌級別
 
ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch.setFormatter(ch_formatter)  #設置時間格式
logger.addHandler(ch)
 
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
 
#輸出
2017-04-11 16:42:49,764 - TEST-LOG - DEBUG - debug message
2017-04-11 16:42:49,764 - TEST-LOG - INFO - info message
2017-04-11 16:42:49,764 - TEST-LOG - WARNING - warn message
2017-04-11 16:42:49,765 - TEST-LOG - ERROR - error message
2017-04-11 16:42:49,765 - TEST-LOG - CRITICAL - critical message

二、logging.FileHandler

說明:和StreamHandler相似,用於向一個文件輸出日誌信息,不過FileHandler會幫你打開這個文件。

它的構造函數是:FileHandler(filename[,mode])。filename是文件名,必須指定一個文件名。mode是文件的打開方式。參見Python內置函數open()的用法。默認是’a',即添加到文件末尾。

import logging
 
#create logging
logger = logging.getLogger("TEST-LOG")
logger.setLevel(logging.DEBUG)
 
fh = logging.FileHandler("debug.log",encoding="utf-8") #日誌輸出到debug.log文件中
fh.setLevel(logging.INFO) #設置FileHandler日誌級別
 
fh_formatter = logging.Formatter("%(asctime)s %(module)s:%(levelname)s %(message)s")
 
fh.setFormatter(fh_formatter)
 
logger.addHandler(fh)
 
# 'application' code
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
 
#輸出到文件中
2017-04-11 17:09:50,035 logging_screen_output:INFO info message
2017-04-11 17:09:50,035 logging_screen_output:WARNING warn message
2017-04-11 17:09:50,035 logging_screen_output:ERROR error message
2017-04-11 17:09:50,035 logging_screen_output:CRITICAL critical message

三、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並不會被改名,而是被刪除。

import logging
from logging import handlers #須要導入handlers

logger = logging.getLogger("Test")
log_file = "timelog.log"

# 按文件大小來分割,10個字節,保留個數是3個
fh = handlers.RotatingFileHandler(filename=log_file, maxBytes=10, backupCount=3,encoding="utf-8")
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")
logger.warning("test15")
logger.warning("test16")

四、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
from logging import handlers
import time

logger = logging.getLogger("test")
log_file = "timelog.log"
# 按時間來分割文件,按5秒一次分割,保留日誌個數是3個
fh = handlers.TimedRotatingFileHandler(filename=log_file, when="S", interval=5, backupCount=3,encoding="utf-8")
formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.warning("test1")
time.sleep(2)
logger.warning("test12")
time.sleep(2)
logger.warning("test13")
time.sleep(2)
logger.warning("test14")
logger.warning("test15")

5、控制檯和文件日誌共同輸出

須要什麼樣的輸出,只須要添加相應的handler就ok了。

一、邏輯圖

二、代碼以下

import logging
 
#create logging
logger = logging.getLogger("TEST-LOG")
logger.setLevel(logging.DEBUG)
 
#屏幕handler
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
 
#文件handler
fh = logging.FileHandler("debug.log",encoding="utf-8")
fh.setLevel(logging.INFO)
#分別建立輸出日誌格式
ch_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh_formatter = logging.Formatter("%(asctime)s %(module)s:%(levelname)s %(message)s")
#設置handler的輸出格式
ch.setFormatter(ch_formatter)
fh.setFormatter(fh_formatter)
#添加handler
logger.addHandler(ch)
logger.addHandler(fh)
 
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

 注:若是添加時間分割或者文件大小分割,再添加handler便可。添加方式請見第4節中的三、4點。

相關文章
相關標籤/搜索