Python日誌模塊logging

官方文檔:html

https://docs.python.org/2/library/logging.htmlpython

logging模塊提供了兩種記錄日誌的方式:程序員

  • 第一種方式是使用logging提供的模塊級別的函數
  • 第二種方式是使用Logging日誌系統的四大組件

其實,logging所提供的模塊級別的日誌記錄函數也是對logging日誌系統相關類的封裝而已。網絡

logging模塊定義的模塊級別的經常使用函數:app

函數 說明
logging.debug(msg, *args, **kwargs) 建立一條嚴重級別爲DEBUG的日誌記錄
logging.info(msg, *args, **kwargs) 建立一條嚴重級別爲INFO的日誌記錄
logging.warning(msg, *args, **kwargs) 建立一條嚴重級別爲WARNING的日誌記錄
logging.error(msg, *args, **kwargs) 建立一條嚴重級別爲ERROR的日誌記錄
logging.critical(msg, *args, **kwargs) 建立一條嚴重級別爲CRITICAL的日誌記錄
logging.log(level, *args, **kwargs) 建立一條嚴重級別爲level的日誌記錄
logging.basicConfig(**kwargs) 對root logger進行一次性配置

 

 

 

 

 

 

 

 

 

 

其中logging.basicConfig(**kwargs)函數用於指定「要記錄的日誌級別」、「日誌格式」、「日誌輸出位置」、「日誌文件的打開模式」等信息,其餘幾個都是用於記錄各個級別日誌的函數。socket

具體以下:函數

參數名稱性能

描述測試

filenamethis

將日誌信息寫入文件中,指定該設置項後日志信息就不會被輸出到控制檯了

filemode

指定日誌文件的打開模式,默認爲'a'。須要注意的是,該選項要在filename指定時纔有效

format

指定日誌格式字符串,即指定日誌輸出時所包含的字段信息以及它們的順序。logging模塊定義的格式字段下面會列出。

datefmt

指定日期/時間格式。須要注意的是,該選項要在format中包含時間字段%(asctime)s時纔有效。

level

指定日誌級別

stream

指定日誌輸出目標stream,如sys.stdout、sys.stderr以及網絡stream。須要說明的是,stream和filename不能同時提供,不然會引起 ValueError異常

style

Python 3.2中新添加的配置項。指定format格式字符串的風格,可取值爲'%'、'{'和'$',默認爲'%'

handlers

Python 3.3中新添加的配置項。該選項若是被指定,它應該是一個建立了多個Handler的可迭代對象,這些handler將會被添加到root logger。須要說明的是:filename、stream和handlers這三個配置項只能有一個存在,不能同時出現2個或3個,不然會引起ValueError異常。

 



 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

上面的時間須要使用format中包含時間段,過於format還有以下參數:

字段/屬性名稱

使用格式

描述

asctime

%(asctime)s

日誌事件發生的時間--人類可讀時間,如:2003-07-08 16:49:45,896

created

%(created)f

日誌事件發生的時間--時間戳,就是當時調用time.time()函數返回的值

relativeCreated

%(relativeCreated)d

日誌事件發生的時間相對於logging模塊加載時間的相對毫秒數(目前還不知道幹嗎用的)

msecs

%(msecs)d

日誌事件發生事件的毫秒部分

levelname

%(levelname)s

該日誌記錄的文字形式的日誌級別('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')

levelno

%(levelno)s

該日誌記錄的數字形式的日誌級別(10, 20, 30, 40, 50)

name

%(name)s

所使用的日誌器名稱,默認是'root',由於默認使用的是 rootLogger

message

%(message)s

日誌記錄的文本內容,經過 msg % args計算獲得的

pathname

%(pathname)s

調用日誌記錄函數的源碼文件的全路徑

filename

%(filename)s

pathname的文件名部分,包含文件後綴

module

%(module)s

filename的名稱部分,不包含後綴

lineno

%(lineno)d

調用日誌記錄函數的源代碼所在的行號

funcName

%(funcName)s

調用日誌記錄函數的函數名

process

%(process)d

進程ID

processName

%(processName)s

進程名稱,Python 3.1新增

thread

%(thread)d

線程ID

threadName

%(thread)s

線程名稱

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1、使用logging提供的模塊級別的函數記錄日誌

  • 能夠經過logging模塊定義的模塊級別的方法去完成簡單的日誌記錄
  • 只有級別大於或等於日誌記錄器指定級別的日誌記錄纔會被輸出,小於該級別的日誌記錄將會被丟棄。

logging的日誌級別由低到高分爲 debug(), info(), warning(), error() and critical() 5個級別

CRITICAL(50) > ERROR(40) > WARNING(30) > INFO(20) > DEBUG(10)

簡單使用示例:

import logging logging.basicConfig(filename="E:\\logging\\abc.log", format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %I:%M:%S %p', level=logging.WARNING) logger = logging.getLogger()
logger.debug(
"The debug.") logger.info("The info.") logger.warning("The warning.") logger.error("The error.") logger.critical("The critical.") print(logger.level)

運行結果:

查看E:\\logging\\abc.log文件中的內容,以下:

能夠看到,因爲設置的日誌級別爲WARNING,因此只打印了比WARNING級別更高的日誌。

2、使用logging四大組件記錄日誌

logging模塊的四大組件:
logger:提供日誌接口,供應用代碼使用。logger最長用的操做有兩類:配置和發送日誌消息。能夠經過logging.getLogger(name)獲取logger對象,
若是不指定name則返回root對象,屢次使用相同的name調用getLogger方法返回同一個logger對象 handler:將日誌記錄(log record)發送到合適的目的地(destination),好比文件,socket等。一個logger對象能夠經過addHandler方法添加多個handler,
每一個handler又能夠定義不一樣日誌級別,以實現日誌分級過濾顯示 filter:提供方式決定一個日誌記錄是否發送到handler formatter:指定日誌記錄輸出的具體格式。formatter的構造方法須要兩個參數:消息的格式字符串和日期字符串,這兩個參數都是可選的

如上面所說,logging.basicConfig()函數中可經過具體參數來更改logging模塊的行爲

日誌同時打印到屏幕和文件:

import logging # 建立一個日誌對象
logg = logging.getLogger("測試日誌") # 定義一個模板
FORMATTER = logging.Formatter("%(asctime)s - %(name)s - [%(lineno)d] - %(message)s") # 建立一個屏幕流
p_stream = logging.StreamHandler() # 建立一個文件流
f_stream = logging.FileHandler("log.log", mode="a", encoding="utf-8") # 將流綁定到模板
p_stream.setFormatter(FORMATTER) f_stream.setFormatter(FORMATTER) # 將日誌和流進行綁定
logg.addHandler(p_stream) logg.addHandler(f_stream) # 設置日誌記錄等級
logg.setLevel(logging.DEBUG) # 打印日誌信息
logg.debug("this is Debug") logg.info("this is info") logg.warning("this is warning") logg.error("this is error") logg.critical("this is critical")

運行結果:

若是想爲多個用戶建立不一樣的日誌,只須要建立流時建立不一樣的流便可,而不須要建立多個日誌對象,若是狀況特殊考慮單獨在建立一個對象。其實咱們能夠在建立流的時候直接指定日誌等級。流的等級是優先於日誌對象的。

以下建立兩個流:

import logging # 建立一個日誌對象
logg = logging.getLogger("測試日誌") # 建立一個程序員模板和老闆模板
CORE_FORMATTER = logging.Formatter("%(asctime)s - %(name)s - [%(lineno)d] - %(message)s") BOOS_FORMATTER = logging.Formatter("%(asctime)s - %(message)s") # 建立一個程序員的流和一個老闆的流
core_stream = logging.FileHandler("core.log", mode="a", encoding="utf-8") boos_stream = logging.FileHandler("boos.log", mode="a", encoding="utf-8") # 設置日誌等級(老闆的日誌等級設置WARNING)
boos_stream.setLevel(logging.WARNING) # 將流綁定到模板
core_stream.setFormatter(CORE_FORMATTER) boos_stream.setFormatter(BOOS_FORMATTER) # 將日誌和流進行綁定
logg.addHandler(core_stream) logg.addHandler(boos_stream) # 設置日誌記錄等級
logg.setLevel(logging.DEBUG) # 打印日誌信息
logg.debug("this is Debug") logg.info("this is info") logg.warning("this is warning") logg.error("this is error") logg.critical("this is critical")

運行結果:

這樣咱們便建立了兩種不一樣的日誌

、日誌分割

將日誌信息輸出到一個單一的文件中,隨着應用程序的持續使用,該日誌文件會愈來愈龐大,進而影響系統的性能。所以,有必要對日誌文件按某種條件進行切分。

分割日誌的觸發條件:大小、日期,或者大小加上日期。

說是切分,其實是,當一個日誌文件達到觸發條件後,對日誌文件進行重命名,以後再新建原來名稱的日誌文件(此時就是空文件了),新產生的日誌就寫入新的日誌文件。

爲啥叫回滾呢?當分割的日誌文件達到指定數目的上限個數時,最老的日誌文件就會被刪除。

logging庫提供了2個能夠用於日誌滾動的class,一個是RotatingFileHandler,它主要是根據日誌文件的大小進行滾動;另外一個是TimeRotatingFileHandler,它主要是根據時間進行滾動。在實際應用中,一般根據時間進行滾動。 

TimedRotatingFileHandler的構造函數定義以下:

TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]]) filename 是輸出日誌文件名的前綴,好比log/myapp.log when 的定義以下: 「S」: Seconds 「M」: Minutes 「H」: Hours 「D」: Days 「W」: Week day (0=Monday) 「midnight」: Roll over at midnight interval:指等待多少個單位when的時間後,Logger會自動重建文件,固然,這個文件的建立取決於filename+suffix,若這個文件跟以前的文件有重名,則會自動覆蓋掉之前的文件,因此有些狀況suffix要定義的不能由於when而重複。 backupCount:保留日誌個數。默認的0是不會自動刪除掉日誌。若設3,則在文件的建立過程當中庫會判斷是否有超過這個3,若超過,則會從最早建立的開始刪除。

按秒切分示例:

import time import logging import logging.handlers import os # 若是日誌文件夾不存在,則建立
log_dir = "log-second"  # 日誌存放文件夾名稱
log_path = os.getcwd() + os.sep + log_dir if not os.path.isdir(log_path): os.makedirs(log_path) # logging初始化工做
logging.basicConfig() # 初始化loggger
test = logging.getLogger('test') test.setLevel(logging.INFO) # 添加TimedRotatingFileHandler # 定義一個1秒換一次log文件的handler # 保留3箇舊log文件
timefilehandler = logging.handlers.TimedRotatingFileHandler( log_dir + os.sep + "log", when='S', interval=1, backupCount=3 ) # 設置後綴名稱,跟strftime的格式同樣
timefilehandler.suffix = "%Y-%m-%d_%H-%M-%S.log" formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s') timefilehandler.setFormatter(formatter) test.addHandler(timefilehandler) n = 6
while n > 0: test.info("這是一個時間分割的測試程序") time.sleep(1) n -= 1

運行結果:

注意:

timefilehandler.suffix的設置必定要和時間單位相符,不如按秒切分,就必須設置timefilehandler.suffix= "%Y-%m-%d_%H-%M-%S.log",不然就不能刪除舊文件了。按天、按分鐘切分也是如此。

RotatingFileHandler基於文件大小切分

示例:

import time # import logging
import os import logging.handlers # 若是日誌文件夾不存在,則建立
log_dir = "log-size"  # 日誌存放文件夾名稱
log_path = os.getcwd() + os.sep + log_dir if not os.path.isdir(log_path): os.makedirs(log_path) # logging初始化工做
logging.basicConfig() # 初始化loggger
test_02 = logging.getLogger('test_02') test_02.setLevel(logging.INFO) # 寫入文件,若是單個文件超過100個Bytes,則寫入下一個文件,最多保留5個文件
handler = logging.handlers.RotatingFileHandler( 'log-size/test_02.log', maxBytes=100, backupCount=5) formatter = logging.Formatter('%(asctime)s|%(name)-12s: %(levelname)-8s %(message)s') handler.setFormatter(formatter) # 設置後綴名稱,跟strftime的格式同樣
test_02.addHandler(handler) n = 6
while n > 0: test_02.info("這是一個大小分割的測試程序") time.sleep(1) n -= 1

運行結果:

-----------------------------------------------------------------------------

推薦:

詳細全面:http://www.javashuo.com/article/p-wqlkttny-y.html

http://www.javashuo.com/article/p-nkwdqert-p.html

相關文章
相關標籤/搜索