每日python,第22篇,日志篇

141 阅读4分钟

​「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

 日志在很多时候对于我们都有很大的帮助,特别是测试人员、研发人员。有一份运行日志,能快速的帮助研发人员定位bug,及时修复bug。一份好的运行日志,需要优秀的你来的书写。

logging与print的区别:

1. logging可以设置不同的日志等级

2. 可以指定如何输出及输出的位置应用场景:当我需要看大量的地方或者在一个文件中查看 的时候,这时候print就不大方便了,所以 Python引入了logging模块来记录我想要的信息。

3. logging相对print来说更好控制输出在哪个地方,怎么输出及控制消息级别来过滤掉那些 不需要的信息

日志的严重程度

     这个是必须要知道的,严重程度不同,在不同的公司,不同时候有些日志可以忽略,bug可以延后修复等,严重程度对于修复bug是一个很关键的东西。

级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

    后面的数字也就相当于等级了,CRITICAL等级最高,也是研发必须要修复的。其次就是ERROR了。

    怎么样让程序跑起来后有日志在控制台?

    先简单的看个例子:

1、导包        import logging

2、设置日志格式

3、传值

# 指定输出的日志格式,format=时间,用户名,严重程度,日志名字,文件名,第多少行,日志信息
# 默认的日志用户  默认输出info级别以上
logging.basicConfig(format='%(asctime)s  %(name)s  %(levelno)s '
                           '%(levelname)s   %(filename)s '
                           '%(lineno)d   %(message)s',level=logging.DEBUG)
# 创建一条critical级别的日志
logging.critical("critical")
# 创建一条error级别的日志
logging.error("error") 
logging.warning("warning")
logging.debug("debug")
logging.info("info")

    level=logging.DEBUG指定控制台输出DEBUG级别以上的信息,通过传值后,得到的结果就是:

#    2021-06-29 10:23:59,990  root  50 CRITICAL   logging日志.py 21   critical
#    2021-06-29 10:23:59,991  root  40 ERROR   logging日志.py 23   error
#    2021-06-29 10:23:59,991  root  30 WARNING   logging日志.py 24   warning
#    2021-06-29 10:23:59,991  root  10 DEBUG   logging日志.py 25   debug
#    2021-06-29 10:23:59,991  root  20 INFO   logging日志.py 26   info

    在logging.basicConfig你也可以不跟小北一样用空格来隔开设个属性,用一些符号,比如:

logging.basicConfig(format='%(asctime)s-->%(name)s-->%(levelno)s '
                           '%(levelname)s   %(filename)s '
                           '%(lineno)d   %(message)s',level=logging.DEBUG)

重点:

四大组件:日志器(Logger),处理器(Handler),过滤器(Filter),格式器(Formatter)

Logger:产生日志

Handler:日志输出位置

        #1、日志器设置级别

        #2、处理器设置级别

#两个组件,以日志组件为准

Formatter:输出格式

# 创建日志器
log = logging.getLogger()
# # 1、日志器设置输出日志级别,debug包括debug级别以上的都输出
log.setLevel(level=logging.ERROR)
# 创建处理器,相当于实例化
h = logging.StreamHandler()
# 2、处理器设置输出级别》》》输出到控制台
h.setLevel(level=logging.DEBUG)
# 文件中保存日志,可以指定D、C盘的路径
h = logging.FileHandler('小北日志.log',mode='a',encoding='utf-8')
# 日志器添加处理器
log.addHandler(h)

log.error("error")
log.warning("warning")
log.debug("debug")
log.info("info")

    这里小北添加了两个输出级别,一个DEBUG级别的还有一个是ERROR级别的,这里以日志器设置的过滤级别为准,日志器设置的是DEBUG级别以上的,所以:这里日志中只打印error!

重重之重

        组件从头到尾的编写过程

日志输出步骤
1、创建日志器 设置日志级别

2、创建处理器 控制台、文件 设置日志级别

3、创建格式器 想要打印的格式

4、日志器添加处理器

5、处理器添加格式器

6、日志器日志的输出

log = logging.getLogger()
log.setLevel(level=logging.DEBUG)
# 创建处理器
h = logging.StreamHandler()
# 创建文件处理器,模式为追加
h1 = logging.FileHandler('格式器日志.log',mode='a',encoding='utf-8')

# 创建格式器--时间,用户名,文件名,日志信息
f = logging.Formatter(fmt='[%(asctime)s  %(levelname)s  %(filename)s:>>>%(message)s]')
# 格式器2--时间,用户名,第多少行,日志信息
f1 = logging.Formatter(fmt='[%(asctime)s  %(levelname)s  行数%(lineno)d:>>>%(message)s]')
# 日志器添加处理器
log.addHandler(h)
log.addHandler(h1)
# 处理器添加格式器
h.setFormatter(f)
h1.setFormatter(f1)

log.error("error")
log.warning("warning")
log.debug("debug")
log.info("info")

    这里小北写了两个处理器,两种不同的格式器,格式器根据自己的要求来写。用日志器添加不同的处理器,处理器引用不同的格式器进行输出。python会给我创建一个名字为格式器日志.log的文件:

# .log文件的日志
[2021-06-29 11:25:35,192  ERROR  行数77:>>>error]
[2021-06-29 11:25:35,192  WARNING  行数78:>>>warning]
[2021-06-29 11:25:35,193  DEBUG  行数79:>>>debug]
[2021-06-29 11:25:35,193  INFO  行数80:>>>info]

# 控制台的日志
[2021-06-29 11:25:35,192  ERROR  logging日志.py:>>>error]
[2021-06-29 11:25:35,192  WARNING  logging日志.py:>>>warning]
[2021-06-29 11:25:35,193  DEBUG  logging日志.py:>>>debug]
[2021-06-29 11:25:35,193  INFO  logging日志.py:>>>info]

    内容大致相似,只是更改了格式器中的内容。

封装使用

# 封装
class Log_object():
    def __init__(self):# 构造函数初始化日志器
        self.log = logging.getLogger()
        self.log.setLevel(level=logging.DEBUG)

    def set_Formatter(self):#格式器
        # 初始化格式器
        self.f1= logging.Formatter(fmt='[%(asctime)s  %(levelname)s  %(filename)s:>>>%(message)s]')
        self.f2 = logging.Formatter(fmt='[%(asctime)s  %(levelname)s  行数:%(lineno)d:>>>%(message)s]')
        return self.f1,self.f2

    def add_StreamHandler(self):#控制台处理器
        # 初始化处理器
        self.h = logging.StreamHandler()
        # 设置处理器级别
        self.h.setLevel(level=logging.WARNING)
        #处理器添加格式器,索引取值,取f1
        self.h.setFormatter(self.set_Formatter()[0])
        #日志器添加处理器
        self.log.addHandler(self.h)

    def add_FileHandler(self,file_name):#文件处理器
        # 初始化文件处理器
        self.h = logging.FileHandler(file_name,mode='a',encoding='utf-8')
        # 设置文件处理器级别
        self.h.setLevel(level=logging.WARNING)
        self.h.setFormatter(self.set_Formatter()[1])
        self.log.addHandler(self.h)
    
    # 函数调用
    def get_log(self,file_name):
        self.add_StreamHandler()
        self.add_FileHandler(file_name)
        return self.log
# 调用类
lg = Log_object()
res = lg.get_log('封装日志.log')
res.error("error")
res.warning("warning")
res.debug("debug")
res.info("info")

    封装后后面想用的时候就可以随时调用。

结语

    小北是走测试的哦,所以举的例子偏测试一些。最后配合selenuim看看一个简单的自动化日志。

​​

import time

from 日志文件.logging日志 import Log_object
from selenium import webdriver

lg = Log_object()
res = lg.get_log('baidu.log')

deiver = webdriver.Firefox()
url = 'https://www.baidu.com'
res.warning(f"打开网址:{url}")
deiver.get(url)
time.sleep(2)
deiver.quit()