搞掂python日志的应用,同事面前装个13
Python日志处理
日志是在软件开发中记录程序运行情况的一种重要方式,它对于错误排查和系统运维非常有帮助。Python标准库自带了强大的logging日志模块,被广泛应用于各种Python模块中.
1. 小试牛刀
1.1 简单使用
import logging
# 默认的warning级别,只输出warning以上的
# 使用basicConfig()来指定日志级别和相关信息
logging.basicConfig(
level=logging.DEBUG, # 设置级别,根据等级显示
format='%(asctime)s-[%(filename)s-->line:%(lineno)d]-%(levelname)s:%(message)s', # 设置输出格式
datefmt="%Y-%m-%d %H:%M:%S" # 时间输出的格式
)
logging.debug("This is a DEBUG message")
logging.info("This is an INFO message")
logging.warning("This is a WARNING message")
logging.error("This is an ERROR message")
logging.critical("This is a CRITICAL message")
输出结果:
2023-06-09 10:22:39-[ts.py-->line:11]-DEBUG:DEBUG
2023-06-09 10:22:39-[ts.py-->line:12]-INFO:INFO
2023-06-09 10:22:39-[ts.py-->line:13]-WARNING:WARNING
2023-06-09 10:22:39-[ts.py-->line:14]-ERROR:TERROR
2023-06-09 10:22:39-[ts.py-->line:15]-CRITICAL:CRITICAL
1.2 日志级别
五种日志等级,不同情况输出不同等级的日志。
日志等级(level) | 描述 |
---|---|
DEBUG | 调试信息,通常在诊断问题的时候用得着 |
INFO | 普通信息,确认程序按照预期运行 |
WARNING | 警告信息,表示发生意想不到的事情,或者指示接下来可能会出现一些问题,但是程序还是继续运行 |
ERROR | 错误信息,程序运行中出现了一些问题,程序某些功能不能执行 |
CRITICAL | 危险信息,一个严重的错误,导致程序无法继续运行 |
过滤掉低于自定义设置的日志等级。
import logging
# 默认的warning级别,只输出warning以上的
# 使用basicConfig()来指定日志级别和相关信息
logging.basicConfig(
level=logging.ERROR, # 设置级别,根据等级显示
format='%(asctime)s-[%(filename)s-->line:%(lineno)d]-%(levelname)s:%(message)s', # 设置输出格式
datefmt="%Y-%m-%d %H:%M:%S" # 时间输出的格式
)
logging.debug("调试等级不输出")
logging.info("普通信息等级不会输出")
logging.warning("警告不会输出)
logging.error("输出错误等级")
logging.critical("输出崩溃等级")
输出结果:
2023-06-09 10:27:16-[ts.py-->line:13]-ERROR:输出错误等级
2023-06-09 10:27:16-[ts.py-->line:14]-CRITICAL:输出崩溃等级
在上面的示例中,我们将日志级别设置为ERROR
,因此只有ERROR
和CRITICAL
级别的日志被输出,DEBUG
、INFO
和WARNING
级别的日志被过滤掉。
1.3 日志格式
通过format
参数可以自定义日志输出的格式。在格式字符串中,可以使用以下占位符来表示不同的日志信息:
-
•
%(asctime)s
:日志记录的时间(默认格式为YYYY-MM-DD HH:MM:SS
) -
•
%(levelname)s
:日志级别 -
•
%(message)s
:日志消息 -
•
%(name)s
:日志器的名称 -
•
%(filename)s
:包含当前日志记录的源文件的文件名 -
•
%(lineno)d
:当前日志记录所在的行号
设置自定义的日志格式:
import logging
logging.basicConfig(
level=logging.DEBUG, # 设置最低过滤级别
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S' # 使用指定的日期/时间格式,与 time.strftime() 所接受的格式相同。
)
logging.debug('勇哥 debug ')
logging.info('勇哥 info')
logging.warning('勇哥 warning ')
logging.error('勇哥 error ')
logging.critical('勇哥 critical ')
输出结果:
2023-06-09 10:33:08 - DEBUG - 勇哥 debug
2023-06-09 10:33:08 - INFO - 勇哥 info
2023-06-09 10:33:08 - WARNING - 勇哥 warning
2023-06-09 10:33:08 - ERROR - 勇哥 error
2023-06-09 10:33:08 - CRITICAL - 勇哥 critical
2. 磨磨牛刀
日志处理器(Log Handlers)
用于指定日志的输出位置,例如控制台、文件或网络等。
2.1 控制台处理器
StreamHandler
是一个将日志输出到控制台的处理器。它可以将日志消息打印到标准输出或标准错误。
将日志输出到控制台:
import logging
logging.basicConfig(level=logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(console_handler)
logger.debug('勇哥 debug ')
logger.info('勇哥 info ')
logger.warning('勇哥 warning')
logger.error('勇哥 error')
logger.critical('勇哥 critical')
输出结果:
2023-06-09 10:52:56,493 - DEBUG - 勇哥 debug
DEBUG:__main__:勇哥 debug
2023-06-09 10:52:56,493 - INFO - 勇哥 info
INFO:__main__:勇哥 info
2023-06-09 10:52:56,493 - WARNING - 勇哥 warning
WARNING:__main__:勇哥 warning
2023-06-09 10:52:56,494 - ERROR - 勇哥 error
ERROR:__main__:勇哥 error
2023-06-09 10:52:56,494 - CRITICAL - 勇哥 critical
CRITICAL:__main__:勇哥 critical
StreamHandler
对象添加到日志器处理器中。设置处理器的级别和格式,控制输出的日志级别和格式。
2.2 文件处理器
FileHandler
将日志输出到文件的处理器,将日志消息写入指定的文件。
将日志输出到文件:
import logging
logging.basicConfig(level=logging.DEBUG)
file_handler = logging.FileHandler('app.log', encoding='utf8') # 不带编码会出现中文乱码
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(file_handler)
logger.debug('勇哥 debug ')
logger.info('勇哥 info ')
logger.warning('勇哥 warning')
logger.error('勇哥 error')
logger.critical('勇哥 critical')
FileHandler
对象添加到日志器中。日志消息写入名为app.log
的文件中。
2.3 其他处理器
除了控制台处理器和文件处理器,logging
模块还提供了其他处理器,例如:
-
•
SMTPHandler
:将日志消息通过电子邮件发送。 -
•
SocketHandler
:将日志消息发送到网络套接字。 -
•
SysLogHandler
:将日志消息发送到系统日志。 -
• 等等。
你可以根据需要选择适合的处理器,并根据需要配置其级别、格式和其他属性。
3. 牛刀贴膜
日志过滤器(Log Filters)
用于对日志进行过滤,只输出满足特定条件的日志消息。通过添加日志过滤器,我们可以进一步控制哪些日志消息应该被处理器处理。
使用过滤器将日志消息限制在特定级别的范围内:
import logging
class LevelFilter(logging.Filter):
def __init__(self, level):
super().__init__()
self.level = level
def filter(self, record):
return record.levelno >= self.level
logging.basicConfig(level=logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(console_handler)
level_filter = LevelFilter(logging.WARNING)
logger.addFilter(level_filter)
logger.debug('勇哥 debug')
logger.info('勇哥 info')
logger.warning('勇哥 warning')
logger.error('勇哥 error')
logger.critical('勇哥 critical')
LevelFilter
自定义过滤器。该过滤器接受一个日志级别作为参数,在filter
方法中根据日志记录的级别判断是否应该处理该日志记录。然后,我们将过滤器添加到控制台处理器中,从而限制了只输出WARNING
级别及以上的日志消息。
输出结果:
2023-06-09 11:17:16,546 - WARNING - 勇哥 warning
WARNING:__main__:勇哥 warning
2023-06-09 11:17:16,546 - ERROR - 勇哥 error
ERROR:__main__:勇哥 error
2023-06-09 11:17:16,546 - CRITICAL - 勇哥 critical
CRITICAL:__main__:勇哥 critical
DEBUG
和INFO
级别的日志消息被过滤掉了。
牛刀装鞘
封装日志功能来提供更方便和可复用的日志记录接口
# -*- coding: utf-8 -*-
# @Time : 2019/11/18 10:17
# @Author : 勇哥
# @Email : 262667641@qq.com
# @File : logger.py.py
# @Project : risk_api_project
import logging
import time
from logging import handlers
from common.base_datas import BaseDates
class MyLog:
level_relations = {
"debug": logging.DEBUG,
"info": logging.INFO,
"warning": logging.WARNING,
"error": logging.ERROR,
"critic": logging.CRITICAL
} # 日志级别关系映射
def my_log(self, msg, level="error", when="D", back_count=10):
"""
实例化 TimeRotatingFileHandler
interval 是时间间隔, backupCount 是备份文件的个数,如果超过这个个数,就会自动删除,when 是间隔的时间单位,单位有以下几种
S 秒
M 分
H 小时
D 天
每星期(interval == 0 时代表星期一
midnight 每天凌晨
"""
file_name = BaseDates.log_path
my_logger = logging.getLogger() # 定义日志收集器 my_logger
my_logger.setLevel(self.level_relations.get(level)) # 设置日志级别
format_str = logging.Formatter(
"%(asctime)s-%(levelname)s-%(filename)s-[ line:%(lineno)d ] - 日志信息:%(message)s") # 设置日志格式
# 创建输出渠道
sh = logging.StreamHandler() # 往屏幕输出
sh.setFormatter(format_str) # 设置屏幕上显示的格式
current = time.strftime("%Y-%m-%d", time.localtime()) # 设置当前日期
if level == "error":
th = handlers.TimedRotatingFileHandler(filename=f'{file_name}/{current}_{level}.log', when=when,
backupCount=back_count, encoding="utf-8")
else:
th = handlers.TimedRotatingFileHandler(filename=file_name + "/{}_info.log".format(current), when=when,
backupCount=back_count,
encoding="utf-8") # 往文件里写日志
th.setFormatter(format_str) # 设置文件里写入的格式
my_logger.addHandler(sh) # 将对象加入logger里
my_logger.addHandler(th)
if level == "debug":
my_logger.debug(msg)
elif level == "error":
my_logger.error(msg)
elif level == "info":
my_logger.info(msg)
elif level == "warning":
my_logger.warning(msg)
else:
my_logger.critical(msg)
my_logger.removeHandler(sh)
my_logger.removeHandler(th)
logging.shutdown()
def decorator_log(self, msg=None):
def warp(fun):
def inner(*args, **kwargs):
try:
return fun(*args, **kwargs)
except Exception as e:
self.my_log(f"{msg}: {e}", "error")
return inner
return warp
if __name__ == '__main__':
# for i in range(2):
# MyLog().my_log("hhhh{}".format(i), "info")
# time.sleep(0.04)
@MyLog().decorator_log(“”知错了嘛?)
def add():
print("试一下")
raise "不好使,异常了。"
输出:
总结
以上就是勇哥今天为各位小伙伴准备的内容,如果你想了解更多关于Python自动化测试的知识和技巧,欢迎关注我:公众号\博客\CSDN\B站:测试玩家勇哥;我会不定期地分享更多的精彩内容。感谢你的阅读和支持!
最后
—
我相信学习不是一朝一夕形成的,学习是一生的事业,坚持不懈,持续进步,为自己创造更美好的未来。
以上,共勉!
题外话,勇哥打算把新建的技术交流群,打造成一个活跃的高质量技术群。工作中遇到的技术问题,都可以在里面咨询大家,还有工作内推的机会。
有兴趣的小伙伴,欢迎加我(记得备注是进群还是报名学习)。👇👇👇****
👆****👆********👆长按上方二维码2秒,关注我
勇哥,10年落魄测试老司机,技术栈偏python,目前在一家超大型房产公司担任自动化测试主管,日常工作比较繁杂,主要负责自动化测试,性能测试、软件质量管理及人员管理。工作之余专注于为粉丝进行简历修改、面试辅导、模拟面试、资料分享、一对一自动化测试教学辅导等副业发展。目前已服务十多位小伙伴,取得高薪offer。
关注公众号,测试干货及时送达
往期精选文章👇:
python-Threading多线程之线程锁 |
Pytest 快速入门 |
pytest 前后置操作详谈 |
接口自动化之测试数据动态生成并替换 |
requests模块该如何封装? |
最通俗易懂python操作数据库 |
python正则一篇搞掂 |
接口自动化如何封装mysql操作 |
性能测试之必备知识 |
Python + ChatGPT来实现一个智能对话的钉钉机器人 |
一文看懂python如何执行cmd命令 |
本文来自博客园,作者:测试玩家勇哥,转载请注明原文链接:https://www.cnblogs.com/Nephalem-262667641/p/17468849.html