009、日志模块(二) 、logging 二次封装 , 单列模式
一、logging 二次封装 ( 自定义 MyLogger 类 )
1、自定义MyLogger类:
a、目录层级 :
b、my_logger.py 代码如下:
在模块中, 生成一个 mylogger 实例,在其他所有模块中导入该模块时,共用这一个日志搜集实例 (类似于全局变量)。日志搜集是典型的 单列设计模式 (单实例设计模式) 。
# -*- coding:utf-8 -*- # Author: Sky # Email: 2780619724@qq.com # Time: 2021/8/3 11:13 # Module: my_logger.py # 自定义一个日志模块 import logging from logging import Logger class MyLogger(Logger): def __init__(self, logger_name, level='INFO', is_stream_handler=True, file=None): """ 实例化一个自定义日志搜集器 :param logger_name: 日志搜集器的名字 :param level: 日志级别,默认是INFO级别 :param is_stream_handler: 是否输出到控制台,默认输出到控制台 :param file: 文件目录,默认不输出到 file """ # 1、设置自定义日志搜集器名字、设置日志级别; super().__init__(logger_name, level) # 2、定义日志输出格式, 使用Formatter类实例化一个日志格式类; fmt = '%(asctime)s, %(levelname)s %(pathname)s,line=%(lineno)d, %(message)s, %(name)s' formatter = logging.Formatter(fmt) # 3、日志默认输出到控制台,如果设置为False,日志将不输出到控制台; if is_stream_handler: stream_handler = logging.StreamHandler() # 设置渠道当中的日志格式 stream_handler.setFormatter(formatter) # 将渠道与实例日志搜集器绑定 self.addHandler(stream_handler) # 4、把日志输出到文件file if file: file_handle = logging.FileHandler(file, mode='a', encoding='utf-8') # 设置渠道当中的日志格式 file_handle.setFormatter(formatter) # 将渠道与实例日志搜集器绑定 self.addHandler(file_handle) # 生成一个 mylogger 实例,在其他所有模块中导入该模块时,共用这一个日志搜集实例。mylogger 类似于 全局变量 # 日志搜集是典型的单列设计模式 (单实例模式) 。 mylogger = MyLogger('日志搜集Demo', file='demo_log.txt')
测试代码:
c、test_logger_cat.py 代码如下:
# 导入 my_logger 模块中 mylogger 实例; from my_logger import mylogger class Cat(): def __init__(self, name): self.name = name def func(self): print('我的名字是: {0}'.format(self.name)) mylogger.debug('debug日志111') mylogger.info('info日志222') mylogger.error('error日志333') # 把异常信息输出到 logging 中 ; # Exception as e 再打印 ; def test_raise(self): try: if str(123) + 12: mylogger.info('成功') except Exception as e: mylogger.error('异常信息为:{}'.format(e)) if __name__ == '__main__': c = Cat('加菲') c.func() c.test_raise()
d、test_logger_dog.py 代码如下:
# 导入 my_logger 模块中 mylogger 实例; from my_logger import mylogger class Dog(): def __init__(self, name): self.name = name def func(self): print('我的名字是: {0}'.format(self.name)) mylogger.debug('debug日志444') mylogger.info('info日志555') mylogger.error('error日志666') if __name__ == '__main__': d = Dog('哈士奇') d.func()
e、test_cat_dog.py 代码如下:
from test_logger_cat import Cat from test_logger_dog import Dog c = Cat('加菲') c.func() d = Dog('哈士奇') d.func()
测试结果:
执行结果如下,同时在控制台输出:
deno_log.txt 中打印如下:
2021-08-03 18:11:38,489, INFO D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_cat.py,line=13, info日志222, 日志搜集Demo 2021-08-03 18:11:38,490, ERROR D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_cat.py,line=14, error日志333, 日志搜集Demo 2021-08-03 18:11:38,490, INFO D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_dog.py,line=13, info日志555, 日志搜集Demo 2021-08-03 18:11:38,490, ERROR D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_dog.py,line=14, error日志666, 日志搜集Demo
控制台输出如下:
D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\venv\Scripts\python.exe D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_cat_dog.py 2021-08-03 18:11:38,489, INFO D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_cat.py,line=13, info日志222, 日志搜集Demo 2021-08-03 18:11:38,490, ERROR D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_cat.py,line=14, error日志333, 日志搜集Demo 2021-08-03 18:11:38,490, INFO D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_dog.py,line=13, info日志555, 日志搜集Demo 2021-08-03 18:11:38,490, ERROR D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\study\test_logger_dog.py,line=14, error日志666, 日志搜集Demo 我的名字是: 加菲 我的名字是: 哈士奇 Process finished with exit code 0
2、把异常信息输出到 logging 中 ;
my_logger.py 代码如下 (延用上面封装好的 MyLogger 类,代码一样):
# -*- coding:utf-8 -*- # Author: Sky # Email: 2780619724@qq.com # Time: 2021/8/3 11:13 # Module: my_logger.py # 自定义一个日志模块 import logging from logging import Logger class MyLogger(Logger): def __init__(self, logger_name, level='INFO', is_stream_handler=True, file=None): """ 实例化一个自定义日志搜集器 :param logger_name: 日志搜集器的名字 :param level: 日志级别,默认是INFO级别 :param is_stream_handler: 是否输出到控制台,默认输出到控制台 :param file: 文件目录,默认不输出到 file """ # 1、设置自定义日志搜集器名字、设置日志级别; super().__init__(logger_name, level) # 2、定义日志输出格式, 使用Formatter类实例化一个日志格式类; fmt = '%(asctime)s, %(levelname)s %(pathname)s,line=%(lineno)d, %(message)s, %(name)s' formatter = logging.Formatter(fmt) # 3、日志默认输出到控制台,如果设置为False,日志将不输出到控制台; if is_stream_handler: stream_handler = logging.StreamHandler() # 设置渠道当中的日志格式 stream_handler.setFormatter(formatter) # 将渠道与实例日志搜集器绑定 self.addHandler(stream_handler) # 4、把日志输出到文件file if file: file_handle = logging.FileHandler(file, mode='a', encoding='utf-8') # 设置渠道当中的日志格式 file_handle.setFormatter(formatter) # 将渠道与实例日志搜集器绑定 self.addHandler(file_handle) # 生成一个 mylogger 实例,在其他所有模块中导入该模块时,共用这一个日志搜集实例。mylogger 类似于 全局变量 # 日志搜集是典型的单列设计模式 (单实例模式) 。 mylogger = MyLogger('日志搜集Demo', file='demo_log.txt')
测试代码:
test_logger_cat.py 代码改动如下。主要改动(添加了一个异常测试代码)
# 导入 my_logger 模块中 mylogger 实例; from my_logger import mylogger class Cat(): def __init__(self, name): self.name = name def func(self): print('我的名字是: {0}'.format(self.name)) mylogger.debug('debug日志111') mylogger.info('info日志222') mylogger.error('error日志333') # 把异常信息输出到 logging 中 ; # Exception as e 再打印 ; def test_raise(self): try: if str(123) + 12: mylogger.info('成功') except Exception as e: mylogger.error('异常信息为:{}'.format(e)) if __name__ == '__main__': c = Cat('加菲') c.func() c.test_raise()
测试结果:
在 test_logger_cat.py 中 run,可以看到把 异常信息输出到 logging中了;
deno_log.txt 中打印如下:
2021-08-03 18:20:39,728, INFO D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py,line=13, info日志222, 日志搜集Demo 2021-08-03 18:20:39,728, ERROR D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py,line=14, error日志333, 日志搜集Demo 2021-08-03 18:20:39,729, ERROR D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py,line=23, 异常信息为:can only concatenate str (not "int") to str, 日志搜集Demo
控制台输出如下:
D:\SkyWorkSpace\WorkSpace\Pytest\Temp\day10\venv\Scripts\python.exe D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py 我的名字是: 加菲 2021-08-03 18:20:39,728, INFO D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py,line=13, info日志222, 日志搜集Demo 2021-08-03 18:20:39,728, ERROR D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py,line=14, error日志333, 日志搜集Demo 2021-08-03 18:20:39,729, ERROR D:/SkyWorkSpace/WorkSpace/Pytest/Temp/day10/study/test_logger_cat.py,line=23, 异常信息为:can only concatenate str (not "int") to str, 日志搜集Demo Process finished with exit code 0
补充知识点:logger.setLevel(logging.INFO) 的参数是用 'INFO' 还是 logging.INFO ? 都可以。