国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中內(nèi)置的日志模塊logging用法詳解

2019-11-25 16:38:50
字體:
供稿:網(wǎng)友

logging模塊簡介

Python的logging模塊提供了通用的日志系統(tǒng),可以方便第三方模塊或者是應(yīng)用使用。這個(gè)模塊提供不同的日志級(jí)別,并可以采用不同的方式記錄日志,比如文件,HTTP GET/POST,SMTP,Socket等,甚至可以自己實(shí)現(xiàn)具體的日志記錄方式。
logging模塊與log4j的機(jī)制是一樣的,只是具體的實(shí)現(xiàn)細(xì)節(jié)不同。模塊提供logger,handler,filter,formatter。

  • logger:提供日志接口,供應(yīng)用代碼使用。logger最長用的操作有兩類:配置和發(fā)送日志消息??梢酝ㄟ^logging.getLogger(name)獲取logger對(duì)象,如果不指定name則返回root對(duì)象,多次使用相同的name調(diào)用getLogger方法返回同一個(gè)logger對(duì)象。
  • handler:將日志記錄(log record)發(fā)送到合適的目的地(destination),比如文件,socket等。一個(gè)logger對(duì)象可以通過addHandler方法添加0到多個(gè)handler,每個(gè)handler又可以定義不同日志級(jí)別,以實(shí)現(xiàn)日志分級(jí)過濾顯示。
  •  filter:提供一種優(yōu)雅的方式?jīng)Q定一個(gè)日志記錄是否發(fā)送到handler。
  •  formatter:指定日志記錄輸出的具體格式。formatter的構(gòu)造方法需要兩個(gè)參數(shù):消息的格式字符串和日期字符串,這兩個(gè)參數(shù)都是可選的。

與log4j類似,logger,handler和日志消息的調(diào)用可以有具體的日志級(jí)別(Level),只有在日志消息的級(jí)別大于logger和handler的級(jí)別。

logging用法解析

1. 初始化 logger = logging.getLogger("endlesscode"),getLogger()方法后面最好加上所要日志記錄的模塊名字,后面的日志格式中的%(name)s 對(duì)應(yīng)的是這里的模塊名字
2. 設(shè)置級(jí)別 logger.setLevel(logging.DEBUG),Logging中有NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL這幾種級(jí)別,日志會(huì)記錄設(shè)置級(jí)別以上的日志
3. Handler,常用的是StreamHandler和FileHandler,windows下你可以簡單理解為一個(gè)是console和文件日志,一個(gè)打印在CMD窗口上,一個(gè)記錄在一個(gè)文件上
4. formatter,定義了最終log信息的順序,結(jié)構(gòu)和內(nèi)容,我喜歡用這樣的格式 '[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S',
%(name)s Logger的名字
%(levelname)s 文本形式的日志級(jí)別
%(message)s 用戶輸出的消息
%(asctime)s 字符串形式的當(dāng)前時(shí)間。默認(rèn)格式是 “2003-07-08 16:49:45,896”。逗號(hào)后面的是毫秒
%(levelno)s 數(shù)字形式的日志級(jí)別
%(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)準(zhǔn)的表示時(shí)間的浮 點(diǎn)數(shù)表示
%(relativeCreated)d 輸出日志信息時(shí)的,自Logger創(chuàng)建以 來的毫秒數(shù)
%(thread)d 線程ID??赡軟]有
%(threadName)s 線程名??赡軟]有
%(process)d 進(jìn)程ID??赡軟]有
5. 記錄 使用object.debug(message)來記錄日志
下面來寫一個(gè)實(shí)例,在CMD窗口上只打出error以上級(jí)別的日志,但是在日志中打出debug以上的信息

import logginglogger = logging.getLogger("simple_example")logger.setLevel(logging.DEBUG)# 建立一個(gè)filehandler來把日志記錄在文件里,級(jí)別為debug以上fh = logging.FileHandler("spam.log")fh.setLevel(logging.DEBUG)# 建立一個(gè)streamhandler來把日志打在CMD窗口上,級(jí)別為error以上ch = logging.StreamHandler()ch.setLevel(logging.ERROR)# 設(shè)置日志格式formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")ch.setFormatter(formatter)fh.setFormatter(formatter)#將相應(yīng)的handler添加在logger對(duì)象中l(wèi)ogger.addHandler(ch)logger.addHandler(fh)# 開始打日志logger.debug("debug message")logger.info("info message")logger.warn("warn message")logger.error("error message")logger.critical("critical message")

運(yùn)行一下將會(huì)看到CMD窗口只記錄兩條,spam.log中記錄了五條日志

2016712145241018.jpg (773×353)

當(dāng)一個(gè)項(xiàng)目比較大的時(shí)候,不同的文件中都要用到Log,可以考慮將其封裝為一個(gè)類來使用

#! /usr/bin/env python#coding=gbkimport logging,osclass Logger: def __init__(self, path,clevel = logging.DEBUG,Flevel = logging.DEBUG):  self.logger = logging.getLogger(path)  self.logger.setLevel(logging.DEBUG)  fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')  #設(shè)置CMD日志  sh = logging.StreamHandler()  sh.setFormatter(fmt)  sh.setLevel(clevel)  #設(shè)置文件日志  fh = logging.FileHandler(path)  fh.setFormatter(fmt)  fh.setLevel(Flevel)  self.logger.addHandler(sh)  self.logger.addHandler(fh) def debug(self,message):  self.logger.debug(message) def info(self,message):  self.logger.info(message) def war(self,message):  self.logger.warn(message) def error(self,message):  self.logger.error(message) def cri(self,message):  self.logger.critical(message)if __name__ =='__main__': logyyx = Logger('yyx.log',logging.ERROR,logging.DEBUG) logyyx.debug('一個(gè)debug信息') logyyx.info('一個(gè)info信息') logyyx.war('一個(gè)warning信息') logyyx.error('一個(gè)error信息') logyyx.cri('一個(gè)致命c(diǎn)ritical信息')

這樣每次使用的時(shí)候只要實(shí)例化一個(gè)對(duì)象就可以了

logobj = Logger(‘filename',clevel,Flevel)

如果想在CMD窗口中對(duì)于error的日志標(biāo)紅,warning的日志標(biāo)黃,那么可以使用ctypes模塊

2016712145318276.jpg (732×225)

#! /usr/bin/env python#coding=gbkimport logging,osimport ctypesFOREGROUND_WHITE = 0x0007FOREGROUND_BLUE = 0x01 # text color contains blue.FOREGROUND_GREEN= 0x02 # text color contains green.FOREGROUND_RED = 0x04 # text color contains red.FOREGROUND_YELLOW = FOREGROUND_RED | FOREGROUND_GREENSTD_OUTPUT_HANDLE= -11std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)def set_color(color, handle=std_out_handle): bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color) return boolclass Logger: def __init__(self, path,clevel = logging.DEBUG,Flevel = logging.DEBUG):  self.logger = logging.getLogger(path)  self.logger.setLevel(logging.DEBUG)  fmt = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')  #設(shè)置CMD日志  sh = logging.StreamHandler()  sh.setFormatter(fmt)  sh.setLevel(clevel)  #設(shè)置文件日志  fh = logging.FileHandler(path)  fh.setFormatter(fmt)  fh.setLevel(Flevel)  self.logger.addHandler(sh)  self.logger.addHandler(fh) def debug(self,message):  self.logger.debug(message) def info(self,message):  self.logger.info(message) def war(self,message,color=FOREGROUND_YELLOW):  set_color(color)  self.logger.warn(message)  set_color(FOREGROUND_WHITE) def error(self,message,color=FOREGROUND_RED):  set_color(color)  self.logger.error(message)  set_color(FOREGROUND_WHITE) def cri(self,message):  self.logger.critical(message)if __name__ =='__main__': logyyx = Logger('yyx.log',logging.WARNING,logging.DEBUG) logyyx.debug('一個(gè)debug信息') logyyx.info('一個(gè)info信息') logyyx.war('一個(gè)warning信息') logyyx.error('一個(gè)error信息') logyyx.cri('一個(gè)致命c(diǎn)ritical信息')

多模塊使用logging
logging模塊保證在同一個(gè)python解釋器內(nèi),多次調(diào)用logging.getLogger('log_name')都會(huì)返回同一個(gè)logger實(shí)例,即使是在多個(gè)模塊的情況下。所以典型的多模塊場(chǎng)景下使用logging的方式是在main模塊中配置logging,這個(gè)配置會(huì)作用于多個(gè)的子模塊,然后在其他模塊中直接通過getLogger獲取Logger對(duì)象即可。
配置文件:

[loggers] keys=root,main  [handlers] keys=consoleHandler,fileHandler  [formatters] keys=fmt  [logger_root] level=DEBUG handlers=consoleHandler  [logger_main] level=DEBUG qualname=main handlers=fileHandler  [handler_consoleHandler] class=StreamHandler level=DEBUG formatter=fmt args=(sys.stdout,)  [handler_fileHandler] class=logging.handlers.RotatingFileHandler level=DEBUG formatter=fmt args=('tst.log','a',20000,5,)  [formatter_fmt] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s datefmt= 

主模塊main.py:

import logging import logging.config  logging.config.fileConfig('logging.conf') root_logger = logging.getLogger('root') root_logger.debug('test root logger...')  logger = logging.getLogger('main') logger.info('test main logger') logger.info('start import module /'mod/'...') import mod  logger.debug('let/'s test mod.testLogger()') mod.testLogger()  root_logger.info('finish test...') 

子模塊mod.py:

import logging import submod  logger = logging.getLogger('main.mod') logger.info('logger of mod say something...')  def testLogger():   logger.debug('this is mod.testLogger...')   submod.tst() 

子子模塊submod.py:

import logging  logger = logging.getLogger('main.mod.submod') logger.info('logger of submod say something...')  def tst():   logger.info('this is submod.tst()...') 

然后運(yùn)行python main.py,控制臺(tái)輸出:

2012-03-09 18:22:22,793 - root - DEBUG - test root logger... 2012-03-09 18:22:22,793 - main - INFO - test main logger 2012-03-09 18:22:22,809 - main - INFO - start import module 'mod'... 2012-03-09 18:22:22,809 - main.mod.submod - INFO - logger of submod say something... 2012-03-09 18:22:22,809 - main.mod - INFO - logger say something... 2012-03-09 18:22:22,809 - main - DEBUG - let's test mod.testLogger() 2012-03-09 18:22:22,825 - main.mod - DEBUG - this is mod.testLogger... 2012-03-09 18:22:22,825 - main.mod.submod - INFO - this is submod.tst()... 2012-03-09 18:22:22,841 - root - INFO - finish test... 

可以看出,和預(yù)想的一樣,然后在看一下tst.log,logger配置中的輸出的目的地:

2012-03-09 18:22:22,793 - main - INFO - test main logger 2012-03-09 18:22:22,809 - main - INFO - start import module 'mod'... 2012-03-09 18:22:22,809 - main.mod.submod - INFO - logger of submod say something... 2012-03-09 18:22:22,809 - main.mod - INFO - logger say something... 2012-03-09 18:22:22,809 - main - DEBUG - let's test mod.testLogger() 2012-03-09 18:22:22,825 - main.mod - DEBUG - this is mod.testLogger... 2012-03-09 18:22:22,825 - main.mod.submod - INFO - this is submod.tst()... 

tst.log中沒有root logger輸出的信息,因?yàn)閘ogging.conf中配置了只有main logger及其子logger使用RotatingFileHandler,而root logger是輸出到標(biāo)準(zhǔn)輸出。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鄯善县| 比如县| 北宁市| 上林县| 河源市| 浑源县| 阿拉善盟| 亳州市| 荔浦县| 肇州县| 乌鲁木齐县| 大同县| 同仁县| 莱芜市| 南和县| 将乐县| 曲阜市| 温宿县| 乌兰县| 石河子市| 青铜峡市| 江孜县| 普宁市| 夏津县| 石景山区| 嵩明县| 兴安盟| 两当县| 玉树县| 天津市| 逊克县| 龙陵县| 河北区| 宁河县| 永州市| 沁阳市| 中西区| 青浦区| 仙桃市| 翼城县| 巴塘县|