查看原文
其他

Python标准库-logging模块(2) logging模块的四大组件

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:李金洋

本文编辑:胡   婧

技术总编:张学人

爬虫俱乐部将于2019年1月19日至25日在武汉举行两期Stata编程技术定制培训,此次采取初级班和高级班分批次培训模式,采用理论与案例相结合的方式,旨在帮助大家熟悉Stata核心的爬虫技术,以及Stata与其他软件交互的高端技术。详细培训大纲及报名方式,请见往期推文《2019寒假Stata编程技术定制培训班》。报名表下载请点击文末阅读原文呦~

欢迎大家来到Python知识小讲堂,今天我们继续为大家介绍logging模块的内容。

考虑如下情境:假如我们要记录程序运行的日志,我们希望将全部日志信息保存到日志文件中,以备来日索查,同时,我们希望将比较严重的事件在控制台上输出,那么,我们需要通过设置不同的日志输出级别来实现这一需求。那么我们要怎么做呢?当然,我们可以设计两个函数,利用上一篇推文介绍的logging模块级别的函数来分别实现这两个需求,但作为一个专业的pythoner~,这样的做法实在是不够优雅简洁。因此,我们使用logging模块提供了另一种记录日志的方式,即使用logging日志系统的四大组件,来实现这一功能。

logging模块将日志系统从高向低依次定义了四个类,分别是logger(日志器)、handler(处理器)、filter(过滤器)和formatter(格式器)。其中,由日志器生成的实例将接管原本日志记录函数logging.log的功能。假定我们原计划使用logging.log记录一则日志消息,那么logger的完成方法如下:

loggertest=logging.getLogger() #定义logger实例
loggertest.error('lemon juice')

即我们通过logger生成一个实例loggertest,再通过loggertest输出日志记录。

那么这样做的意义在哪里呢?其中最显而易见的好处就是,我们将程序的日志信息按日志器进行了分类,假定我们的程序需要记录三份测试内容不同的日志,则我们可以通过定义三个logger实例,并在程序的相应位置使用相应的实例进行记录输出即可。

但是对于本文中的需求,即同一份日志记录,不同级别内容输出,我们还需要用到低一层的组件,即处理器handler,处理器生成的实例不能独立存在,必须从属于某一确定的logger实例,用于处理该日志器接收的所有信息,按要求输出至指定位置。迷人的是,一个logger实例可以包含有若干个处理器,这些处理器接收到了一样的输入内容,并按其设定的不同过滤规则输出至不同位置,这也就达到了我们需求中的一份输出,N份不同等级的日志输出。其核心代码如下

#文件日志处理器
file_happy = logging.FileHandler("test.log","w") file_happy.setFormatter(formatter)  #通过setFormatter指定输出格式
file_happy.setLevel(logging.DEBUG) #设置log文件的最低输出级别为DEBUG
#控制台日志处理器
console_happy=logging.StreamHandler(sys.stderr) console_happy.setFormatter(formatter) console_happy.setLevel(logging.WARNING) #设定控制台最低输出级别为WARNING
#日志器
loggertest=logging.getLogger() #定义logger实例
loggertest.setLevel(logging.DEBUG) #设定日志器的日志最低输出级别为DEBUG
loggertest.addHandler(file_happy) loggertest.addHandler(console_happy)

在这段演示代码里,我们定义了两个处理器,一个处理器将输出流指向控制台,另一个指向某日志文件,并使用logger的实例loggertest将其均添加进来。

现在,我们可以将上述核心代码照抄到下方,来完成这个例子,再在随后进行更细的讲解,假如晶晶同学想喝杯饮料,但是选择困难症爆发,我们可以使用随机数的方式帮助她做出选择,程序如下:

#导入所用模块
import logging
import sys
import os
import random os.chdir('E:/财大/爬虫俱乐部/推文/python-logging模块')
#指定输出格式
formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s')
#文件日志
file_happy = logging.FileHandler("test.log","w") file_happy.setFormatter(formatter)  #通过setFormatter指定输出格式
file_happy.setLevel(logging.DEBUG) #设置log文件的最低输出级别为DEBUG
#控制台日志
console_happy=logging.StreamHandler(sys.stderr) console_happy.setFormatter(formatter) console_happy.setLevel(logging.WARNING) #设定控制台最低输出级别为WARNING
#为loggertest添加handler
loggertest=logging.getLogger() #定义logger实例
loggertest.setLevel(logging.DEBUG) #设定日志器的日志最低输出级别为DEBUG
loggertest.addHandler(file_happy) loggertest.addHandler(console_happy) i=1
while i<5:  #设置4次循环    numb=random.random() #生成0-1之间的随机数    if numb<0.2:        loggertest.debug("soda water")    
   elif numb<0.4:        loggertest.info('lemon juice')    
   elif numb<0.6:        loggertest.warning('cappuccino')    
   elif numb<0.8:        loggertest.error('hot chocolate')    
   else:        loggertest.critical('IceCola')    i=i+1

在log文件中,我们保存下来了全部的日志记录

但在控制台中,只输出了WARNING级别以上的日志记录

从上述例子可以看出,日志信息同时输出到了log文件控制台,并且实现了不同设置级别的输出

在经过上面关于logger和handler的非正式介绍后,我们正式为大家介绍logging模块四大组件的概念相应用法

表1  logging模块的四大组件

通常来讲,在一个logger对象中,我们可以创建多个handler,对每一个handler设置不同的输出配置,如日志级别、输出位置等。同时,我们还可以对每个handler设置不同的过滤条件和输出格式,这样,就可以实现多样化的日志输出需求,这也是四大组件的基本工作流程。

爬虫俱乐部是您身边的科研助手,能够为您在数据处理实证研究中提供帮助。承蒙30000+粉丝的支持与厚爱,我们在腾讯课堂推出了网络视频课程,专注于数据整理、网络爬虫、循环命令编制和结果输出…李老师及团队精彩地讲解,深入浅出,注重案例与实战,让您更加快速高效地掌握Stata技巧及数据处理的精髓,而且可以无限次重复观看,百分百好评,简单易学,一个月让您从入门到精通。绝对物超所值!观看学习网址:https://ke.qq.com/course/286526?tuin=1b60b462,敬请关注!

四大组件的常见用法如下:

1. logger类:logger用于提供日志接口,常用于配置和发送日志消息。我们一般使用logging.getLogger(name)方法来获得一个logger对象。其中,可选参数name指定日志器名称,默认为“root”。常用方法包括:

logger.setLevel() :设置日志器处理日志信息的最低级别

logger.addHandler():为该logger对象添加一个handler对象

logger.removeHandler():为该logger对象添加移除一个handler对象

logger.addFilter():为该logger对象添加一个filter对象

logger.removeFilter():为该logger对象移除一个filter对象

logger.debug(),logger.info(),logger.warning(),logger.error(),logger.critical():创建一个对应等级的日志记录

logger.log():获取一个日志level参数来创建一个日志记录

2. handler类:handler对象用于将指定的日志信息发送到指定的位置。一个logger对象可以添加多个handler,每个handler又可以定义不同日志级别,以实现日志分级过滤显示。通过handler,我们可以将日志同时输出到多个位置。常用的方法包括:

handler.setLevel():设置handler处理的日志信息最低级别

handler.setFormatter():为handler设置一个格式器对象

handler.addFilter():为handler添加一个过滤器对象

handler.removeFilter():为handler删除一个过滤器对象

logging.StreamHandler():将日志信息发送到Stream

logging.FileHandler():将日志消息发送到磁盘文件

注:在上例中,我们对于日志输出级别的设置共进行了三次,分别是:

file_happy.setLevel(logging.DEBUG) #设置log文件的最低输出级别为DEBUG
console_happy.setLevel(logging.WARNING) #设定控制台最低输出级别为WARNING
loggertest.setLevel(logging.DEBUG) #设定日志器的日志最低输出级别为DEBUG

上例中,DEBUG级别以上的信息全部输出到log文件中,而控制台中只输出了WARNING级别以上的信息。那么,或许会有读者产生疑问:为什么还要对日志器的日志最低输出级别进行设置呢?只针对不同的handler设置不就可以了吗?

在这里需要注意的是,无论是logger还是handler实例,它们都可以设置日志的最低输出级别,但是如果logger层面的最低输出级别是高级别(如DEBUG),那么其内部的处理器就不会接收到低于该级别的日志信息(如INFO会在日志器层面即被挡在外面),因此在设置各实例输出级别时需要小心谨慎。

因此,在上述程序运行时,低于logger对象设置的日志输出级别的信息不会被传送到handler中。换言之,如果我们不将logger的输出级别设置成DEBUG,其默认的输出级别就是WARNING,那么低于WARNING级别的信息会首先被过滤掉,那么,handler接收到的信息就全部是高于WARNING级别的不完整的信息了。

3. filter类:filter是一个过滤器,可以实现比logger和handle更细致灵活的过滤功能。

4. formatter类:formatter对象用来输出格式化字符串,构造方法如下:

logging.Formatter.__init__(fmt=None, datefmt=None)

其中:

fmt:指定信息的格式化字符串,如不设定则使用信息的原始字符串

datefmt:指定日期的格式化字符串,如不设定则使用默认格式"%Y-%m-%d %H:%M:%S"

了解了四大组件的基本定义之后,我们通过图示的方式来理解下信息的传递过程:

至此,关于logging模块的常见用法就已经为大家介绍完毕了。由上述介绍可知,logging模块的函数和组件具有部分相同的功能,但在实际操作中,日志组件能够对logging进行更多灵活的控制,希望大家能够多多练习,以充分掌握该模块的用途(^_^)。

参考学习资料

① Python标准库文件:https://docs.python.org/3/library/logging.html#module-logging

② CSDN博客——Python之日志处理(logging模块):https://www.cnblogs.com/yyds/p/6901864.html

③ 往期推文:python 第三天:条件判断与循环语句

④ 往期推文:python第四天:拒绝重复,while循环

⑤ 往期推文:python标准库:random生成随机数

有问题,不要怕!访问 

http://www.wuhanstring.com/uploads/5_aboutus/爬虫俱乐部-用户问题登记表.docx (复制到浏览器中)下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱statatraining@163.com,我们会及时为您解答哟~

爬虫俱乐部的github主站正式上线了!我们的网站地址是:https://stata-club.github.io,粉丝们可以通过该网站访问过去的推文哟~

爬虫俱乐部隆重推出数据定制及处理业务,您有任何网页数据获取及处理方面的难题,请发邮件至我们邮箱statatraining@163.com,届时会有俱乐部高级会员为您排忧解难!

对爬虫俱乐部的推文累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫!

往期推文推荐

关于我们

微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。


此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存