1、簡介python
python的logging模塊提供了通用的日誌系統,能夠方便第三方模塊或者是應用使用。這個模塊提供不一樣的日誌級別,並能夠採用不一樣的方式記錄日誌,好比文件,HTTP GET/POST,SMTP,Socket等,甚至能夠本身實現具體的日誌記錄方式。網絡
logging模塊與log4j的機制是同樣的,只是具體的實現細節不一樣。模塊提供logger,handler,filter,formatter。app
logger:提供日誌接口,供應用代碼使用。logger最長用的操做有兩類:配置和發送日誌消息。能夠經過logging.getLogger(name)獲取logger對象,若是不指定name則返回root對象,屢次使用相同的name調用getLogger方法返回同一個logger對象。socket
handler:將日誌記錄(log record)發送到合適的目的地(destination),好比文件,socket等。一個logger對象能夠經過addHandler方法添加0到多個handler,每一個handler又能夠定義不一樣日誌級別,以實現日誌分級過濾顯示。函數
filter:提供一種優雅的方式決定一個日誌記錄是否發送到handler。spa
formatter:指定日誌記錄輸出的具體格式。formatter的構造方法須要兩個參數:消息的格式字符串和日期字符串,這兩個參數都是可選的。debug
與log4j相似,logger,handler和日誌消息的調用能夠有具體的日誌級別(Level),只有在日誌消息的級別大於logger和handler的級別。日誌
logging的日誌能夠分爲debug(),info(),warning(),error() 和 critical()5個級別。orm
2、用法server
2.1 初識
logging的5個日誌級別debug最低,critical高,日誌級別越低輸出的信息就越詳細。
import logging logging.debug("This is debug info") logging.info("This is info infomation") logging.warning("user [bigberg] attempted wrong password more than 3 times") logging.error("This is error info") logging.critical("server is down") #輸出日誌 WARNING:root:user [bigberg] attempted wrong password more than 3 times ERROR:root:This is error info CRITICAL:root:server is down
能夠看出python中默認的日誌輸出級別爲 warning(),低於warning()級別如下的就輸出了。
2.2 日誌級別
2.3 將日誌寫入文件
import logging logging.basicConfig(filename="../log/test.log",level=logging.DEBUG) # 定義文件和日誌級別 logging.debug("This is debug info") logging.info("This is info infomation") logging.warning("user [bigberg] attempted wrong password more than 3 times") logging.error("This is error info") logging.critical("server is down")
能夠看到日誌已經寫到test.log的文件中了,咱們在此選擇的日子級別是DEBUG,因此全部的日子信息都會保存到日誌文件中。若是選擇選擇WARNING級別那麼其如下的級別日誌信息就不會寫入。並且日誌是以追加的形式寫入test.log文件中的。
2.4 爲日誌信息增長時間
import logging logging.basicConfig(filename="../log/test.log", level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s ', datefmt='%Y/%m/%d %H:%M:%S') logging.debug("This is debug info") logging.info("This is info infomation") logging.warning("user [bigberg] attempted wrong password more than 3 times") logging.error("This is error info") logging.critical("server is down") # %(asctime)s 設置時間格式 # %(levelname)s 日誌級別 # %(message)s 日誌信息 ###日誌輸出 2017/04/20 18:54:46 INFO: This is info infomation 2017/04/20 18:54:46 WARNING: user [bigberg] attempted wrong password more than 3 times 2017/04/20 18:54:46 ERROR: This is error info 2017/04/20 18:54:46 CRITICAL: server is down
2.5 format日誌格式
咱們能夠根據本身的需求在format中添加本身須要的功能,好比在日誌輸出中添加出錯的文件名和所在的行數。
3、複雜日誌輸出
Python 使用logging模塊記錄日誌涉及四個主要類,使用官方文檔中的歸納最爲合適:
3.1 logger
3.2 handler
handler對象負責發送相關的信息到指定目的地。Python的日誌系統有多種Handler可使用。有些Handler能夠把信息輸出到控制檯,有些Logger能夠把信息輸出到文件,還有些 Handler能夠把信息發送到網絡上。若是以爲不夠用,還能夠編寫本身的Handler。能夠經過addHandler()方法添加多個多handler。
每一個Logger能夠附加多個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',即添加到文件末尾。
同時分別向屏幕和文件輸出日誌:
import logging logger = logging.getLogger("TEST-LOG") logger.setLevel(logging.DEBUG) # StreamHandler ch = logging.StreamHandler() ch.setLevel(logging.WARNING) # 能夠在handler中設置具體的日子級別 # FileHandler fh = logging.FileHandler("../log/handler.log", encoding="utf-8") fh.setLevel(logging.ERROR) # Formatter ch_formatter = logging.Formatter("%(asctime)s %(filename)s-%(lineno)d %(levelname)s:%(message)s", datefmt='%Y/%m/%d %H:%M:%S') fh_formatter = logging.Formatter('%(asctime)s %(filename)s-%(lineno)d %(levelname)s: %(message)s', datefmt='%Y/%m/%d %H:%M:%S') ch.setFormatter(ch_formatter) fh.setFormatter(fh_formatter) logger.addHandler(ch) logger.addHandler(fh) logger.debug("This is debug info") logger.info("This is info infomation") logger.warning("user [bigberg] attempted wrong password more than 3 times") logger.error("This is error info") logger.critical("server is down")
屏幕輸出:
文件輸出:
3.3 日誌文件截斷
1.按文件大小截斷日誌
logging.handler.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 logger = logging.getLogger("Test-log") log_file = "../log/rotaing.log" # 設置日誌文件大小在100B時截斷 # 最多保留3個日誌文件 fh = handlers.RotatingFileHandler(filename=log_file, maxBytes=100, backupCount=3, encoding="utf-8") formatter = logging.Formatter('%(asctime)s %(filename)s-%(lineno)d %(levelname)s: %(message)s', datefmt='%Y/%m/%d %H:%M:%S') fh.setFormatter(formatter) logger.addHandler(fh) logger.warning("test1") logger.warning("test2") logger.warning("test3") logger.warning("test4") logger.warning("test5")
輸出的日誌文件:
2.按日期截斷
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 time import logging from logging import handlers logger = logging.getLogger("test-log") log_file = "../log/time_rotating.log" # S 表明秒 # interval 間隔時間 # 保留文件3個 fh = handlers.TimedRotatingFileHandler(filename=log_file, when="S", interval=3, backupCount=3, encoding="utf-8") fh.setLevel(logging.WARNING) formatter = logging.Formatter('%(asctime)s %(filename)s-%(lineno)d %(levelname)s: %(message)s', datefmt='%Y/%m/%d %H:%M:%S') fh.setFormatter(formatter) logger.addHandler(fh) logger.warning("test1") logger.warning("test12") time.sleep(3) logger.warning("test13") logger.warning("test14")
日誌文件輸出: