2019/12/30 04-日志流、Formater、Filter

logging.info实际上真正工作的时候logger,跟logger是所有logger祖先,祖先下面可以产生一些logger,用工厂方法getlogger,会得到一个logger实例,getlogger()是拿到跟logger,得到跟logger两种方式(logging,root,getlogger()),logger就形成了体系结构,跟logger在最上面,就需要使用.点号父子关系\

在某一个logger调用info,就需要看这个logger对象的有效的level,如果大于等于这个有效level就可以输出日志,每一个logger都可以有自己的level,设定有效level就变成自己的,没设定就是用最近的父的
在这里插入图片描述现在给了filename,控制台就不输出信息了,想要控制台也输出
在这里插入图片描述在这里插入图片描述
handler是控制信息输出的目的地,可以是控制台或者文件,handler(处理器),这个处理器可以有自己的level跟logger的level是两码事。
可以单独设置格式,可以设置过滤器。
logger是不干活的,真正干活的是handler,只不过有些时候忽略handler

在这里插入图片描述
handler的继承
streamHandler 流式,默认把数据放到stderr,什么都不写,把数据输出到stderr
handler有两个子类,FileHandler文件(往文件写),_StderrHandler标准输出
日志输出其实都是handler做的,其实不是logger,logger应该有handler

在这里插入图片描述
root应该有handler,而且不止一个,问root的handler=0,说明下面要做很多在这里插入图片描述
跟logger也是logger
这就说明handler可以不止一个
在这里插入图片描述
问root的handler如果等于0,len(root.handlers )==0
做下面一大堆事情
如果handler是none,stream和filename,在里面就抛出异常
在这里插入图片描述
如果handler是none,有一个在,就出问题
在这里插入图片描述
if filename,代表filename不是空字符串,创建filehandler,否则创建stream handler,root logger什么都没做都要生成rootloger,logger没有handler是不行的,就创建stream handler,就是把你的日志输出到控制台上去在这里插入图片描述
streamhandler,默认显示红色的就是因为错误输出在这里插入图片描述
给了文件路径就不会创建stream handler,就不往控制台输出了
在这里插入图片描述
filehandler继承自stream handler,
只要记住给了文件名就是filehandler,没给就是streamhandle,streamhandler默认标准错误输出r

在这里插入图片描述
如果想要变成标准输出,把none改成sys.stdout即可在这里插入图片描述
把参数中凑出一个handler,把handler扔到列表里去,把列表给了handlers
在这里插入图片描述
handler我们能打印格式,handler被setFormatter,如果level不是none,就setlevel
在这里插入图片描述把我们写入format,这个参数是kwargs
在这里插入图片描述
从kwargs把format弹出,给fs用,然后用formatter构造一个格式fmt,把这个格式化器,就给handler
在这里插入图片描述
如果给的level不是none,就给一个不是root.level的级别,把我们写的level传进去
在这里插入图片描述在这里插入图片描述
真正干活的是handler,但是handler可以单独设置level,可以单独设置格式(通过format产生(来源于我们format传参)),可以设置设置过滤器
在这里插入图片描述
现在生产的handler放到一个列表中,也就是这个列表里只有一个元素,如果 handlers不是none,就不创建(需要提供一个列表)在这里插入图片描述
跟logger至少有一个handler,设置文件名会输出filehandler,没有就是streamhandler
在这里插入图片描述、没有handler但是确实能打印,就跟他的流有关系在这里插入图片描述

创建的handler的初始的level是什么

在这里插入图片描述
getlogger如果名字没有返回root,这个root就是rootlogger,否则就到.logger.manager里面在这里插入图片描述
是把logger放到字典里通过名字来找在这里插入图片描述
这就是实例化,logger类,创建出一个rv,然后往下加到字典中去在这里插入图片描述创建出一个rv,然后往下加到字典中去在这里插入图片描述
logger类里,要检查下你给的名词,checklevel,是否是合法范围,level的缺省值是NOTSET,没设定在这里插入图片描述
一个logger在创建的过程中,默认创建的是0

rootlogger,这个level会在1731行改成warning
在这里插入图片描述
logger在创建的时候,设定的level,默认是0,创建handler默认是空的,getlogger,这个logger对象,就需要创建这个logger对象,这个logger对象的handlers竟然是个空列表,在这里插入图片描述
这样就没有handler,就可以用父的,也可以不用在这里插入图片描述下面创建一个filehandler,addhandler,给空列条塞一个handler进去
在这里插入图片描述
上面是streamhandler,下面是加了一个filehandler在这里插入图片描述在这里插入图片描述
handler没指定格式
在这里插入图片描述
说明,格式就是%(message)s,现在既可以在控台输出,又可以文件里输出在这里插入图片描述
现在handler级别没设定在这里插入图片描述
filehandler是log1的,那么控制台这行是谁打的,其实是root打印的在这里插入图片描述
line2按照集成线路走到filehandler里了,这条数据又到了streamhandler里面 了在这里插入图片描述
没有filehandler就没有文件,但是在streamhandler里有
在这里插入图片描述
执行一下看看,在这里插入图片描述
没有输出因为是w,w一下会把文件清空
在这里插入图片描述在这里插入图片描述
这样就有了
在这里插入图片描述
也就是handler有自己的level
但是logger也有自己的level

在这里插入图片描述

日志流

在这里插入图片描述
logger的level,自己设定就拿自己的,不然就从最近的父的拿
s . s1多了空格没有父子关系了
在这里插入图片描述
现在就有父子关系了
在这里插入图片描述在这里插入图片描述
日志在哪个logger产生,就需要先过自己的一关
在这里插入图片描述在这里插入图片描述

继承关系及信息传递

logger日志想流进来,首先在哪个logger产生,就要在哪个logger级别进行对比,如果这个门槛太高,信息就进不来,
在这里插入图片描述
如果没有设置就用最近的父,root默认在1731行死warning
在这里插入图片描述

流转过程很重要

在这里插入图片描述
产生消息的级别,就要和当前logger的Effectivelevel有效级别进行比较,如果低于当前logger的有效等级,就流程结束(自己这关都过不了),否则就生成log记录。
2.这个记录会交给当前logger的所有handler处理

log1下面有三个handler,handler默认几倍是noset=0,,所以这个消息先对比log1等级,然后转发给三个handler进行比较,handler级别如果高于消息的级别,handler就对这个记录没有反应
在这里插入图片描述
propagate传递传播的意思
当前logger的所有handler处理完,就要看自己的propagate属性,如果是True表示向父logger传递这个日志记录,否则到此流程结束,(这个就是开关)

在这里插入图片描述
如果日志记录传递到了父logger,不需要和父logger的level比较,而是直接交给父的所有handler,父logger成为当前logger。重复2、3步骤,直到当前logger的父logger是None退出(最后跑到rootlogger),也就是说当前logger最后一般是root logger(是否能到root logger要看中间logger是否允许propagate)
在这里插入图片描述

,log1.info生成日志记录,向所有的handler进行发送,凡是没有handler,就需要看propagate,如果是true,则向root传递。,传递给父logger,不需要和父logger的level进行比较,直接将信息传递给所以的父的handler
在这里插入图片描述
**
按照道理,log1传递给了error就看不到了,说明没有跟logging.error比较**在这里插入图片描述
这个函数创建了一个handler列表,这个会根据filename有没有,创建fileheandler还是streamhandler
在这里插入图片描述
查看logger类
在这里插入图片描述在这里插入图片描述
也就是用getlogger取到的,propagate=TRUE,默认都有传递行为,都会向父一级进行传递在这里插入图片描述
这样就传不到root上去 了
在这里插入图片描述
logger实例初始的propagate属性为true,即允许向父logger传递消息在这里插入图片描述
如果root没有handler,就默认创建一个StreamHandler,如果设置了filename,就创建一个FileHandler。如果设置了format参数,就会用它生成一个formatter对象,并把这个formatter加入到刚才创建的handler上(没有设置format参数,就会自己创建一个,只不过就一个message),然后把这些handler加入到root.handlers列表上。level是设置给root logger的。
如果root.handlers列表不为空,logging.basicConfig的调用什么都不做。

在这里插入图片描述在这里插入图片描述
要是没有这句话,root都没有handler在这里插入图片描述
这样就没有handler,没有handler就什么都没打印出来
在这里插入图片描述

日志流转图

在这里插入图片描述在这里插入图片描述
日志信息来跟logger的level进行比较,,不能通过就stop,可以就创建一个日志记录在这里插入图片描述
日志记录就需要过滤,过滤不通过结束,通过,向下,reject是反义的
在这里插入图片描述
如果这个日志记录通过自己logger的level,然后pass to到current logger,给当前logger的所有handler发送,所有handler处理完,把这些handler都遍历完以后,就继续向下做,问是否需要传递,不传递就结束了,传递就传递给自己的parent logger父logger,如果没有父logger就结束,有自己的父logger就将当前logger设定自己的parent在这里插入图片描述
这样parent就设定成自己的当前logger了,发给当前logger的handler,不跟有效level比较了
在这里插入图片描述
接写来时发给handler的整个过程,把记录发给handler,handler把这个记录跟自己的level进行比较,不合适就stop,yes就到了过滤器,过滤不成功stop,yes就向后继续跑
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
c就是current,如果propagate时true,就进不来这里,等于none就不进循环了在这里插入图片描述
遍历所有handler,拿handler的level和你日志记录的level进行比较在这里插入图片描述
这是logger的在这里插入图片描述在这里插入图片描述
将root定义INFO级别,格式如下
在这里插入图片描述
root重新设定级别到error
在这里插入图片描述
准备创建一个streamhandler,默认是到stderr
在这里插入图片描述
两个handler,打印出来是不一样的,在这里插入图片描述在这里插入图片描述
两次就发生变化了
一个级别没设定,一个级别被修改成了warning,这是handler的级别,不是root.logger的级别
在这里插入图片描述
打印不出来信息,查看当前有效level在这里插入图片描述
注释掉临时设定的error,就打印一条,下面的还是过不去在这里插入图片描述
改成warning就能出现两条信息,没设定handler,默认就打印message
在这里插入图片描述
缺省的root,一样可以捆绑多个handler,它给自己创建一个默认stream,也可以添加一个filehandler
在这里插入图片描述
查看下面这一段在这里插入图片描述
创建一个log1 logger对象,添加一个handler,里面就一个handler
在这里插入图片描述
继续下面一段
在这里插入图片描述
log3中没有handler,warning消息到达log2,log2的logger的level无效,看handler的等级,也就是test.log文件里应该有数据
在这里插入图片描述在这里插入图片描述
没有设定propagate,继续向后传,s的handler还是warning也会往test.log文件里面写,所以消息就有两条,也可以给这两个设定不同的format对象在这里插入图片描述
看到三个stderr,下面的是h0打 的,上面是root打的在这里插入图片描述
Formatter是一个类,允许指定某个格式的字符串,如果是none就打印message在这里插入图片描述
会root缺省的streamhandler定义的格式
在这里插入图片描述在这里插入图片描述
这时候把格式送给h2在这里插入图片描述
等于logging下面有Formatter类
在这里插入图片描述
**再运行一次,每一个handler都可以设定level,每个handler都可以设定自己的format
**
在这里插入图片描述
addhandler,表示handler可以往容器里加,而setformatter只能再handler上加一次

filter

filter可以增加过滤器,过滤器之后影响某一个handler,不会影响整个处理流程,但是,如果过滤器加到logger上,就会影响流程
在这里插入图片描述
这个跟logger相关的filter如果过不起,就到不了handler,
logger的filter通不过,就没有后面的流转了
在这里插入图片描述
每一个handler里面是可以再加filter,handler可以给自己加level,format,filter
在这里插入图片描述
再h2上加了个filter,h2是再log2上面的,也就是只影响log2下的h2的过滤在这里插入图片描述
先跟level比较,比完了再跟filter比较在这里插入图片描述
传递过来就需要所有的handler来过滤,所以handler的filter就起作用了在这里插入图片描述
这个过滤器就会判断下,这个过滤器是谁,是s开头的所有日志信息的,因为这是跟s相关的所有logger产生的在这里插入图片描述
消息产生后,会有s.s1的名字,名字就是record name,这个名字就可以过滤在这里插入图片描述
在现在这个记录当中去kan 's’这个名字,从0开始到name的长度!=0(在一个字符串中,从头定死开始找,)
在这里插入图片描述在这里插入图片描述
从0开始找第一个字符,如果第一个字符能够找到就行,find不会抛出异常,找不到了-1,找不到爱什么是什么,(找到的索引值之能是0,所以!=0)在这里插入图片描述
这两句相等
在这里插入图片描述
如果用log2发出的记录的日志,都是s.s1,在过这个过滤器的时候,是可以通过的。前缀匹配能匹配到
在这里插入图片描述在这里插入图片描述
filter用的较少

在这里插入图片描述
logging模块,有几个有难点,有效级别,handler(handler可以有自己的format,filter,level)
如果偷懒每个logger都不用了,直接所有模块都是logging.,不偷懒,就是logging.getlogger(name)拿这个模块名创建一个当前的独自的logger,一般更多是把数据发到file当中去,日志文件是查问题的地方

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值