python logging模块默认日志,python打印log日志
原木日志模块前言记录是大蟒中的一个包,封装所有日志功能。
例如获取日志器logging.getLogger是记录包的__init__文件中定义的函数(包的__init__文件中的函数直接可以使用包名。函数名调用),如下获取记录器代码:
def getLogger(name=None):
返回具有指定名称的记录器,如有必要,创建它。
如果没有指定名称,则返回根日志记录器。
如果不是名字或isinstance(名称,字符串)并且name==root.name:
返回根目录
返回记录器。经理。get Logger(name)root=root Logger(WARNING)class root Logger(Logger):
根日志记录器与任何其他日志记录器没有什么不同,除了
它必须有一个日志记录级别,并且在中只有一个实例
等级制度。
def __init__(自身,等级):
用名称"根"初始化记录器。
伐木工. init__(自身,根,级别)
def __reduce__(自己):
返回获取记录器,()即获取记录器函数返回值为记录器类的实例对象。
例如为日志器设置默认的日志级别logger.setLevel()为记录包的__init__文件记录器类中的设置等级函数,代码如下:
定义设置级别(自身,级别):
设置该记录器的记录级别。级别必须是整数或字符串。
self.level=_checkLevel(级别)
自我。经理。_ clear _ cache()def _ check level(level):
if isinstance(level,int):
rv=水平
elif str(level)==level:
如果级别不在_nameToLevel中:
提升值错误("未知级别:% r"%级别")
rv=_nameToLevel[level]
否则:
引发TypeError(级别不是整数或有效字符串:%r %级别
return rv_nameToLevel={
关键:关键,
致命:致命,
错误:错误,
警告:警告,
警告:警告,
信息:信息,
调试:调试,
NOTSET: NOTSET,
}临界=50
致命=危急
误差=40
警告=30
警告=警告
INFO=20
调试=10
NOTSET=0一、伐木函数根据它们用来跟踪的事件的级别或严重程度来命名。标准级别及其适用性描述如下(以严重程度递增排序):
默认等级是警告,只有高于默认等级以上的级别才会打印到控制台。
将日志直接输出到屏幕
由于默认设置的等级是警告,所有只有警告的信息会输出到控制台。
导入日志记录
logging.debug(debug信息)
logging.warning(只有这个会输出。)
logging.info(info信息)输出结果:
通过logging.basicConfig函数对日志的输出格式及方式做相关配置导入日志记录
伐木。基本配置(级别=日志记录.调试,
format= %(ASC time)s %(filename)s[line:%(行号)d]%(级别名)s %(消息)s ,
datefmt=%a,%d %b %Y %H:%M:%S ,
filename=myapp.log ,
filemode=w )
logging.debug("这是调试消息")
logging.info("这是信息消息")
logging.warning("这是警告消息")
#./myapp.log文件中内容为:
#孙,2009年年5月24日21:48:54 demo2.py[line:11]调试这是调试消息
#孙,2009年年5月24日21:48:54 demo2.py[line:12] INFO这是信息消息
#孙,2009年年5月24日21:48:54演示2。py[line:13]警告这是警告消息logging.basicConfig参数:
#logging.basicConfig函数各参数:
文件名:指定日志文件名
文件模式:和文件函数意义相同,指定日志文件的打开模式, w 或一个
格式:指定输出的格式和内容,格式可以输出很多有用信息,如上例所示:
%(级别号)秒:打印日志级别的数值
%(级别名)s:打印日志级别名称
%(路径名)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(文件名)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(行号)d:打印日志的当前行号
%(asctime)s:打印日志的时间
%(螺纹)d:打印线程身份
%(线程名)s:打印线程名称
%(流程)d:打印进程身份
%(消息)s:打印日志信息
日期:指定时间格式,同time.strftime()
级别:设置日志级别,默认为伐木。警告[高于该日志级别才会打印到控制台上】
流:指定将日志的输出流,可以指定输出到系统标准错误,系统标准输出或者文件,默认输出到sys.stderr,当溪流和文件名同时指定时,流被忽略将日志同时输出到多个处理者定义处理者,并使用addHander()添加到日志器,实现日志输出到多个处理程序。
答:同时输出到文件和屏幕
导入日志记录
#设置一个基本配置只能输出到一个处理者
伐木。基本配置(级别=日志记录.调试,
format= %(ASC time)s %(filename)s[line:%(行号)d]%(级别名)s %(消息)s ,
datefmt=%a,%d %b %Y %H:%M:%S ,
filename=myapp.log ,
filemode=w )
#定义一个StreamHandler,将信息级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象#
控制台=日志记录StreamHandler()
console.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(名称)-12s: %(级别名)-8s %(消息)s’)
console.setFormatter(格式化程序)
logging.getLogger(" ").addHandler(控制台)
#输出到文件的原木级别为调试,输出到溪流的原木级别为信息
logging.debug("这是调试消息")
logging.info("这是信息消息")
logging.warning(这是警告消息)b,添加一个处理人:输出到文件,并根据文件大小滚动存储
在a的基础上添加一个处理者
从日志记录.处理程序导入旋转文件处理器
#定义一个旋转文件处理器,最多备份5个日志文件,每个日志文件最大10M
rthandler=旋转文件处理程序( myapp。log ,maxBytes=10*1024*1024,backupCount=5)
Rthandler.setLevel(日志记录。信息)
格式化程序=记录。格式化程序( %(名称)-12s: %(级别名)-8s %(消息)s’)
Rthandler.setFormatter(格式化程序)
logging.getLogger(" ").addHandler(Rthandler)日志记录几种处理者类型:
伐木。流处理器(默认): 日志输出到流,可以是系统标准错误、系统标准输出或者文件
伐木。文件处理程序:日志输出到文件
伐木。经手人。旋转文件处理程序日志输出到文件,基于文件大小滚动存储日志
伐木。经手人。timedrotatingfilehandler日志输出到文件,基于时间周期滚动存储日志
logging.handlers.SocketHandler:远程输出日志到传输控制协议套接字
伐木。经手人。数据报处理程序:远程输出日志到用户数据报协议(User Datagram Protocol)套接字
logging.handlers.SMTPHandler:远程输出日志到邮件地址
logging.handlers.SysLogHandler:日志输出到系统记录
伐木。经手人。nteventloghandler:远程输出日志到Windows NT/2000/XP的事件日志
logging.handlers.MemoryHandler:日志输出到内存中的制定缓冲器
logging.handlers.HTTPHandler:通过得到或发布远程输出到超文本传送协议服务器通过配置文件配置伐木工,定义配置文件logger.conf
#logger.conf
###############################################
[伐木工人]
keys=root,example01,example02
[logger_root]
级别=调试
处理程序=hand01、hand02
[logger_example01]
处理程序=hand01、hand02
qualname=example01
传播=0
[logger_example02]
处理程序=hand01、hand03
qualname=example02
传播=0
###############################################
[经手人]
密钥=hand01、hand02、hand03
[handler_hand01]
级别=信息
formatter=form02
args=(sys.stderr,)
[handler_hand02]
级别=调试
formatter=form01
args=(myapp.log , a )
[handler_hand03]
级别=信息
formatter=form02
args=(myapp.log , a ,10*1024*1024,5)
###############################################
[格式化程序]
密钥=表格01,表格02
[formatter_form01]
format=%(ASC time)s %(filename)s[line:%(行号)d]%(级别名)s %(消息)s
datefmt=%a,%d %b %Y %H:%M:%S
[formatter_form02]
格式=%(名称)-12s: %(级别名称)-8s %(消息)s
datefmt=b、logging.config获取配置
导入日志记录
导入日志记录。配置
伐木。配置。文件配置(记录器。conf’)
logger=日志记录。获取记录器(“示例01”)
logger.debug(这是调试消息)
logger.info(这是信息消息)
logger.warning(这是警告消息)导入日志记录
导入日志记录。配置
伐木。配置。文件配置(记录器。conf’)
logger=日志记录。获取记录器(“示例02”)
logger.debug(这是调试消息)
logger.info(这是信息消息)
伐木工。警告(这是警告信息)二、日志库【python中打包的功能模块】采用模块化设计,提供了很多组件:日志器、处理器、过滤器和格式化器。1.Logger公开了应用程序代码可以直接使用的接口。
2.处理程序将日志记录(由记录器生成)发送到适当的目的地。
3.过滤器提供了更好的粒度控制,它可以决定输出哪些日志记录。
4.格式化程序指示最终输出中日志记录的布局。
3.LoggersLogger对象必须做三件事。
首先,它们向应用程序代码公开了许多方法,因此应用程序可以在运行时记录消息。
其次,logger对象确定哪些日志消息需要按严重性(默认过滤工具)或过滤器对象来记录。
第三,logger对象将相关的日志消息传递给所有感兴趣的日志处理器。
记录器对象常用的方法分为两类:配置和发送消息。
以下是最常用的配置方法:Logger.setLevel()指定Logger将处理的最低安全级别日志信息:
调试是最低的内置安全级别;
关键是最高的内置安全级别。
例如,如果严重性为INFO,记录器将只处理INFO、WARNING、ERROR和CRITICAL消息,而DEBUG消息将被忽略。
Logger.addHandler()和Logger.removeHandler()在Logger对象中添加和删除处理程序对象。有关详细信息,请参见处理程序。
Logger.addFilter()和Logger.removeFilter()在Logger对象中添加和删除过滤器对象。四。Handlers handler对象负责将适当的日志消息(基于日志消息的严重性)分发到处理程序的指定目标。[根据不同的指定处理程序,不同的日志信息以不同的方式输出]
Logger对象可以通过addHandler()方法添加零个或多个handler对象。
比如:一个应用可以将所有日志消息发送到日志文件中;所有错误级别及以上的日志消息都发送到标准输出;所有重要日志消息都发送到一个电子邮件地址。
在这个示例中,需要三个独立的处理器,每个处理器负责将特定级别的日志消息发送到特定位置。常用的有四种:
1.伐木。StreamHandler:控制台输出
将信息输出到任何文件对象,如sys.stdout或sys.stderr
它的构造函数是:StreamHandler([strm])
参数介绍:strm参数是一个文件对象。默认情况下是sys.stderr(没有传递strm参数时,默认情况下会将日志信息输出到控制台)。
2.伐木。FileHandler:文件输出
用于将日志信息输出到文件。
构造函数是:FileHandler(文件名[,模式])
参数介绍:文件名:必须指定一个文件名;模式是打开文件的方式。默认值为“a”,即添加到文件的末尾。
3.伐木。经手人。RotatingFileHandler:根据日志文件的大小自动划分日志文件,并在文件达到指定大小时重新生成文件。
这个处理程序类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小时,会自动重命名当前日志文件,然后新建一个同名的日志文件继续输出。
示例:例如,日志文件是chat.log
当chat.log达到指定大小时,RotatingFileHandler将自动重命名文件chat.log.1
但是,如果chat.log.1已经存在,它将首先被重命名为chat.log.2。最后,再次创建chat.log,继续输出日志信息。构造函数:RotatingFileHandler(文件名[,模式[,最大字节[,备份计数]])
参数介绍:文件名:必须指定一个文件名。模式是打开文件的方式。默认值为“a”,即添加到文件的末尾。maxBytes用于指定日志文件的最大文件大小。[如果maxBytes为0,表示日志文件可以是无限的,那么上述重命名过程不会发生。】backupCount用于指定要保留的备份文件数量。[如果指定了2,当上述重命名过程发生时,原始的chat.log.2将不会被重命名,但会被删除。】
4.伐木。经手人。TimeDrotatingFileHandler:根据时间自动划分日志文件。
此处理程序类似于RotatingFileHandler
但是,它不是通过判断文件大小来决定何时重新创建日志文件,而是定期自动创建新的日志文件。
的重命名过程类似于RotatingFileHandler:但是,新文件不会附加数字,而是附加当前时间。构造函数:TimeDrotatingFileHandler(文件名[,何时[,间隔[,备份计数]])
参数介绍:
filename文件名:您必须指定一个文件名。
模式是打开文件的方式。默认值为“a”,即添加到文件的末尾。backupCount用于指定要保留的备份文件的数量。
interval是时间间隔。
当参数是字符串时。表示时间间隔的单位,不区分大小写。它具有以下值:
s秒
m点
h小时
d天
w每周(interval==0代表星期一)
每天早上午夜配置方法:
handlers.setLevel():记录器的级别决定了消息是否会传递给处理器。每个处理器的级别决定了消息是否会被分发。[logger.setLevel()为记录器设置日志级别(根据设置的日志级别,是否将日志信息传输到处理器),handlers.setLevel为处理器设置日志级别(根据每个处理器设置的日志级别,是否将日志信息输出到指定的地方)。】
handlers.setFormatter():为此处理器选择一个格式化程序。
handlers.addFilter()和handlers.removeFilter():分别在处理器上配置和取消配置Filter对象。
5.FormattersFormatter对象设置日志信息的最终规则、结构和内容;[日志生成的风格]
默认的时间格式是% y-%m-%d% h:% m:% s。
以下是格式化程序常用的一些信息:
不及物动词代码示例代码示例1: Get _ logger: # boot package
导入日志记录.处理程序
导入操作系统
导入时间
#新类别
课程日志:
root _ path=OS . path . ABS path(OS . path . dirname(_ _ file _ _))。拆分( shippingSchedule)[0]
#创建新的记录器变量
__logger=无
#定义生成日志文件的时间
_ _ log _ time=time . strftime( % Y-% m-% d ,time.localtime())
#创建一个新方法来获取记录器。
@classmethod
def get_logger(cls):
#判断记录器为空:
如果cls。_ _记录器为无:
# Get Logger [Logger公开了应用程序代码可以直接使用的接口]
CLS。_ _ logger=logging.getLogger () #包名。方法名直接调用日志包下初始化模块中的getlogger()返回RootLogger
#修改默认级别
cls。__logger.setLevel(日志记录。调试)
log _ path=cls . root _ path OS . sep python-log OS . sep info . python-log _ cls。_ _日志时间
#获取处理器[处理器将日志记录(由记录器生成)发送到适当的目的地]
th=logging . handlers . timedrotatingfilehandler(文件名=log_path,
当=午夜,
间隔=1,
backupCount=3,
编码=utf-8 )
# Get formatter[过滤器提供更好的粒度控制,可以决定输出哪些日志记录]
fmt= %(asctime)s %(level name)s[%(filename)s(%(funcName)s:%(line no)d)]-%(message)s
FM=logging . formatter(FMT)# formatter表示日志记录在最终输出中的布局。
#将格式化程序添加到处理器
th.setFormatter(fm)
#将处理器添加到记录器
cls。__logger.addHandler(th)
#返回记录器
返回cls。_ _记录器
if __name__==__main__ :
log=Logs.get_logger()
Log.info(“测试信息级别日志”)
log.error(测试错误级别)代码示例2:输出原木到控制台以及同时将原木写入原木文件#编码:utf-8
导入日志记录
从日志导入处理程序
类记录器(对象):
level_relations={
调试:日志记录。调试,
信息:日志记录。信息,
警告:日志记录。警告,
错误:日志记录。错误,
“暴击”:记录日志。批评的
} # 日志级别关系映射
def __init__(self,filename,level=info ,when=D ,backCount=3,
fmt= %(asctime)s-%(name)s-%(pathname)s[line:%(行号)d]-%(级别名)s:%(消息)s ):
self.logger=logging.getLogger(文件名)#获取日志器(文件名是日志器的名称,如果不填,默认日志器名称为根)
格式_字符串=日志记录。格式化程序(fmt) #设置日志格式
自我。伐木工。设置级别(自我。级别_关系。获取(级别))#设置日志级别
sh=记录StreamHandler() #输出至控制台
sh.setFormatter(format_str) #设置输出至控制台上日志格式
th=处理程序TimedRotatingFileHandler(文件名=文件名,当=时,备份计数=回计数,
encoding=utf-8) #往文件里写入#指定间隔时间自动生成文件的处理器
# 实例化TimedRotatingFileHandler
#间隔是时间间隔,备份计数是备份文件的个数,如果超过这个个数,就会自动删除,什么时候是间隔的时间单位,单位有以下几种:
# S秒
# M分
# H小时、
# D天、
# W每星期(间隔==0时代表星期一)
#午夜每天凌晨
th.setFormatter(format_str) #设置文件里写入的格式
self.logger.addHandler(sh) #把对象加到记录器里
self.logger.addHandler(th)
if __name__==__main__ :
log=Logger(all.log ,level=debug )
log.logger.debug("调试")
日志。伐木工。信息(“信息”)
log.logger.warning(警告)
log.logger.error(报错)
log.logger.critical(严重)
记录器( error.log ,level= error )。伐木工。错误(“错误”)代码示例3:输出原木日志到控制台以及同时将原木日志写入原木文件装饰器函数代替测试用例脚本中函数调用。号-*-编码:utf-8 -*-
导入日志记录
导入操作系统
导入时间
导入追溯
从函数工具导入包装
""处理程序是什么?
#日志记录模块中包含的类
# 用来自定义日志对象的规则(比如:设置日志输出格式、等级等)
# 常用子类:流处理程序、文件处理程序
# StreamHandler控制台输出日志
#文件处理程序日志输出到文件
# 日志文件路径
LOG _ PATH=OS。路径。加入(OS。路径。dirname(OS。路径。dirname(OS。路径。真实路径(_ _ file _ _), LOG )
如果不是os.path.exists(LOG_PATH):
os.mkdir(日志路径)
类记录器:
def __init__(self):
# 创建日志路径和时间
自我。LOG _ PATH=OS。路径。join(LOG _ PATH, {}).日志。格式(time.strftime(%Y%m%d ))
# 创建一个记录器日志对象,并传参为原木日志器命名为原木
自我。logger=日志记录。获取记录器(“日志”)
# 为日志器设置默认的日志级别
self.logger.setLevel(日志记录。调试)
# 创建日志格式对象
自格式化程序=日志记录。格式化程序([%(ASC time)s][%(文件名)s %(行号)d][%(级别名)s]:%(消息)s )
# 创建文件处理器对象(输出原木至文件)
self.file_handlers=日志记录FileHandler(self.log_path,mode=a ,encoding=UTF-8 )
# 创建流处理器对象(输出原木至控制台)
self.console_handlers=日志记录StreamHandler()
#文件处理程序对象定义日志级别
self.file_handlers.setLevel(日志记录。调试)
# StreamHandler对象定义日志级别
self.console_handlers.setLevel(日志记录。调试)
# 设置文件处理器处理器的格式
自我。文件处理程序。设置格式化程序(自身。格式化程序)
# 设置流处理器处理器的格式
自我。控制台_处理程序。设置格式化程序(自身。格式化程序)
#记录器日志对象加载文件处理器对象
自我。伐木工。addhandler(self。文件处理程序)
#记录器日志对象加载流处理器对象
自我。伐木工。addhandler(self。控制台_处理程序)
Logger=Logger().记录器
# 定义一个装饰器,为修饰测试方法提供附加操作(测试方法调用前,测试方法调用后)
def decorate_log(func):
@wraps(func)
定义日志(*args,**kwargs):
Logger.info(f -开始执行{func .__name__} -)
尝试:
func(*args,**kwargs)
例外情况为e:
Logger.error(f - {func .__name__}执行失败,失败原因:{e} -)
伐木工。错误(f"{ func .__name__}出错,详细信息如下:{traceback.format_exc()} )
提高e
否则:
Logger.info(f - {func .__name__}执行成功- )
返回日志
@装饰_日志
def hbq():
断言1==1
if __name__==__main__ :
hbq()
# Logger.info( -测试开始- )
# Logger.error( -测试结束- )
# Logger.debug( -测试结束- )衍生:结合代码示例3:
大蟒装饰器functools.wraps(func)详解1、先看一段代码:
定义is_login(func):
def foo(*args,**kwargs):
return func(*args,**kwargs)
返回富(中国姓氏)
定义测试():
打印(我是:,测试__姓名_ _)
@是_登录
def test1():
打印(我是:,测试1。__name__)
@是_登录
def test2():
打印(我是:,测试2。__name__)
if __name__==__main__ :
测试()
测试1()
测试2()运行结果:
我是:测试
我是:foo
我是:foo可以发现函数的函数名即功能.__姓名_ _已被装饰器改变,变成了装饰器内返回的函数的函数名
2、在装饰器内返回的函数的函数名上新增@wraps装饰器/functools.wraps(func)装饰器
从函数工具导入包装
定义is_login(func):
@wraps(func)
def foo(*args,**kwargs):
return func(*args,**kwargs)
返回富(中国姓氏)
定义测试():
打印(我是:,测试__姓名_ _)
@是_登录
def test1():
打印(我是:,测试1。__name__)
@是_登录
def test2():
打印(我是:,测试2。__name__)
if __name__==__main__ :
测试()
测试1()
测试2()运行结果:
我是:测试
我是:测试一
我是:测试2结论:
@wraps可以保证被装饰器修饰的函数的功能.__姓名_ _的值即函数名保持不变。
装饰器的优化以时间装饰器为例,进行优化
装饰器的统一模板从函数工具导入包装
# 对函数的装饰器,对类功能最好为清屏
定义装饰(功能):
@wraps(func)
# 增添或修改功能的函数
极好的包装(*args,**kwargs):
# 执行被装饰的函数
result=func(*args,**kwargs)
# 返回结果
回送结果
# 返回内层函数
返回包装普通-时间装饰器
从函数工具导入包装
导入时间
从随机导入产生均匀分布的随机整数矩阵
定义使用时间(函数):
@wraps(func)
极好的包装(*args,**kwargs):
st_time=time.time()
result=func(*args,**kwargs)
end_time=time.time()
打印(f"{ func .__name__}函数使用时间:{结束时间-最短时间}秒)
返回包装
@使用时间
def foo():
time.sleep(randint(1,3))
对于_在范围(3):
foo()运行结果:
富(中国姓氏)函数使用时间:3.01秒。16360.686686866667
富(中国姓氏)函数使用时间:1.0116651058197021s
富(中国姓氏)函数使用时间:1.0145542秒下面对改装饰器进行优化(解耦)可以发先上面时间装饰器计算的结果,只能在控制台上打印那我们怎样才能将它输出为日志呢?我们需要将他的结果进行自定输出# 在增加一层函数
从函数工具导入包装
导入时间
从随机导入产生均匀分布的随机整数矩阵
定义记录(输出):
定义使用时间(函数):
@wraps(func)
极好的包装(*args,**kwargs):
st_time=time.time()
func(*args,**kwargs)
end_time=time.time()
# print(f{func .__name__}函数使用时间:{结束时间-最短时间}秒)
输出(函数. name__, use ,end_time - st_time)
返回包装
返回使用时间
# 改装饰器的结果就可以自定义了,下面以打印函数为例
@记录(打印)
def foo():
time.sleep(randint(2,5))
if __name__==__main__ :
foo()结果输出日志
# 在增加一层函数
从函数工具导入包装
导入时间
从随机导入产生均匀分布的随机整数矩阵
定义记录(输出):
定义使用时间(函数):
@wraps(func)
极好的包装(*args,**kwargs):
st_time=time.time()
func(*args,**kwargs)
end_time=time.time()
# print(f{func .__name__}函数使用时间:{结束时间-最短时间}秒)
输出(函数. name__,end_time - st_time)
返回包装
返回使用时间
def write_log(名称,内容):
带开(。/time.log , a ,编码=utf-8 )作为女:
f。写(f"{ name }耗时:{content}\r\n) # \r\n换行
#只需将装饰器改为@record(write_log)
@record(write_log)
def foo():
time.sleep(randint(2,5))
if __name__==__main__ :
foo()
期待陌生,拥抱惊喜。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。