摘要:上一篇文章模塊分析第節(jié)模塊一日志記錄的級別優(yōu)先級,記錄調(diào)試的詳細(xì)信息,只在調(diào)試時(shí)開啟優(yōu)先級,記錄普通的消息,報(bào)告錯(cuò)誤和警告等待。監(jiān)聽端口號上一篇文章模塊分析第節(jié)模塊
上一篇文章:Python模塊分析:第3節(jié)-typing模塊一、日志記錄的級別
debug:優(yōu)先級10,記錄調(diào)試的詳細(xì)信息,只在調(diào)試時(shí)開啟
info:優(yōu)先級20,記錄普通的消息,報(bào)告錯(cuò)誤和警告等待。
warning:優(yōu)先級30,記錄相關(guān)的警告信息。
error:優(yōu)先級40,記錄錯(cuò)誤信息、程序崩潰
critical:優(yōu)先級50,記錄錯(cuò)誤信息
如果不設(shè)置,默認(rèn)為iwarning二、logging模塊的主要結(jié)構(gòu)
查看logging的源碼,可知主要有四個(gè)類實(shí)現(xiàn)功能:
Loggers:提供應(yīng)該程序直接使用的接口,如相關(guān)的配置設(shè)置
Handlers:將Loggers產(chǎn)生的日志傳到指定位置,設(shè)置日志保存的位置;
Filters:對輸出日志進(jìn)行過濾操作;
Formatters:控制日志的輸出格式
FormattersFormatters對象定義了日志的輸出格式,有多種可選參數(shù)。
參數(shù) | 含義 |
---|---|
%(name)s | Logger的名字 |
%(levellno)s | 數(shù)字形式的日志級別 |
%(levelname)s | 文本形式的日志級別 |
%(pathname)s | 調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒有 |
%(filename)s | 調(diào)用日志輸出函數(shù)的模塊的文件名 |
%(module)s | 調(diào)用日志輸出函數(shù)的模塊名 |
%(funcName)s | 調(diào)用日志輸出函數(shù)的函數(shù)名 |
%(lineno)d | 調(diào)用日志輸出函數(shù)的語句所在的代碼行 |
%(created)f | 當(dāng)前時(shí)間,用unix標(biāo)表示的時(shí)間浮點(diǎn)表示 |
%(relativeCreated)d | 輸出日志信息時(shí),自Logger創(chuàng)建以來的毫秒數(shù) |
%(asctime)s | 字符串形式的當(dāng)前時(shí)間,默認(rèn)格式是‘2018-11-22 16:49:45,896’,逗號后面是毫秒 |
%(thread)d | 線程ID,可能沒有 |
%(threadName)s | 線程名,可能沒有 |
%(process)d | 進(jìn)程ID,可能沒有 |
%(message)s | 用戶輸出的信息 |
實(shí)例:
import logging #fmt:定義輸出的日志信息的格式 #datefmt:定義時(shí)間信息的格式,默認(rèn)為:%Y-%m-%d %H:%M:%S #style:定義格式化輸出的占位符,默認(rèn)是%(name)格式,可選{}或$格式 formatter=logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s" ,datefmt="%Y-%m-%d %H:%M:%S",style="%")Handlers日志處理器
日志處理器用來處理日志的具體流向,是輸出到文件中還是標(biāo)準(zhǔn)輸出等,它通過設(shè)置Formatter控制輸出格式,添加filters過濾日志。
StreamHandler:用于向控制臺打印日志
FileHandler:用于向日志文件打印日志
名稱 | 詳細(xì)位置 | 說明 |
---|---|---|
RotatingHandler | logging.handlers.RotatingHandler | 日志回滾方式,支持日志文件最大數(shù)量和日志文件回滾 |
TimeRotatingHandler | logging.handlers.TimeRotatingHandler | 日志回滾方式,在一定時(shí)間區(qū)域內(nèi)回滾日志文件 |
SocketHandler | logging.handlers.SocketHandler | 遠(yuǎn)程輸出日志到TCP/IP sockets |
DatagramHandler | logging.handlers.DatagramHandler | 遠(yuǎn)程輸出日志到UDP sockets |
SMTPHandler | logging.handlers.SMTPHandler | 遠(yuǎn)程輸出日志到郵件地址 |
SysLogHandler | logging.handlers.SysLogHandler | 日志輸出到syslog |
NTEventLogHandler | logging.handlers.NTEventLogHandler | 遠(yuǎn)程輸出日志到Windows NT/2000/xp的事件日志 |
MemoryHandler | logging.handlers.MemoryHandler | 日志輸出到內(nèi)存中的指定buffer |
HTTPHandler | logging.handlers.HTTPHandler | 通過“GET”或者“POST”遠(yuǎn)程輸出到HTTP服務(wù)器 |
from logging import Handler #所有日志處理器的父類 handler=Handler() print("處理日志的等級:",handler.level) print("處理日志的名字:",handler.name) print("處理器的日志過濾器::",handler.filters) print("日志的格式::",handler.filters) #一些常用方法: handler.get_name() handler.set_name("") handler.createLock()#創(chuàng)建線程鎖 handler.acquire()#獲取線程鎖 handler.release()#釋放線程鎖 handler.setLevel("info") #設(shè)置日志處理器的記錄級別 handler.setFormatter(fmt="")#設(shè)置日志的輸出格式 handler.addFilter("")#往處理器中添加過濾器 handler.removeFilter("")#往處理器中移除過濾器 handler.emit("")#日志記錄的處理邏輯,由子類實(shí)現(xiàn)Logger日志對象
Logger管理著所有記錄日志的方法。
from logging import error, debug, warning, info, fatal, critical, getLogger #返回一個(gè)Logger實(shí)例 #以"root"為名字的日志對象在Logger對象中只有一個(gè)實(shí)例 logger=getLogger("root") print("獲取根日志對象",logger.root) print("獲取manager",logger.manager) print("獲取根日志對象的名字",logger.name) print("獲取根日志對象記錄水平",logger.level) print("獲取根日志對象過濾器列表",logger.filters) print("獲取根日志對象處理器列表",logger.handlers) print("獲取根日志對象",logger.disabled) #設(shè)置日志記錄水平 logger.setLevel("info") #輸出日志信息,格式化輸出 logger.info("this is %s","info",exc_info=1) #記錄warning信息 logger.warning("") #記錄error信息 logger.error("") #等價(jià)于logger.error("",exc_info=1) logger.exception("") #記錄debug信息 logger.debug("") #記錄critical信息 logger.critical("") #直接指定級別 logger.log("info","") #添加處理器 logger.addHandler() #移除處理器 logger.removeHandler() #判是否有處理器 logger.hasHandlers()三、logger的基本使用
實(shí)例:
import logging import sys def my_get_logger(appname): #獲取logger實(shí)例,如果參數(shù)為空則返回root logger logger=logging.getLogger(appname) #創(chuàng)建日志輸出格式 formatter=logging.Formatter("%(asctime)s %(levelname)s %(mark)s: %(message)s") #指定輸出的文件路徑 file_handler=logging.FileHandler("test.log") # 設(shè)置文件處理器,加載處理器格式 file_handler.setFormatter(formatter) #控制臺日志 console_handler=logging.StreamHandler(sys.stdout) console_handler.formatter=formatter #為logger添加的日志處理器 logger.addHandler(file_handler) logger.addHandler(console_handler) #指定日志的最低輸出級別,默認(rèn)為warn級別 logger.setLevel(logging.INFO) return logger if __name__ == "__main__": logger=my_get_logger("test") # extra: 這是一個(gè)字典(dict)參數(shù),它可以用來自定義消息格式中所包含的字段,但是它的key不能與logging模塊定義的字段沖突。 logger.debug("this is debug info",extra={"mark":"mark"}) logger.info("this is information",extra={"mark":"mark"}) logger.warning("this is warning message",extra={"mark":"mark"}) logger.error("this is error message",extra={"mark":"mark"}) logger.fatal("this is fatal message,it is same ad logger.critical",extra={"mark":"mark"}) logger.critical("this is critical message",extra={"mark":"mark"})
結(jié)果:
2018-11-27 09:54:43,318 INFO mark: this is information 2018-11-27 09:54:43,318 WARNING mark: this is warning message 2018-11-27 09:54:43,318 ERROR mark: this is error message 2018-11-27 09:54:43,319 CRITICAL mark: this is fatal message,it is same ad logger.critical 2018-11-27 09:54:43,319 CRITICAL mark: this is critical message四、logger日志記錄的邏輯調(diào)用過程
記錄日志通過調(diào)用logger.debug等方法;
首先判斷本條記錄的日志級別是否大于設(shè)置的級別,如果不是,直接pass,不再執(zhí)行;
將日志信息當(dāng)做參數(shù)創(chuàng)建一個(gè)LogRecord日志記錄對象
將LogRecord對象經(jīng)過logger過濾器過濾,如果被過濾則pass
日志記錄對象被Handler處理器的過濾器過濾
判斷本條記錄的日志級別是否大于Handler處理器設(shè)置的級別,如果不是,直接pass,不再執(zhí)行;
最后調(diào)用處理器的emit方法處理日志記錄;
五、配置logger通過代碼進(jìn)行完整配置,主要是通過getLogger方法實(shí)現(xiàn),但不好修改
通過basicConfig方法實(shí)現(xiàn),這種方式快速但不夠?qū)哟畏置?/p>
通過logging.config.fileConfig(filepath),文件配置
通過dictConfig的字典方式配置,這是py3.2版本引入的新的配置方法
使用文件方式配置#logging.cong [loggers] #定義日志的對象名稱是什么,注意必須定義root,否則報(bào)錯(cuò) keys=root,main [handlers] #定義處理器的名字是什么,可以有多個(gè),用逗號隔開 keys=consoleHandler [formatters] #定義輸出格式對象的名字,可以有多個(gè),用逗號隔開 keys=simpleFormatter [logger_root] #配置root對象的日志記錄級別和使用的處理器 level=INFO handlers=consoleHandler [logger_main] #配置main對象的日志記錄級別和使用的處理器,qualname值得就是日志對象的名字 level=INFO handlers=consoleHandler qualname=main #logger對象把日志傳遞給所有相關(guān)的handler的時(shí)候,會逐級向上尋找這個(gè)logger和它所有的父logger的全部handler, #propagate=1表示會繼續(xù)向上搜尋; #propagate=0表示停止搜尋,這個(gè)參數(shù)涉及重復(fù)打印的坑。 propagate=0 [handler_consoleHandler] #配置處理器consoleHandler class=StreamHandler level=WARNING formatter=simpleFormatter args=(sys,) [formatter_simpleFormatter] #配置輸出格式過濾器simpleFormatter format=%(asctime)-%(name)s-%(levelname)s-%(message)s
注意:可以看到logger和Handler都可以設(shè)置日志級別,日志輸出是取最高級別。使用字典形式配置
字典形式配置功能更強(qiáng)大,也更加靈活。通過dictConfig函數(shù),我們可以將其他格式的配置文件轉(zhuǎn)化成字典,如json,YAML等。
實(shí)例:
import yaml from logging.config import dictConfig import os filename=os.path.dirname(os.path.abspath(__file__)) with open(filename+"/logging.yaml","r") as f: log=yaml.load(f.read()) dictConfig(log)
#logging.yaml #注意:yaml格式嚴(yán)格,:后面一定要帶空格 version: 1 formatters: simple: format: "%(asctime)s-%(name)s-%(levelname)s-%(message)s" handlers: console: class: logging.StreamHandler level: DEBUG formatter: simple stream: ext://sys.stdout console_err: class: logging.StreamHandler level: DEBUG formatter: simple stream: ext://sys.stderr loggers: simpleExample: level: DEBUG handlers: [console] propagate: no root: level: DEBUG handlers: [console_err]]六、監(jiān)聽logger配置更改
logging.config.listen(port)函數(shù)可以讓英語程序在一個(gè)socket上監(jiān)聽新的配置信息,達(dá)到在運(yùn)行時(shí)改變配置,而不用重啟應(yīng)用程序的目的。
import logging.config import logging logging.config.fileConfig("logging.conf") logger=logging.getLogger("test.listen") #監(jiān)聽端口號9999 t=logging.config.listen(9999) t.setDaemon(True) t.start()
上一篇文章:Python模塊分析:第3節(jié)-typing模塊
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42673.html
摘要:代碼實(shí)例運(yùn)行結(jié)果跟不用無異上一篇文章模塊分析第節(jié)加密模塊下一篇文章模塊分析第節(jié)日志模塊 上一篇文章:Python模塊分析:第2節(jié)-hashlib加密模塊下一篇文章:Python模塊分析:第4節(jié)-logging日志模塊 Python是一門弱類型的語言,很多時(shí)候我們可能不清楚函數(shù)參數(shù)類型或者返回值類型,很有可能導(dǎo)致一些類型沒有指定方法,typing模塊可以很好的解決這個(gè)問題。 該模塊加入...
摘要:原因是,直接傳遞格式化后的字符串會導(dǎo)致參數(shù)被完全求值,這個(gè)有可能是非必要的,會導(dǎo)致日志性能下降。添加一個(gè)過濾器用來進(jìn)行消息格式化上面的中的中文注釋部分直接說明了解決方案。 問題 Python的logging庫是標(biāo)準(zhǔn)庫中用來實(shí)現(xiàn)日志的庫,功能強(qiáng)大,而且使用起來也算是方便。該庫提供了很多個(gè)不同的Handler,用來對日志進(jìn)行不同的處理。例如FileHandler用來將日志記錄到文件,Rot...
摘要:上一篇文章模塊分析第節(jié)模塊下一篇文章模塊分析第節(jié)模塊模塊是用來對字符串進(jìn)行加密的模塊,明文與密文是一一對應(yīng)不變的關(guān)系用于注冊登錄時(shí)用戶名密碼等加密使用。一函數(shù)分析共有種加密算法,分別得到不同的加密密文。 上一篇文章:Python模塊分析:第1節(jié)-random模塊下一篇文章:Python模塊分析:第3節(jié)-typing模塊 hashlib模塊是用來對字符串進(jìn)行hash加密的模塊,明文與密...
摘要:下一篇文章模塊分析第節(jié)加密模塊是產(chǎn)生偽隨機(jī)數(shù)的模塊,隨機(jī)種子默認(rèn)為系統(tǒng)時(shí)鐘。核心源碼時(shí)間復(fù)雜度實(shí)例結(jié)果下一篇文章模塊分析第節(jié)加密模塊 下一篇文章:Python模塊分析:第2節(jié)-hashlib加密模塊 random是Python產(chǎn)生偽隨機(jī)數(shù)的模塊,隨機(jī)種子默認(rèn)為系統(tǒng)時(shí)鐘。下面分析模塊中的方法: 1、random.randint(start,stop) 這是一個(gè)產(chǎn)生整數(shù)隨機(jī)數(shù)的函數(shù),參數(shù)...
摘要:課程簡介簡明易懂的課程,不僅適用于那些有其它語言基礎(chǔ)的同學(xué),對沒有編程經(jīng)驗(yàn)的同學(xué)也非常友好。建議遵守以下約定使用個(gè)空格來縮進(jìn)永遠(yuǎn)不要混用空格和制表符在函數(shù)之間空一行在類之間空兩行字典,列表,元組以及參數(shù)列表中,在后添加一個(gè)空格。 showImg(https://segmentfault.com/img/bVCldE); 課程簡介:簡明易懂的 Python3 課程,不僅適用于那些有其它語...
閱讀 765·2019-08-29 16:32
閱讀 836·2019-08-29 12:31
閱讀 3208·2019-08-26 18:26
閱讀 3152·2019-08-26 12:20
閱讀 1728·2019-08-26 12:00
閱讀 3006·2019-08-26 10:58
閱讀 2811·2019-08-23 17:08
閱讀 2309·2019-08-23 16:32