logging日志模块(封装)

转载1:

一.logging模块日志级别介绍

日志一共分为5个等级,从低到高分别是:

级别 说明
DEBUG 输出详细的运行情况,主要用于调试。
INFO 确认一切按预期运行,一般用于输出重要运行情况。
WARNING 系统运行时出现未知的事情(如:警告内存空间不足),但是软件还可以继续运行,可能以后运行时会出现问题。
ERROR 系统运行时发生了错误,但是还可以继续运行。
CRITICAL 一个严重的错误,表明程序本身可能无法继续运行。

这5个等级,也分别对应5种打印日志的方法:debug、info、warning、error、critical。默认的日志收集器是收集WARNING以上等级的日志。

复制代码

import logging
#日志收集器
#默认的日志收集器是root,默认收集WARNING以上等级的日志。
logging.debug("这是debug等级的日志信息")
logging.info("这是info等级的日志信息")
logging.warning("这是warning等级的日志信息")
logging.error("这是error等级的日志信息")
logging.critical("这是critical等级的日志信息")

复制代码

 二、日志收集器

复制代码

import logging
#创建自己的日志收集器
my_log = logging.getLogger("my_log")
#设置收集的日志等级,设置为DEBUG等级
my_log.setLevel("DEBUG")
#日志输出
my_log.debug("--my_log_debug--")
my_log.info("--my_log_info--")
my_log.warning("--my_log_warning--")
my_log.error("--my_log_error")

复制代码

三、日志输出渠道

有两种方式记录跟踪,一种是输出到控制台,另一种是记录到文件中,如日志文件。

1.日志输出到控制台

#创建一个日志输出渠道,输出到控制台
l_s = logging.StreamHandler()
#设置输出的日志等级为INFO以上
l_s.setLevel("INFO")
#将日志输出渠道添加到日志收集器中
my_log.addHandler(l_s)

2.将日志输出到文件中

#创建一个日志输出渠道,输入到文件中
l_f = logging.FileHandler("login.log",encoding='utf8')
# 设置输出的日志等级为DEBUG以上
l_f.setLevel("DEBUG")
#将日志输出渠道添加到日志收集器中
my_log.addHandler(l_f)

3.将日志同时输出到控制台和文件中

复制代码

import logging
# 创建自己的日志收集器
my_log = logging.getLogger("my_log")
# 设置收集的日志等级,设置为DEBUG等级
my_log.setLevel("DEBUG")
# 日志输出渠道
# 创建一个日志输出渠道(输出到控制台),并且设置输出的日志等级为INFO以上
l_s = logging.StreamHandler()
l_s.setLevel("INFO")
# 创构建一个日志输出渠道(输出到文件),并且设置输出的日志等级为DEBUG以上
l_f = logging.FileHandler("login.log",encoding='utf8')
l_f.setLevel("DEBUG")
#将日志输出渠道添加到日志收集器中
my_log.addHandler(l_s)
my_log.addHandler(l_f)
#日志输出
my_log.debug("--my_log_debug--")
my_log.info("--my_log_info--")
my_log.warning("--my_log_warning--")
my_log.error("--my_log_error")
my_log.error("--my_log_critical")

复制代码

控制台输出结果为:

 日志文件的输出结果为:

 四、日志输出格式

可以通过logging.Formatter指定日志的输出格式,这个参数可以输出很多有用的信息,如下:

  • %(name)s:收集器名称
  • %(levelno)s:打印日志级别的数值
  • %(levelname)s:打印日志级别名称
  • %(pathname)s:打印当前执行程序的路径,其实就是sys.argv()
  • %(filename)s:打印当前执行程序名
  • %(funcName)s:打印日志的当前函数
  • %(lineno)d:打印日志的当前行号
  • %(asctime)s:打印日志的时间
  • %(thread)d:打印线程ID %(threadName)s:打印线程名称
  • %(process)d:打印进程ID
  • %(message)s:打印日志信息

工作中常用格式如下:

ft = "%(asctime)s - [%(filename)s -->line:%(lineno)d] - %(levelname)s: %(message)s"

这个格式可以输出日志的打印时间,是哪个模块的哪一行输出的,输出的日志级别是什么,以及输出的日志内容。

复制代码

import logging
# 创建自己的日志收集器
my_log = logging.getLogger("my_log")
# 设置收集的日志等级,设置为DEBUG等级
my_log.setLevel("DEBUG")
# 日志输出渠道
# 创建一个日志输出渠道(输出到控制台),并且设置输出的日志等级为INFO以上
l_s = logging.StreamHandler()
l_s.setLevel("INFO")
# 创构建一个日志输出渠道(输出到文件),并且设置输出的日志等级为DEBUG以上
l_f = logging.FileHandler("login.log",encoding='utf8')
l_f.setLevel("DEBUG")
#将日志输出渠道添加到日志收集器中
my_log.addHandler(l_s)
my_log.addHandler(l_f)
# 设置日志输出的格式
ft = "%(asctime)s - [%(filename)s -->line:%(lineno)d] - %(levelname)s: %(message)s"
ft = logging.Formatter(ft)
# 设置控制台和日志文件输出日志的格式
l_s.setFormatter(ft)
l_f.setFormatter(ft)
#日志输出
my_log.debug("--my_log_debug--")
my_log.info("--my_log_info--")
my_log.warning("--my_log_warning--")
my_log.error("--my_log_error")
my_log.error("--my_log_critical")

复制代码

控制台输出结果为:

 日志文件的输出结果为:

封装一个日志的类(在接口测试时可直接使用)

第一种方法:__init__方法(此方法打印出来的日志行数显示不对,不建议使用)

复制代码

import logging
class MyLogging(object):
    def __init__(self):
        # 创建自己的日志收集器
        self.my_log = logging.getLogger("my_log")
        # 设置收集的日志等级,设置为DEBUG等级
        self.my_log.setLevel("DEBUG")
        # 日志输出渠道
        # 创建一个日志输出渠道(输出到控制台),并且设置输出的日志等级为INFO以上
        l_s = logging.StreamHandler()
        l_s.setLevel("INFO")
        # 创构建一个日志输出渠道(输出到文件),并且设置输出的日志等级为DEBUG以上
        l_f = logging.FileHandler("login.log",encoding='utf8')
        l_f.setLevel("DEBUG")
        #将日志输出渠道添加到日志收集器中
        self.my_log.addHandler(l_s)
        self.my_log.addHandler(l_f)
        # 设置日志输出的格式
        ft = "%(asctime)s - [%(filename)s -->line:%(lineno)d] - %(levelname)s: %(message)s"
        ft = logging.Formatter(ft)
        # 设置控制台和日志文件输出日志的格式
        l_s.setFormatter(ft)
        l_f.setFormatter(ft)

    def debug(self,msg):
        self.my_log.debug(msg)

    def info(self,msg):
        self.my_log.info(msg)

    def warning(self,msg):
        self.my_log.warning(msg)

    def error(self,msg):
        self.my_log.error(msg)

    def critical(self,msg):
        self.my_log.critical(msg)

#日志输出
m_log = MyLogging()
m_log.debug("--my_log_debug--")
m_log.info("--my_log_info--")
m_log.warning("--my_log_warning--")
m_log.error("--my_log_error")
m_log.critical("--my_log_critical")

复制代码

输出结果为:

第二种方法:普通方法

复制代码

import logging
class MyLogging(object):
    def create_logger(*args,**kwargs):
        # 创建自己的日志收集器
        my_log = logging.getLogger("my_log")
        # 设置收集的日志等级,设置为DEBUG等级
        my_log.setLevel("DEBUG")
        # 日志输出渠道
        # 创建一个日志输出渠道(输出到控制台),并且设置输出的日志等级为INFO以上
        l_s = logging.StreamHandler()
        l_s.setLevel("INFO")
        # 创构建一个日志输出渠道(输出到文件),并且设置输出的日志等级为DEBUG以上
        l_f = logging.FileHandler("login.log",encoding='utf8')
        l_f.setLevel("DEBUG")
        #将日志输出渠道添加到日志收集器中
        my_log.addHandler(l_s)
        my_log.addHandler(l_f)
        # 设置日志输出的格式
        ft = "%(asctime)s - [%(filename)s -->line:%(lineno)d] - %(levelname)s: %(message)s"
        ft = logging.Formatter(ft)
        # 设置控制台和日志文件输出日志的格式
        l_s.setFormatter(ft)
        l_f.setFormatter(ft)
        return my_log

    def debug(self,msg):
        self.my_log.debug(msg)

    def info(self,msg):
        self.my_log.info(msg)

    def warning(self,msg):
        self.my_log.warning(msg)

    def error(self,msg):
        self.my_log.error(msg)

    def critical(self,msg):
        self.my_log.critical(msg)


#日志输出
m_log = MyLogging()
logger = m_log.create_logger()
logger.debug("--my_log_debug--")
logger.info("--my_log_info--")
logger.warning("--my_log_warning--")
logger.error("--my_log_error")
logger.critical("--my_log_critical")

复制代码

输出结果为:

 第三种方法:直接使用__new__方法

复制代码

import logging
class MyLogging(object):
    def __new__(cls,*args,**kwargs):
        # 创建自己的日志收集器
        my_log = logging.getLogger("my_log")
        # 设置收集的日志等级,设置为DEBUG等级
        my_log.setLevel("DEBUG")
        # 日志输出渠道
        # 创建一个日志输出渠道(输出到控制台),并且设置输出的日志等级为INFO以上
        l_s = logging.StreamHandler()
        l_s.setLevel("INFO")
        # 创构建一个日志输出渠道(输出到文件),并且设置输出的日志等级为DEBUG以上
        l_f = logging.FileHandler("login.log",encoding='utf8')
        l_f.setLevel("DEBUG")
        #将日志输出渠道添加到日志收集器中
        my_log.addHandler(l_s)
        my_log.addHandler(l_f)
        # 设置日志输出的格式
        ft = "%(asctime)s - [%(filename)s -->line:%(lineno)d] - %(levelname)s: %(message)s"
        ft = logging.Formatter(ft)
        # 设置控制台和日志文件输出日志的格式
        l_s.setFormatter(ft)
        l_f.setFormatter(ft)
        return my_log
    def debug(self,msg):
        my_log.debug(msg)

    def info(self,msg):
        my_log.info(msg)

    def warning(self,msg):
        my_log.warning(msg)

    def error(self,msg):
        my_log.error(msg)

    def critical(self,msg):
        my_log.critical(msg)

#日志输出
m_log = MyLogging()
m_log.debug("--my_log_debug--")
m_log.info("--my_log_info--")
m_log.warning("--my_log_warning--")
m_log.error("--my_log_error")
m_log.critical("--my_log_critical")

复制代码

输出结果为:

 扩展:设置日志名称、最大字节数、最多能存在的文件数,日志格式

复制代码

import logging
from logging.handlers import RotatingFileHandler

# 创建自己的日志收集器
logger = logging.getLogger("my_log")
# 设置收集的日志等级,设置为DEBUG等级
logger.setLevel("DEBUG")
# 设置日志名称为test.log,日志最大字节数为1024,最多只能存在3个文件,设置日志格式为utf8
rf = RotatingFileHandler(filename="test.log",
                         maxBytes=1024,
                         backupCount=3,
                         encoding="utf8")
# 将日志输出渠道添加到日志收集器中
logger.addHandler(rf)
for i in range(200):
    logger.debug("--my_log_debug--")
    logger.info("--my_log_info--")
    logger.warning("--my_log_warning--")
    logger.error("--my_log_error")
    logger.critical("--my_log_critical")

复制代码

转载2:

学习一下python的日志模块logging,可以参考如下博客,写得很详细

https://www.cnblogs.com/yyds/p/6901864.html

https://www.cnblogs.com/goodhacker/p/3355660.html

https://cuiqingcai.com/6080.html

实践:把日志模块加到requests+excel接口测试框架中

新建一个logs文件夹,用来存放输出的日志文件;然后在utils工具中创建一个logger.py,封装日志调用方法

logger.py的内容如下

复制代码

# -*- coding:utf-8 -*-
import logging
import os
from utils import getcwd


log_path = os.path.dirname(getcwd.get_cwd())
print(log_path)
class Logger:
    def __init__(self,loggername):

        #创建一个logger
        self.logger = logging.getLogger(loggername)
        self.logger.setLevel(logging.DEBUG)

        #创建一个handler,用于写入日志文件
        log_path = os.path.dirname(getcwd.get_cwd())+"/logs/" # 指定文件输出路径,注意logs是个文件夹,一定要加上/,不然会导致输出路径错误,把logs变成文件名的一部分了
        logname = log_path + 'out.log' #指定输出的日志文件名
        fh = logging.FileHandler(logname,encoding = 'utf-8')  # 指定utf-8格式编码,避免输出的日志文本乱码
        fh.setLevel(logging.DEBUG)

        #创建一个handler,用于将日志输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)

        # 定义handler的输出格式
        formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)

        # 给logger添加handler
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)


    def get_log(self):
      """定义一个函数,回调logger实例"""
        return self.logger  


if __name__ == '__main__':
    t = Logger("hmk").get_log().debug("User %s is loging" % 'jeck')

复制代码

在主函数run_main.py中使用日志

复制代码

# coding: utf-8
# author: hmk

from base.main import RunMethod
from get_datas.get_data import GetData
from utils.handle_excel import HandleExcel
import json
from utils.logger import Logger


class RunMain:
    def __init__(self):
        """实例化写好的类,备用"""
        self.run_method = RunMethod()
        self.get_data = GetData()
        self.excel = HandleExcel()
        self.logger = Logger(__name__)

    def run(self):
        count = self.get_data.get_nrows()
        # print(count)
        for i in range(1, count):
            priority = self.get_data.get_priority(i)  # 获取用例的优先级priority
            url = self.get_data.get_url(i)  # 获取用例的url
            method = self.get_data.get_method(i)  # 获取请求方法
            params = self.get_data.get_params(i)  # 获取参数(此处取出来的数据是字符串格式)
            params_load = json.loads(params)  # 将获取到的参数反序列化,即转化为字典
            except_value = self.get_data.get_except_value(i)  # 获取预期结果值
            if priority == 'H':
                r = self.run_method.run_main(method, url, params_load, header=None)  # 如果是高优先级用例,则执行
                # print(r)
                self.logger.get_log().debug('第'+str(i)+'个接口的返回结果为:%s',r) # 输出接口响应内容
                # print(type(r))
                if except_value in r:
                    # print(self.get_data.get_caseSeq(i) + '测试通过')
                    self.logger.get_log().debug('第' + str(i) + '接口测试通过')
                    # self.get_data.write_values(i, 'PASS')  # 调用get_data.py文件中的write_values()方法
                    self.excel.write_value(i, 11, 'pass')  # 调用handle_excel.py文件中的write_value()方法
                else:
                    # print(self.get_data.get_caseSeq(i) + '执行失败')
                    self.logger.get_log().debug('第' + str(i) + '接口测试不通过')
                    # self.get_data.write_values(i, 'FAIL')
                    self.excel.write_value(i, 11, 'fail')


if __name__ == '__main__':
    t = RunMain()
    t.run()

复制代码

打印出的日志内容

这样就可以替代用print来查看代码运行的输出内容了

发布了18 篇原创文章 · 获赞 2 · 访问量 1100

猜你喜欢

转载自blog.csdn.net/weixin_45433031/article/details/105609328