logging模块(* * * * *)

一 (简单应用)、

import logging  
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')  

输出:

WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

可见,默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默认的日志格式为日志级别:Logger名称:用户输出消息。

二  灵活配置日志级别,日志格式,输出位置

 1 import logging  
 2 logging.basicConfig(level=logging.DEBUG,  
 3                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
 4                     datefmt='%a, %d %b %Y %H:%M:%S',  
 5                     filename='/tmp/test.log',  
 6                     filemode='w')  
 7   
 8 logging.debug('debug message')  
 9 logging.info('info message')  
10 logging.warning('warning message')  
11 logging.error('error message')  
12 logging.critical('critical message')

查看输出:
cat /tmp/test.log 
Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message

可见在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。 
datefmt:指定日期时间格式。 
level:设置rootlogger(后边会讲解具体概念)的日志级别 
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息

三  logger对象

    上述几个例子中我们了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分别用以记录不同级别的日志信息),logging.basicConfig()(用默认日志格式(Formatter)为日志系统建立一个默认的流处理器(StreamHandler),设置基础配置(如日志级别等)并加到root logger(根Logger)中)这几个logging模块级别的函数,另外还有一个模块级别的函数是logging.getLogger([name])(返回一个logger对象,如果没有指定名字将返回root logger)

     先看一个最简单的过程:

 1 import logging
 2 
 3 logger = logging.getLogger()
 4 # 创建一个handler,用于写入日志文件
 5 fh = logging.FileHandler('test.log')
 6 
 7 # 再创建一个handler,用于输出到控制台
 8 ch = logging.StreamHandler()
 9 
10 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
11 
12 fh.setFormatter(formatter)
13 ch.setFormatter(formatter)
14 
15 logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
16 logger.addHandler(ch)
17 
18 logger.debug('logger debug message')
19 logger.info('logger info message')
20 logger.warning('logger warning message')
21 logger.error('logger error message')
22 logger.critical('logger critical message')

先简单介绍一下,logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。

     (1)

      Logger是一个树形层级结构,输出信息之前都要获得一个Logger(如果没有显示的获取则自动创建并使用root Logger,如第一个例子所示)。
      logger = logging.getLogger()返回一个默认的Logger也即root Logger,并应用默认的日志级别、Handler和Formatter设置。
当然也可以通过Logger.setLevel(lel)指定最低的日志级别,可用的日志级别有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。
      Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()输出不同级别的日志,只有日志等级大于或等于设置的日志级别的日志才会被输出。 

logger.debug('logger debug message')  
logger.info('logger info message')  
logger.warning('logger warning message')  
logger.error('logger error message')  
logger.critical('logger critical message') 

只输出了
2014-05-06 12:54:43,222 - root - WARNING - logger warning message
2014-05-06 12:54:43,223 - root - ERROR - logger error message
2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
     从这个输出可以看出logger = logging.getLogger()返回的Logger名为root。这里没有用logger.setLevel(logging.Debug)显示的为logger设置日志级别,所以使用默认的日志级别WARNIING,故结果只输出了大于等于WARNIING级别的信息。

     (2) 如果我们再创建两个logger对象: 

 1 ##################################################
 2 logger1 = logging.getLogger('mylogger')
 3 logger1.setLevel(logging.DEBUG)
 4 
 5 logger2 = logging.getLogger('mylogger')
 6 logger2.setLevel(logging.INFO)
 7 
 8 logger1.addHandler(fh)
 9 logger1.addHandler(ch)
10 
11 logger2.addHandler(fh)
12 logger2.addHandler(ch)
13 
14 logger1.debug('logger1 debug message')
15 logger1.info('logger1 info message')
16 logger1.warning('logger1 warning message')
17 logger1.error('logger1 error message')
18 logger1.critical('logger1 critical message')
19   
20 logger2.debug('logger2 debug message')
21 logger2.info('logger2 info message')
22 logger2.warning('logger2 warning message')
23 logger2.error('logger2 error message')
24 logger2.critical('logger2 critical message')

结果:

这里有两个个问题:

      <1>我们明明通过logger1.setLevel(logging.DEBUG)将logger1的日志级别设置为了DEBUG,为何显示的时候没有显示出DEBUG级别的日志信息,而是从INFO级别的日志开始显示呢?

       原来logger1和logger2对应的是同一个Logger实例,只要logging.getLogger(name)中名称参数name相同则返回的Logger实例就是同一个,且仅有一个,也即name与Logger实例一一对应。在logger2实例中通过logger2.setLevel(logging.INFO)设置mylogger的日志级别为logging.INFO,所以最后logger1的输出遵从了后来设置的日志级别。

      <2>为什么logger1、logger2对应的每个输出分别显示两次?
       这是因为我们通过logger = logging.getLogger()显示的创建了root Logger,而logger1 = logging.getLogger('mylogger')创建了root Logger的孩子(root.)mylogger,logger2同样。而孩子,孙子,重孙……既会将消息分发给他的handler进行处理也会传递给所有的祖先Logger处理。

        ok,那么现在我们把

# logger.addHandler(fh)

# logger.addHandler(ch)  注释掉,我们再来看效果:

因为我们注释了logger对象显示的位置,所以才用了默认方式,即标准输出方式。因为它的父级没有设置文件显示方式,所以在这里只打印了一次。

孩子,孙子,重孙……可逐层继承来自祖先的日志级别、Handler、Filter设置,也可以通过Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。设置自己特别的日志级别、Handler、Filter。若不设置则使用继承来的值。

<3>Filter
     限制只有满足过滤规则的日志才会输出。
     比如我们定义了filter = logging.Filter('a.b.c'),并将这个Filter添加到了一个Handler上,则使用该Handler的Logger中只有名字带          a.b.c前缀的Logger才能输出其日志。

 

     filter = logging.Filter('mylogger') 

     logger.addFilter(filter)

     这是只对logger这个对象进行筛选

     如果想对所有的对象进行筛选,则:

      filter = logging.Filter('mylogger') 

      fh.addFilter(filter)

      ch.addFilter(filter)

      这样,所有添加fh或者ch的logger对象都会进行筛选。

完整代码1:

 1 import logging
 2 
 3 logger = logging.getLogger()
 4 # 创建一个handler,用于写入日志文件
 5 fh = logging.FileHandler('test.log')
 6 
 7 # 再创建一个handler,用于输出到控制台
 8 ch = logging.StreamHandler()
 9 
10 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
11 
12 fh.setFormatter(formatter)
13 ch.setFormatter(formatter)
14 
15 # 定义一个filter
16 filter = logging.Filter('mylogger')
17 fh.addFilter(filter)
18 ch.addFilter(filter)
19 
20 # logger.addFilter(filter)
21 logger.addHandler(fh)
22 logger.addHandler(ch)
23 
24 
25 
26 
27 logger.setLevel(logging.DEBUG)
28 
29 logger.debug('logger debug message')
30 logger.info('logger info message')
31 logger.warning('logger warning message')
32 logger.error('logger error message')
33 logger.critical('logger critical message')
34 
35 ##################################################
36 logger1 = logging.getLogger('mylogger')
37 logger1.setLevel(logging.DEBUG)
38 
39 logger2 = logging.getLogger('mylogger')
40 logger2.setLevel(logging.INFO)
41 
42 logger1.addHandler(fh)
43 logger1.addHandler(ch)
44 
45 logger2.addHandler(fh)
46 logger2.addHandler(ch)
47 
48 logger1.debug('logger1 debug message')
49 logger1.info('logger1 info message')
50 logger1.warning('logger1 warning message')
51 logger1.error('logger1 error message')
52 logger1.critical('logger1 critical message')
53 
54 logger2.debug('logger2 debug message')
55 logger2.info('logger2 info message')
56 logger2.warning('logger2 warning message')
57 logger2.error('logger2 error message')
58 logger2.critical('logger2 critical message')
 1 #coding:utf-8  
 2 import logging  
 3   
 4 # 创建一个logger    
 5 logger = logging.getLogger()  
 6   
 7 logger1 = logging.getLogger('mylogger')  
 8 logger1.setLevel(logging.DEBUG)  
 9   
10 logger2 = logging.getLogger('mylogger')  
11 logger2.setLevel(logging.INFO)  
12   
13 logger3 = logging.getLogger('mylogger.child1')  
14 logger3.setLevel(logging.WARNING)  
15   
16 logger4 = logging.getLogger('mylogger.child1.child2')  
17 logger4.setLevel(logging.DEBUG)  
18   
19 logger5 = logging.getLogger('mylogger.child1.child2.child3')  
20 logger5.setLevel(logging.DEBUG)  
21   
22 # 创建一个handler,用于写入日志文件    
23 fh = logging.FileHandler('/tmp/test.log')  
24   
25 # 再创建一个handler,用于输出到控制台    
26 ch = logging.StreamHandler()  
27   
28 # 定义handler的输出格式formatter    
29 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')  
30 fh.setFormatter(formatter)  
31 ch.setFormatter(formatter)  
32   
33 #定义一个filter  
34 #filter = logging.Filter('mylogger.child1.child2')  
35 #fh.addFilter(filter)    
36   
37 # 给logger添加handler    
38 #logger.addFilter(filter)  
39 logger.addHandler(fh)  
40 logger.addHandler(ch)  
41   
42 #logger1.addFilter(filter)  
43 logger1.addHandler(fh)  
44 logger1.addHandler(ch)  
45   
46 logger2.addHandler(fh)  
47 logger2.addHandler(ch)  
48   
49 #logger3.addFilter(filter)  
50 logger3.addHandler(fh)  
51 logger3.addHandler(ch)  
52   
53 #logger4.addFilter(filter)  
54 logger4.addHandler(fh)  
55 logger4.addHandler(ch)  
56   
57 logger5.addHandler(fh)  
58 logger5.addHandler(ch)  
59   
60 # 记录一条日志    
61 logger.debug('logger debug message')  
62 logger.info('logger info message')  
63 logger.warning('logger warning message')  
64 logger.error('logger error message')  
65 logger.critical('logger critical message')  
66   
67 logger1.debug('logger1 debug message')  
68 logger1.info('logger1 info message')  
69 logger1.warning('logger1 warning message')  
70 logger1.error('logger1 error message')  
71 logger1.critical('logger1 critical message')  
72   
73 logger2.debug('logger2 debug message')  
74 logger2.info('logger2 info message')  
75 logger2.warning('logger2 warning message')  
76 logger2.error('logger2 error message')  
77 logger2.critical('logger2 critical message')  
78   
79 logger3.debug('logger3 debug message')  
80 logger3.info('logger3 info message')  
81 logger3.warning('logger3 warning message')  
82 logger3.error('logger3 error message')  
83 logger3.critical('logger3 critical message')  
84   
85 logger4.debug('logger4 debug message')  
86 logger4.info('logger4 info message')  
87 logger4.warning('logger4 warning message')  
88 logger4.error('logger4 error message')  
89 logger4.critical('logger4 critical message')  
90   
91 logger5.debug('logger5 debug message')  
92 logger5.info('logger5 info message')  
93 logger5.warning('logger5 warning message')  
94 logger5.error('logger5 error message')  
95 logger5.critical('logger5 critical message')  
 1 import os
 2 import time
 3 import logging
 4 from config import settings
 5 
 6 
 7 def get_logger(card_num, struct_time):
 8 
 9     if struct_time.tm_mday < 23:
10         file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon, 22)
11     else:
12         file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon+1, 22)
13 
14     file_handler = logging.FileHandler(
15         os.path.join(settings.USER_DIR_FOLDER, card_num, 'record', file_name),
16         encoding='utf-8'
17     )
18     fmt = logging.Formatter(fmt="%(asctime)s :  %(message)s")
19     file_handler.setFormatter(fmt)
20 
21     logger1 = logging.Logger('user_logger', level=logging.INFO)
22     logger1.addHandler(file_handler)
23     return logger1

原文链接:https://www.cnblogs.com/yuanchenqi/articles/5732581.html

转载于:https://www.cnblogs.com/jiawen010/p/9917082.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/484813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

业界首个!华为联合中国信通院等发布《网络体系强基展望白皮书》

来源&#xff1a; 华为数据通信编辑&#xff1a; 杨盼近日&#xff0c;华为联合中国信息通信研究院等单位&#xff0c;共同发布《网络体系强基展望白皮书》(以下简称《白皮书》)。《网络体系强基展望白皮书》从工业网络现状、趋势和需求出发&#xff0c;首次提出了“工业设备网…

【原】Win SQL Server2012 IIS 安装(图文详解)

1、进入服务器管理&#xff0c;点击添加“添加角色和功能” 2、单击“安装类型”&#xff0c;然后选择“基于角色或者功能得安装”&#xff0c;单击下一步 3、选择“从服务器池中选择服务器”&#xff0c;单击下一步 4、在角色列表里面找到“Web服务器(IIS)”&#xff0c;并勾选…

终极孵化器:仿生婴儿的美丽新世界

Conceptual Photograph: The Voorhes来源&#xff1a; IEEE电气电子工程师子宫是人类生物学中最复杂的构造之一&#xff1a;可以帮助完成从胚胎到胎儿再到婴儿的壮举。但是如果没有胎盘&#xff0c;这种巨大的转化也是不可能实现的&#xff0c;胎盘是一种赋予生命的器官&#x…

学界丨北大清华合力打造通用人工智能实验班,朱松纯教授领衔

来源&#xff1a;北京大学微信公众号、AI科技评论、新智元据悉&#xff0c;首批北大通班同学已经开课&#xff0c;清华通班也已启动首批招生。师资方面&#xff0c;清华和北大各有优势学科&#xff0c;在通班的合作上可以优势互补&#xff1b;在平台方面&#xff0c;以朱松纯教…

struts2_模型驱动

一.注意点 建立实现ModelDriven接口的action类在该action类中,创建实体对象并new在getModel返回该对象在显示页面中提交的表单name正常写二.案例 创建实体类User: package com.ahd.entity;import com.opensymphony.xwork2.ModelDriven;public class User{private String userna…

美智库预言特斯拉十年内退出中国:已踩红线,谷歌就是前车之鉴

来源&#xff1a;厚势汽车编辑&#xff1a;琪琪2020 年年末&#xff0c;在经历了 8 年的发展期后&#xff0c;特斯拉终于在中国市场站稳了脚跟。2020 年销售暴涨&#xff0c;在中国电动车市场占比达到 21% &#xff0c;全球仅第四季度就交付 18 万辆电动车&#xff0c;相对于第…

222页斯坦福人工智能报告出炉:全球AI投资猛增680亿,北美博士学术机构就业率下降

来源&#xff1a;中国自动化学会编辑 ∑Gemini1、我们生活在一个「人工智能」的时代如图所示&#xff0c;人工智能的研究正在蓬勃发展&#xff1a;在2019年&#xff0c;全球发表了超过12万篇的AI论文。在2000年至2019年之间&#xff0c;人工智能的论文占所有同行评审论文的比例…

量子理论的哲学宣言

来源&#xff1a;《中国社会科学》2019年第2期作者&#xff1a;成素梅&#xff08;上海社会科学院&#xff09;本文为国家社会科学基金重大项目“当代量子论与新科学哲学的兴起”(16ZDA113)阶段性成果。关于量子理论的哲学研究有两个层次&#xff0c;一是根据量子理论及其技术的…

2050大会走向通用人工智能专场总结

来源&#xff1a;混沌巡洋舰这两天主持了阿里云A组召集的杭州云栖小镇的2050大会《走向更加通用的人工智能》专场。活动分为论坛和深度交流两部分。也邀请了来自神经符号&#xff0c;类脑计算&#xff0c;复杂系统的很多朋友共同交流。我觉得如果来总结这个主题&#xff0c; 我…

一种基于平衡二叉树(AVL树)插入、查找和删除的简易图书管理系统

目录1. 需求分析2. 项目核心设计2.1 结点插入2.2 结点删除3 测试结果4 总结分析4.1 调试过程中的问题是如何解决的&#xff0c;以及对设计与实现的回顾讨论和分析4.2 算法的时间和空间复杂度的分析&#xff0c;以及进一步改进的设想4.3 本次实验的经验和体会5 完整代码(C)1. 需…

物联网产业104页深度研究报告:物联网研究框架与投资机会分析

报告出品方&#xff1a;国信证券作者&#xff1a;马成龙、付晓钦、陈彤1物联网是未来五年甚至十年的大赛道1.1 物联网&#xff1a;下一代网络网络革命的本质是连接主体和连接方式的变化&#xff1a;第一代互联网&#xff08;PC互联网&#xff09;是计算机与计算机之间的联网&am…

随笔:朋友圈扫街图有感(爱情)

#声明&#xff1a;照片来自我的一位甘姓友人&#xff0c;并非本人所拍。但为之感动&#xff0c;尤其震撼。 皮夹里老照片上恰风华正茂的少年&#xff0c;但如今一双褶皱的手&#xff0c;缓缓掏出过了时的纸币&#xff0c;无疑岁月蹉跎&#xff0c;当年的Ta早已成了耄耋老人。说…

浅谈SDN架构下的运维工作

导读目前国内的网络运维还处于初级阶段&#xff0c;工作人员每天就像救火一样&#xff0c;天天疲于奔命。运维人员只能埋头查找系统运行的日志&#xff0c;耗时耗力&#xff0c;老眼昏花不说&#xff0c;有时候忙了半天还一无所获&#xff0c;作为运维工程师的你&#xff0c;有…

华为自动驾驶实车实路测试视频曝光!徐直军:比特斯拉好多了

资料来源&#xff1a;量子位、物联网智库等整理发布&#xff1a;物联网智库 昨日&#xff08;4月15日&#xff09;&#xff0c;消息称配备华为自动驾驶技术的北汽新能源极狐阿尔法S的HI版车型在上海进行了公开试乘&#xff0c;这也是华为自动驾驶技术公开试乘的全球首秀。以下视…

Pycharm社区版运行Django的三种方法(Pycharm添加配置参数快捷启动Django、Pycharm社区版Django项目创建)

目录Pycharm社区版运行Django的三种方法Django安装和环境变量的配置&#xff08;MacOS&#xff09;创建Project启动Django Webserver方法一&#xff1a;终端启动方法二&#xff1a;pycharm项目界面启动方法三&#xff1a;pycharm社区版实现直接启动Pycharm社区版运行Django的三…

日本机器人全球领先来自这三大顶尖技术

来源&#xff1a;工业机器人▍日本尖端技术之一&#xff1a;机器人精密减速机世界上工业机器人使用的精密减速机几乎都为日本所垄断。尽管国内也量产的RV减速机&#xff0c;但国产机器人企业却鲜有选用的&#xff0c;原因是日本精密减速机技术遥遥领先&#xff0c;短期很难替代…

仰望星空后,更将脚踏实地!

仰望星空后&#xff0c;更将脚踏实地&#xff01;

在目标检测中如何解决小目标的问题?

作者&#xff1a;Nabil MADALI来源&#xff1a;AI公园编译&#xff1a;ronghuaiyang在深度学习目标检测中&#xff0c;特别是人脸检测中&#xff0c;由于分辨率低、图像模糊、信息少、噪声多&#xff0c;小目标和小人脸的检测一直是一个实用和常见的难点问题。然而&#xff0c;…

python学习之路day02

一、.pyc是什么&#xff1f; 1. Python是一门解释型语言&#xff1f; 我初学Python时&#xff0c;听到的关于Python的第一句话就是&#xff0c;Python是一门解释性语言&#xff0c;我就这样一直相信下去&#xff0c;直到发现了*.pyc文件的存在。如果是解释型语言&#xff0c;那…

像人一样自然流畅地说话,下一代智能对话系统还有多长的路要走?

来源&#xff1a;机器之心机器之心编辑部作为人工智能的一个子领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;指的是机器理解并解释人类书面语和口语的能力&#xff0c;目的在于使计算机像人类一样智能地理解语言和用语言表达&#xff0c;弥补人类交流&#xff08;自…