Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】

1行代码输出Python日志

  • 1、引言
  • 2、 logging模块
    • 2.1 日志等级
    • 2.2 Logging 定义的模块级别函数
      • 2.2.1 设置日志显示级别
      • 2.2.2 将日志信息记录到文件
      • 2.2.3 显示信息的日期及更改显示消息格式
    • 2.3 四大组件
      • 2.3.1 日志器 - Logger
      • 2.3.2 处理器 - Handler
      • 2.3.3 过滤器 - Filter
      • 2.3.4 格式器 - Formatter
    • 2.4 代码实例
  • 3、 loguru模块
    • 3.1 安装
    • 3.2 初识loguru
    • 3.3 写文件
    • 3.4 停止写入文件
    • 3.5 滚动记录日志文件
    • 3.6 指定日志文件有效期
    • 3.7 配置压缩文件
    • 3.8 异常捕获
      • 3.8.1 catch捕获异常
      • 3.8.2 excepiton 捕获异常
  • 3、总结

1、引言

小屌丝:鱼哥,最近你不讲究了啊~
小鱼:啥情况??
小屌丝:你竟然对我有隐瞒。。。
小鱼:我对你,除了妹子,其他的哪有隐藏的!!
小屌丝:Python日支输出方法,就对我有隐藏。
小鱼:没有啊,日志输出不都是用logging模块嘛。
小屌丝:不,你用的不是logging模块, 妹子都跟我说了。
小鱼:…

被妹子出卖后,小鱼的表情
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第1张图片
而此时,小屌丝的表情

开心,可能是因为要get新的姿势 知识!

Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第2张图片
不管咋样,为了当初的约定, 小鱼忍着泪水,Share一次Python的日志输出内容。

2、 logging模块

关于Python的日志, 今天分享两个重量级模块:

  • logging模块
  • loguru模块

话不多说,直接上车,开整!

2.1 日志等级

日志等级 描述
DEBUG 最详细的日志信息,典型应用场景是 问题诊断
INFO 信息详细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作
WARNING 当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的
ERROR 由于一个更严重的问题导致某些功能不能正常运行时记录的信息
CRITICAL 当发生严重错误,导致应用程序不能继续运行时记录的信息

敲黑板

日志级别等级排序:critical > error > warning > info > debug

2.2 Logging 定义的模块级别函数

Logging 模块提供了两种日志记录方式:

  • ①使用 Logging 提供的模块级别的函数;

  • ②使用 Logging 日志系统的四大组件记录;

函数 说明
logging.debug(msg, *args, **kwargs) 创建一条严重级别为DEBUG的日志记录
logging.info(msg, *args, **kwargs) 创建一条严重级别为INFO的日志记录
logging.warning(msg, *args, **kwargs) 创建一条严重级别为WARNING的日志记录
logging.error(msg, *args, **kwargs) 创建一条严重级别为ERROR的日志记录
logging.critical(msg, *args, **kwargs) 创建一条严重级别为CRITICAL的日志记录
logging.log(level, *args, **kwargs) 创建一条严重级别为level的日志记录
logging.basicConfig(**kwargs) 对root logger进行一次性配置

代码实例

# -*- 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()

运行结果

Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第3张图片

敲黑板

当指定一个日志级别之后,会记录大于或等于这个日志级别的日志信息,小于的将会被丢弃, 默认情况下日志打印只显示大于等于 WARNING 级别的日志。

2.2.1 设置日志显示级别

通过 logging.basicConfig() 可以设置 root 的日志级别,和日志输出格式。

logging.basicConfig() 关键字参数

关键字 描述
filename 创建一个 FileHandler,使用指定的文件名,而不是使用 StreamHandler。
filemode 如果指明了文件名,指明打开文件的模式(如果没有指明 filemode,默认为 ‘a’)。
format handler 使用指明的格式化字符串。
datefmt handler 使用指明的格式化字符串。
level 指明根 logger 的级别。
stream 使用指明的流来初始化 StreamHandler。该参数与 ‘filename’ 不兼容,如果两个都有,‘stream’ 被忽略。

代码实例

# -*- 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()

运行结果

Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第4张图片

敲黑板

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')

运行结果
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第5张图片
敲黑板

在脚本的上级目录,会生成 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.')

运行结果

Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第6张图片

  • 更改消息格式,代码实例
# -*- 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')

运行结果
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第7张图片

2.3 四大组件

logging四大组件,好比四大护法。必不可少,我们来看看!

组件名称 对应类名 功能描述
日志器 Logger 暴露函数给应用程序,基于日志记录器和过滤器级别决定哪些日志有效
处理器 Handler 将 logger 创建的日志记录发送到合适的目的输出
过滤器 Filter 提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录
格式器 Formatter 决定日志记录的最终输出格式

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从入门到框架设计系列博文

3、 loguru模块

解释完logging模块,就到了今天的主角 loguru模块
登场方式,必须闪亮。
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第8张图片

3.1 安装

凡事都要第一步,loguru 也让不开的安装

pip install loguru

安装完成,就是这样:
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第9张图片

当然,
如果不想每次都pip安装,直接跳转这两篇:

  • Python3,选择Python自动安装第三方库,从此跟pip说拜拜!!
  • Python3,我低调的只用一行代码,就导入Python所有库!

3.2 初识loguru

安装完成后, 我们来小试一下,看看有啥能耐:
编写代码:

# -*- coding:utf-8 -*-
# @Time   : 2021-10-21
# @Author : carl_DJ


from loguru import logger
#定义日志输出debug级别
logger.debug("output  debug message")

运行结果

2021-10-21 23:25:12.565 | DEBUG    | __main__::5 - output  debug message

解析
输出的内容包含:

  • 日期 :2021-10-21
  • 时间:23:25:12.565
  • 日志级别:DEBUG
  • 日志代码行数:__main__::5
  • 日志内容信息:output debug message

3.3 写文件

在loguru中,输出日志文件只需要一个 add() 函数即可:

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

#输出日志文件
logger.add('testDJ.log')
#设置日志输出等级
logger.debug("output  debug message")

直接运行后,会生成testDJ.log文件,如下:
在这里插入图片描述

控制台输出的内容:
在这里插入图片描述

日志文件信息
在这里插入图片描述

我们添加一些参数,指定日志输出格式和级别

代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

#定义日志输出格式、级别
log = logger.add('testInfo.log', format="{time} | {level} | {message}", level="INFO")

#设置日志输出等级
logger.debug("output  debug message")

logger.info('output info message')

输出内容
在这里插入图片描述

敲黑板
因为设置的level 是 "INFO"级别,
所以,debug级别不会输出的。

3.4 停止写入文件

小屌丝:鱼哥,我不想把日志写入文件,怎么操作呢?
小鱼:嗯,你想的很全面,直接用logger.remove()就可以了。

当我们不想把日志写入文件,使用logger.remove()方法。

代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

#定义日志输出格式、级别
log = logger.add('testInfo.log', format="{time} | {level} | {message}", level="INFO")

#输出info级别日志
logger.info("output  debug message")

#移除日志文件内容
logger.remove(log)
#输出info级别日志
logger.info('output another info message')

输出结果
在这里插入图片描述
敲黑板:
文件中只记录了 第一条信息,
第二条被使用logger.remove()方法,所以不会写入日志里面了。

3.5 滚动记录日志文件

小屌丝:这个可以啊, 那能不能指定日志的生成方式,例如:按照文件大小,时间等来指定生成。
小鱼:这也可以,直接在logger.add()方法里面配置rotation 值即可。

代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

# 超过300M就新生成一个文件
logger.add("size.log", rotation="300 MB")

# 每天凌晨1点生成一个新文件
logger.add("time.log", rotation="1:00")

# 2周生成一个新文件
logger.add("size.log", rotation="2 week")

3.6 指定日志文件有效期

小屌丝:指定日志文件有效期,这个能实现吗?
小鱼:弄破了博勒姆( no problem)…

直接在logger.add()方法里面配置retention 值即可。

代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

# 保留日志时长为30天
logger.add("file.log", retention="30 days") 

3.7 配置压缩文件

小屌丝:如果日志文件太大,是否可以压缩呢
小鱼:那肯定的,logger.add()方法里面配置compression 值即可。

代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

# 日志文件压缩成zip格式
logger.add("file.log", compression="zip") 

3.8 异常捕获

小屌丝:这给loguru厉害的,那我再升级难度问一下
小鱼:请出题。
小屌丝:请问,loguru能否捕获异常呢??
小鱼:额,容我想一下。
小屌丝:怎么样,被难住了吧
小鱼:就这?? 我是在想,loguru一共有几种捕获异常的方法。
小屌丝:…

3.8.1 catch捕获异常

catch,是以装饰器的形式存在,
用法为:@logger.catch

我们就算一道除法题,来看看catch捕获异常后,输出的信息是否足够详细。
题目:用3除以 0。

这道题,3岁小孩都知道 除数不能为0。

代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger

#使用catch装饰器来捕获异常
@logger.catch
def test_function(a):
	return 3/a

#给a传参为0
test_functioin(0)
	

运行结果
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第10张图片

我们可以看到,输出的信息,非常的详细,很奈斯

3.8.2 excepiton 捕获异常

第二种捕获异常方法,使用exception。
代码实例

# -*- coding:utf-8 -*-
# @Time   : 2021-10-22
# @Author : carl_DJ

from loguru import logger


def x_function(a):
    try:
        return 3/a
    except ZeroDivisionError:
        #exception捕获异常
        logger.exception("exception!")
        
#给a传参为0
x_function(0)

	

运行结果
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第11张图片
妥妥的,异常信息也很奈斯!!
小屌丝:妥,我要转粉为loguru了,谁都拦不住!!
Python3,1行代码就输出日志文件,从此跟logging模块说拜拜~ ~【赶紧收藏】_第12张图片

3、总结

今天分享了两个日志模块:loggingloguru
每个模块都有自己的优点,选择哪一个,只看各位同学的使用习惯了。
但是,不管怎样,使用自己熟练的方法,让程序零BUG,就是最初的本质的。
不要为了高大上而高大上

今天的内容很多,如果一次记不住,键位收藏慢慢吸收!!

你可能感兴趣的:(Python开发实战及代码讲解,python,开发语言,后端,logging)