1、引言
小屌丝:鱼哥,最近你不讲究了啊~
小鱼:啥情况??
小屌丝:你竟然对我有隐瞒。。。
小鱼:我对你,除了妹子,其他的哪有隐藏的!!
小屌丝:Python日支输出方法,就对我有隐藏。
小鱼:没有啊,日志输出不都是用logging模块嘛。
小屌丝:不,你用的不是logging模块, 妹子都跟我说了。
小鱼:…
被妹子出卖后,小鱼的表情
而此时,小屌丝的表情,
开心,可能是因为要get新的姿势 知识!
不管咋样,为了当初的约定, 小鱼忍着泪水,Share一次Python的日志输出内容。
2、 logging模块
关于Python的日志, 今天分享两个重量级模块:
logging模块
loguru模块
话不多说,直接上车,开整!
2.1 日志等级
敲黑板
日志级别等级排序:critical > error > warning > info > debug
2.2 Logging 定义的模块级别函数
Logging 模块提供了两种日志记录方式:
①使用 Logging 提供的模块级别的函数;
②使用 Logging 日志系统的四大组件记录;
代码实例
# -*- coding:utf-8 -*- # @Time : 2021-10-21 # @Author : carl_DJ import logging # 打印日志级别 def test_logging(): logging.debug('Python debug') logging.info('Python info') logging.warning('Python warning') logging.error('Python Error') logging.critical('Python critical') test_logging()
运行结果:
敲黑板
当指定一个日志级别之后,会记录大于或等于这个日志级别的日志信息,小于的将会被丢弃, 默认情况下日志打印只显示大于等于 WARNING 级别的日志。
2.2.1 设置日志显示级别
通过 logging.basicConfig() 可以设置 root 的日志级别,和日志输出格式。
logging.basicConfig() 关键字参数:
代码实例
# -*- coding:utf-8 -*- # @Time : 2021-10-21 # @Author : carl_DJ import logging # 打印日志级别 def test(): logging.basicConfig(level=logging.DEBUG) logging.debug('Python debug') logging.info('Python info') logging.warning('Python warning') logging.error('Python Error') logging.critical('Python critical') logging.log(2,'test') test()
运行结果
敲黑板:
Logging.basicConfig() 需要在开头就设置,在中间设置并无作用
2.2.2 将日志信息记录到文件
代码实例
# -*- coding:utf-8 -*- # @Time : 2021-10-21 # @Author : carl_DJ import logging # 打印日志级别 logging.basicConfig(filename='../test.log', level=logging.DEBUG) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too')
运行结果
敲黑板:
在脚本的上级目录,会生成 test.log文件
2.2.3 显示信息的日期及更改显示消息格式
日期对日志的重要性,不言而喻,所以,我们要学会使用日期格式,
不更改消息格式,代码实例
# -*- coding:utf-8 -*- # @Time : 2021-10-21 # @Author : carl_DJ import logging # 显示消息时间 logging.basicConfig(format='%(asctime)s %(message)s') logging.warning('is when this event was logged.') logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.warning(' this event is logged.')
运行结果:
更改消息格式,代码实例
# -*- coding:utf-8 -*- # @Time : 2021-10-21 # @Author : carl_DJ import logging # 更改显示消息的格式 logging.basicConfig(format='%(levelname)s:%(message)s',level=logging.DEBUG) logging.debug('Python message format Debug') logging.info('Python message format Info') logging.warning('Python message format Warning')
运行结果
2.3 四大组件
logging四大组件,好比四大护法。必不可少,我们来看看!
2.3.1 日志器 - Logger
Logger是一个树形层级结构,在使用接口 debug,info,warn,error,critical 之前必须创建 Logger 实例:
创建方法
logger = logging.getLogger(logger_name)
创建Logger实例后,可以使用以下方法进行日志级别设置,增加处理器 Handler:
logger.setLevel(logging.ERROR) : 设置日志级别为 ERROR,即只有日志级别大于等于 ERROR 的日志才会输出;
logger.addHandler(handler_name) :为 Logger 实例增加一个处理器;
logger.removeHandler(handler_name) : 为 Logger 实例删除一个处理器;
2.3.2 处理器 - Handler
Handler 处理器类型有很多种,比较常用的有三个:
StreamHandler,
FileHandler,
NullHandler
StreamHandler创建方法:
sh = logging.StreamHandler(stream=None)
创建 StreamHandler 之后,可以通过使用以下方法:
设置日志级别,
设置格式化器 Formatter,
增加或删除过滤器 Filter:
代码实例
# 指定日志级别,低于WARN级别的日志将被忽略 ch.setLevel(logging.WARN) # 设置一个格式化器formatter ch.setFormatter(formatter_name) # 增加一个过滤器,可以增加多个 ch.addFilter(filter_name) # 删除一个过滤器 ch.removeFilter(filter_name)
2.3.3 过滤器 - Filter
Handlers 和 Loggers 可以使用 Filters 来完成比级别更复杂的过滤。
Filter 基类只允许特定 Logger 层次以下的事件。
创建方法
filter = logging.Filter(name='')
2.3.4 格式器 - Formatter
使用Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。
创建方法
formatter = logging.Formatter(fmt=None, datefmt=None)
敲黑板
fmt 是消息的格式化字符串,datefmt 是日期字符串。
如果不指明 fmt,将使用 ‘%(message)s’ ;
如果不指明 datefmt,将使用 ISO8601 日期格式。
2.4 代码实例
配置log文件,文件名称 logger.conf:
[loggers] keys=root,infoLogger [logger_root] level=DEBUG handlers=consoleHandler,fileHandler [logger_infoLogger] handlers=consoleHandler,fileHandler qualname=infoLogger propagate=0 [handlers] keys=consoleHandler,fileHandler [handler_consoleHandler] class=StreamHandler level=INFO formatter=form02 args=(sys.stderr,) #args = (sys.stdout,) [handler_fileHandler] class=FileHandler level=INFO formatter=form01 args=('../log/testlog.log', 'a') [formatters] keys=form01,form02 [formatter_form01] format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s [formatter_form02] format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
调用logger.conf文件,封装log方法
# -*- coding:utf-8 -*- # @Time : 2021-10-21 # @Author : carl_DJ import logging import os.path import time class Logger(object): def __init__(self, logger): """ 指定保存日志的文件路径,日志级别,以及调用文件 将日志存入到指定的文件中 :param logger: """ # 拼接日志文件夹,如果不存在则自动创建 cur_path = os.path.dirname(os.path.realpath(__file__)) log_path = os.path.join(os.path.dirname(cur_path), 'logs') if not os.path.exists(log_path):os.mkdir(log_path) # 创建一个logger self.logger = logging.getLogger(logger) self.logger.setLevel(logging.DEBUG) # 创建一个handler,用于写入日志文件 rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) # log_path = os.path.dirname(os.getcwd()) + '/Logs/' # log_name = log_path + rq + '.log' log_name = os.path.join(log_path,'%s.log ' %rq) fh = logging.FileHandler(log_name) fh.setLevel(logging.INFO) # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() ch.setLevel(logging.INFO) # 定义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 getlog(self): return self.logger
如果不理解日志的封装,可以参照小鱼的这篇博文
《Selenium Python 框架之日志(Log)的写法及调用》
或者参照Selenium/Appium的系列博文:
Web自动化Selenium从入门到框架设计系统博文
移动APP自动化Appium从入门到框架设计系列博文