python3中的logging记录日志实现过程及封装成类

作用:
主要记录信息,便于定位查看问题。

python logging模块官网:
https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects

三种定位问题方法:

  1. print
  2. debug调试:代码写好后,就不需要再进行调试了,所以引入了logger
    logging.debug() – 一般在测试环境中用
  3. logger:当生产环境中有问题时,可以查看logger定位问题

步骤:

1.初始化日志 收集器
2.设置日志 收集器级别 -默认是warning
3.初始化日志 处理器 - 可以理解为写日志的笔
4.设置日志 处理器级别
5.添加handler
6.设置日志的格式
7.添加日志处理器
8.设置不同级别的logger

这里是引用
日志收集器级别
1.NOSET 0 等于没写,废话
2.DEBUG 10 程序调试bug时使用
3.INFO 20 程序正常运行时使用
4.WARNING 30 警告,程序未按预期运行时使用
5.ERROE 40 程序出错
6.CRITICAL 50 严重问题

如何定义级别:自己定的 可以结合try: except: 记录log

代码实现过程如下:

```python
import logging # 标准库,直接导入。
logger = logging.getLogger("日志名字") # 初始化日志收集器
logger.setLevel("DEBUG") # 设置日志收集器级别

handler = logging.FileHandler("日志路径") # 初始化日志处理器 - 文件输出(指定位置使用绝对路径,默认当前目录下)
handler.setLevel("warning") # 设置日志处理器级别 默认warning

console_handler = logging.StreamHandler() # 控制台输出
console_handler.setLevel("DEBUG")

logger.addHandler(handler) # 添加handler
logger.addHandler(console_handler)
 # 设置日志格式,中间间隔使用冒号也可以(模块名字-报错行-收集器名字-级别-信息)
fmt = logging.Formatter("%(filename)s-%(lineno)s-%(name)s-%(levelname)s-%(massage)s")
handler.setFormat(fmt) # 日志轮转 - 添加日志处理器
# 设置不同级别的logger -- 选择一个级别就可以
logging.info("")
logging.debug("")
logging.waring("")
logging.error("")
logging.critical("")

问题1:级别设置
如当设成debug的时候,只有高于,等于该级别的才会打印
如当你设成warning的时候,只有warning.error,critical才会打印
不用管(日志收集器)的级别是啥,这里设置就以(日志处理器)的级别
为准,两者中选择最高的如果(日志收集器)是warning,(日志处理器)
是debug,就以warning为准,两个都设置,这样可以添加多个handler

问题2:实例化
在模块中直接实例化,如果在外部实例化,容易造成多个日志文件的生成

问题3:日志格式设置,python logging官网,查找需要用到的。
https://docs.python.org/zh-cn/3.7/library/logging.html#formatter-objects

封装为类

import logging
class LoggerHandler(logging.Logger):

    def __init__(self,
                 name="root",
                 level="DEBUG",
                 file=None,
                 format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s"
                 ):

        # 初始化日志收集器
        logger = logging.getLogger(name)

        # 设置收集器级别
        logger.setLevel(level) # 继承了Logger 返回的实例就是自己

        # 初始化format,设置格式
        fmt = logging.Formatter(format)

        # 初始化处理器
        # 如果file为空,就执行stream_handler,如果有,两个都执行
        if file:
            file_handler = logging.FileHandler(file)
            # 设置handler级别
            file_handler.setLevel(level)
            # 添加handler
            logger.addHandler(file_handler)
            # 添加日志处理器
            file_handler.setFormatter(fmt)

        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(level)
        logger.addHandler(stream_handler)
        stream_handler.setFormatter(fmt)

        self.logger = logger

	   def debug(self, msg):
	       return self.logger.debug(msg)
	   def info(self,msg):
	       return self.logger.info(msg)

	   def warning(self,msg):
	       return self.logger.warning(msg)
	  
	   def error(self,msg):
	       return self.logger.error(msg)
	  
	   def critical(self,msg):
	       return self.logger.critical(msg)
# 为了确保每次是同一个文件,调用同样的logger对象(防止手误写错文件名字),所以在这里直接初始化logger这个对象比较好
# 可以将name,file参数写入配置文件中(这里我是直接写到了配置文件当中,也可以直接传)
logger = LoggerHandler(config.logger_name,config.level,config.logger_file)  
# logger = LoggerHandler("python21",file="demo.txt")

if __name__ == '__main__':
    logger = LoggerHandler()
    logger.debug("world")
    # 测试.py:40:root:DEBUG:world - 应该是59行打印,因为信息早就保存到logger当中了  -- 可以直接继承logging.Logger使用    

重新封装 - 继承logger后,发现可以直接定位到哪一行打印,可以查看源码

import logging

class LoggerHandler(logging.Logger):

    def __init__(self,
                 name="root",
                 level="DEBUG",
                 file=None,
                 format="%(filename)s:%(lineno)d:%(name)s:%(levelname)s:%(message)s"
                 ):

        # logger(name)  直接超继承logger当中的name
        super().__init__(name) 

        # 设置收集器级别
        # logger.setLevel(level)
        self.setLevel(level) # 继承了Logger 返回的实例就是自己

        # 初始化format,设置格式
        fmt = logging.Formatter(format)

        # 初始化处理器
        # 如果file为空,就执行stream_handler,如果有,两个都执行
        if file:
            file_handler = logging.FileHandler(file)
            # 设置handler级别
            file_handler.setLevel(level)
            # 添加handler
            self.addHandler(file_handler)
            # 添加日志处理器
            file_handler.setFormatter(fmt)

        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(level)
        self.addHandler(stream_handler)
        stream_handler.setFormatter(fmt) 
# 为了确保每次是同一个文件,调用同样的logger对象(防止手误写错文件名字),所以在这里直接初始化logger这个对象比较好
# 可以将name,file参数写入配置文件中(这里我是直接写到了配置文件当中,也可以直接传)
logger = LoggerHandler(config.logger_name,config.level,config.logger_file)
# logger = LoggerHandler("python21",file="demo.txt")  

if __name__ == '__main__':
    logger = LoggerHandler()
    logger.debug("world")
    # 继承后---测试.py:44:root:DEBUG:world

你可能感兴趣的:(python基础)