Python开发之日志记录模块:logging(7)

在开发过程中,经常出现多个模块都需要记录日志的情况,也许你想到的做法是在一个模块中配置好一个logger并实例化,在需要用到的模块中进行导入,但如果不同模块的日志器配置有区别时,这种方法就不适用了,若是为每个模块都定义一个logger,所有配置都需要重新写入,有些繁琐。还记得上文中提到logging的日志器可以通过name属性进行分层吗?子日志器可以继承父日志器的配置,也可以重新配置,这就是logging给我们提供的多模块共享日志的解决方案。看代码:

模块main.py中的代码:

import logging import log_child logger = logging.getLogger('main') logger.setLevel(logging.DEBUG) fmt = '%(name)s , %(asctime)s , %(levelname)s , %(filename)s %(funcName)s line %(lineno)s , %(message)s' datefmt = '%Y-%m-%d %H:%M:%S %a' log_fmt = logging.Formatter(fmt=fmt, datefmt=datefmt) handler = logging.FileHandler('./.log',encoding='utf-8') handler.setFormatter(log_fmt) logger.addHandler(handler) if __name__=='__main__': logger.debug('Running …') log_child.fun_child()

模块child_log.py中的代码:

 

import logging logger = logging.getLogger('main.child') logger.setLevel(logging.DEBUG) def fun_child(): try: logger.info('Running …') 1 / 0 except Exception as e: logger.exception(e)

运行main.py后,.log文件会被写入���下内容:

main , 2019-03-29 20:23:32 Fri , DEBUG , main.py <module> line 16 , Running …

main.child , 2019-03-29 20:23:32 Fri , INFO , log_child.py fun_child line 7 , Running …

main.child , 2019-03-29 20:23:32 Fri , ERROR , log_child.py fun_child line 10 , division by zero

Traceback (most recent call last):

File "E:\myCode\test1\log_child.py", line 8, in fun_child

1 / 0

ZeroDivisionError: division by zero

4.3 使用配置文件配置logger

我们之前的程序中都是将对logger的配置一并写在程序中,但事实上,采用配置化编程的方式,将对logger的配置写在专门的配置文件中,例如写入json文件、conf文件、yaml文件等文件中,当需要实例化logger时,读取即可。下面以conf文件为例,通过代码注释的方式,介绍logging配置文件的书写方式。配置文件log.conf如下:

 

[loggers] #固定写法,定义logger的模块 keys=root,log_1,log_2 #创建三个logger,root是父类,必需存在的,其他两个logger的name分别为 [logger_root] # 定制上面的logger,严格要求格式为"logger_loggername",必须通过loggername与上面的logger一一对应 level=DEBUG # 设置日志级别 qualname=root # 对于root,其实这里可以不填,默认就是root handlers=debugs #设置指定处理器,如果有多个处理器,中间以逗号分隔,这个名字待会儿 我们会以固定格式"handler_(value)"创建 [logger_log_1] level=INFO qualname=log_1 #除了root以外,必须要设置这个属性,用于定义打印输出时候的logger名 handlers=infos propagate=0 # 是否将消息想父日志传递,0表示不传递,1表示传递。如果向上传递,父日志器接收到消息后会以父日志器的配置再次处理该消息,所以可能所有多次输出 [logger_log_2] level=WARNING qualname=log_2 handlers=warns [handlers] #固定格式, 开始定义处理器 keys=debugs,infos,warns#定义过滤器名称,与上面出现的handlers的值一一对应,下面定义以handler_handlername格式定义 [handler_debugs] class=StreamHandler # 指定处理器的类名 level=DEBUG # 设置级别 formatter=form01 #定义格式器,名称为form01,下面会创建formatters,格式也是严格要求为formatter_formattername args=(sys.stdout,) # 控制台输出 [handler_infos] class=FileHandler level=INFO formatter=form02 args=('b.log','a') [handler_warns] class=FileHandler level=WARNING formatter=form02 args=('a.log','a')# 写入到文件,写入方式 [formatters] #固定格式 keys=form01,form02 #定义名称,下面会引用格式,与上面出现的formatter的值对应 [formatter_form01] format=%(asctime)s %(message)s # 定义消息输出格式,内容 datefmt=%Y-%m-%d %H:%M:%S #日期输出格式 [formatter_form02] format=%(asctime)s %(filename)s %(levelname)s %(message)s datefmt=%Y-%m-%d %H:%M:%S

实例化logger:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d642fc980407ebf79378f34feecfa099.html