04. Logging日志模块用法
2024年10月28日大约 5 分钟
04. Logging日志模块用法
日志代码,无需手写实现。会修改、调用即可!
1. 收集日志想要达成的效果
- 可以把日志输出到不同位置
- 控制台
- 日志文件(防止日志文件过大,每日生成一个日志文件)
- 记录更加详细的日志信息
- 打印日志的时间
- 日志的级别
- 打印日志的位置
- 日志内容
- 可以打印不同级别的日志
- INFO
- ERROR
2. 日志收集实现
日志代码,无需手写实现。会修改、调用即可
"""
步骤:
# 0. 导包
# 1. 创建日志器对象
# 2. 设置日志打印级别
# logging.DEBUG 调试级别
# logging.INFO 信息级别
# logging.WARNING 警告级别
# logging.ERROR 错误级别
# logging.CRITICAL 严重错误级别
# 3. 创建处理器对象
# 创建 输出到控制台 处理器对象
# 创建 输出到日志文件 处理器对象
# 4. 创建日志信息格式
# 5. 将日志信息格式设置给处理器
# 设置给 控制台处理器
# 设置给 日志文件处理器
# 6. 给日志器添加处理器
# 给日志对象 添加 控制台处理器
# 给日志对象 添加 日志文件处理器
# 7. 打印日志
"""
import logging.handlers
import time
# 1. 创建日志器对象
logger = logging.getLogger()
# 2. 设置日志打印级别
# logging.DEBUG 调试级别
# logging.INFO 信息级别
# logging.WARNING 警告级别
# logging.ERROR 错误级别
# logging.CRITICAL 严重错误级别
logger.setLevel(logging.DEBUG)
# 3. 创建处理器对象
# 3.1 创建输出到控制台 处理器对象
st = logging.StreamHandler()
# 3.2 创建输出到日志文件 处理器对象
fh = logging.handlers.TimedRotatingFileHandler(
'a.log',
when='midnight',
interval=1,
backupCount=3,
encoding='utf-8'
)
# when 字符串,指定日志切分间隔时间的单位。midnight:凌晨:12点。
# interval 是间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
# backupCount 是保留日志文件的个数
# 4. 创建日志信息格式
fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
formatter = logging.Formatter(fmt)
# 5. 将日志信息格式设置给处理器
# 5.1 日志信息格式 设置给 控制台处理器
st.setFormatter(formatter)
# 5.2 日志信息格式 设置给 日志文件处理器
fh.setFormatter(formatter)
# 6.1 给日志器对象 添加 控制台处理器
logger.addHandler(st)
# 6.2 给日志器对象 添加 日志文件处理器
logger.addHandler(fh)
# 7. 打印日志
while True:
logging.debug('我是一个调试级别的日志')
logging.info('我是一个信息级别的日志')
logging.warning('我是一个警告级别的日志')
logging.error('我是一个错误级别的日志')
logging.critical('我是一个严重错误级别的日志')
time.sleep(1)
3. 日志相关对象介绍
1. 日志器介绍
2. Handler处理器介绍
3. Formatter格式化器介绍
占位符 | 描述 |
---|---|
%(name)s | 调试级别,打印非常详细的日志信息,通常用于代码调试 |
%(levelno)s | 信息级别,一般用于记录突出强调的运行过程步骤 |
%(levelname)s | 警告级别,可能出现潜在错误的情况,一般不影响系统使用 |
%(pathname)s | 错误级别,打印错误异常信息,出现BUG |
%(filename)s | 严重错误级别,系统可能已经无法运行 |
%(lineno)d | 文本形式的日志级别 |
%(asctime)s | 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896” |
%(message)s | 用户输出的消息 |
%(funcName)s | 调用日志输出函数的函数名 |
4. 打印日志
import logging
import logging.handlers
def init_log_config(filename, when='midnight', interval=1, backup_count=7):
"""
功能:初始化日志配置函数
:param filename: 日志文件名
:param when: 设定日志切分的间隔时间单位
:param interval: 间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
:param backup_count: 保留日志文件的个数
:return:
"""
# 1. 创建日志器对象
logger = logging.getLogger()
# 2. 设置日志打印级别
logger.setLevel(logging.DEBUG)
# logging.DEBUG 调试级别
# logging.INFO 信息级别
# logging.WARNING 警告级别
# logging.ERROR 错误级别
# logging.CRITICAL 严重错误级别
# 3. 创建处理器对象
# 控制台对象
st = logging.StreamHandler()
# 日志文件对象
fh = logging.handlers.TimedRotatingFileHandler(
filename,
when=when,
interval=interval,
backupCount=backup_count,
encoding='utf-8'
)
# 4. 日志信息格式
fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
formatter = logging.Formatter(fmt)
# 5. 给处理器设置日志信息格式
st.setFormatter(formatter)
fh.setFormatter(formatter)
# 6. 给日志器添加处理器
logger.addHandler(st)
logger.addHandler(fh)
if __name__ == '__main__':
# 初始化日志
init_log_config('a.log')
# 打印输出日志信息
logging.debug('我是一个调试级别的日志')
使用步骤
1. 调用 init_log_config() 函数,初始化日志信息。
2. 指定 日志级别,打印 日志信息。
tips: 日志初始化方法项目中初始化一次就够了否则日志会重复打印
https://blog.csdn.net/qq_31455841/article/details/127889511
5. 三方日志库
loguru
- loguru-1
- loguru-2
- https://zhuanlan.zhihu.com/p/514838075
- https://blog.csdn.net/hubing_hust/article/details/128402860
- https://www.cnblogs.com/upstudy/p/18004483
import os import sys import time sys.path.append(os.getcwd()) log_time = time.strftime("%Y%m%d%H-%M", time.localtime()) from loguru import logger log_path = os.path.dirname(__file__) + "/a.log" retention = "15 days" class Logger: def __init__(self, need_log=True): self.my_logger = logger # 判断是否需要写入日志 if need_log is True: self.my_logger.add( log_path, format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module} : {line} | processId : {process} | threadId : " "{thread} : {message}", encoding='utf-8', retention=retention ) def info(self, content): self.my_logger.info(content) def debug(self, content): self.my_logger.debug(content) def error(self, content): self.my_logger.error(content) def critical(self, content): self.my_logger.critical(content) def warning(self, content): self.my_logger.warning(content) def success(self, content): self.my_logger.success(content) def trace(self, content): self.my_logger.trace(content) def traceback(self): import traceback self.my_logger.error(f'执行失败!!!失败信息:\n {traceback.format_exc()}') logger = Logger() def wrapper_log(func): """ 无参装饰器,也可以写成有参装饰器,True或Flase标记是否调用日志模块 功能一:执行失败,打印并记录错误日志信息,定位bug 功能二:记录用例执行时间 """ from functools import wraps import time @wraps(func) # wraps 使 inner装的更像一个func def inner(*args, **kwargs): logger.info(f'{func.__name__}用例执行开始') logger.info(f'正在初始化环境......') now1 = time.time() try: func(*args, **kwargs) except Exception as e: logger.error(f'用例执行失败,失败原因:{e}') logger.traceback() raise e now2 = time.time() logger.success(f'{func.__name__}用例执行成功!!!,用例执行用时:{now2 - now1}ms') return func return inner # 结合语法糖执行用例 @wrapper_log def test_demo(): print(1 / 0) if __name__ == '__main__': test_demo()