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

python logging模块官网:

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

三种定位问题方法:

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

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

这里是引用
日志收集器级别
1.NOSET 0 等于没写,废话
2.DEBUG 10 程序调试bug时使用
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") # 设置日志处理器级别 默认warningconsole_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 (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