1、概述
目前python 日志相关的库很多,但是,高可用的并不多,就loguru:来说是目前很快,封装的很到位,但是问题是:
(1)、多线程、高并发下会出现日志重复
(2)、日志丢失
所以,我们选择库的前提是,稳定,可靠,高效!
2、代码实例
def getLogger(callObjct: object = None, logLevel=logging.INFO) -> logging.Logger:
'''
:param callObjct: 传入用例对象,以便按用例类名保存日志。
:param logLevel: 日志的级别设置,缺省为INFO。
:return: 日志对象。
注意:整个工程都要使用此logger打印。
'''
global global_logger
if callObjct == None and global_logger != None:
return global_logger
SAVE_LOG_DIR = getLogRootDir() + "testcase_logs\\"
if (not os.path.exists(SAVE_LOG_DIR)):
os.mkdir(SAVE_LOG_DIR)
logSaveName = callObjct.__class__.__name__
tslog = logging.getLogger("root")
tslog.setLevel(logLevel)
tslog.propagate = False # 日志不传递给自己的祖先。
while tslog.handlers: # 注意:getLogger时获取的初始logger中已有streamhandler,这也是为什么会重复打印的原因。
# print("已有处理器!")
tslog.handlers.pop()
# formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
formatter = logging.Formatter('%(asctime)s - %(message)s')
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
tslog.addHandler(stream_handler)
saveFName = SAVE_LOG_DIR + logSaveName + "-" + getTimestamp() + ".txt"
file_handler = logging.FileHandler(saveFName)
file_handler.setFormatter(formatter)
tslog.addHandler(file_handler)
tslog.info("Testcase log will be saved to {}".format(saveFName))
global_logger = Logger(tslog)
return global_logger
class Logger:
def __init__(self, logger: logging.Logger):
self.logger = logger
# color: 30黑,31红,32绿,33黄,34蓝,35紫红色,36青蓝色,37白。
def info(self, msg: str):
# modName = getmodule((stack()[1][0])).__name__
fileName= os.path.basename(currentframe().f_back.f_code.co_filename)
# funcName= currentframe().f_back.f_code.co_name
lineNo = currentframe().f_back.f_lineno
self.logger.info("{:>26}[Line:{:>4d}] - {}INFO: {}{}".format(fileName, lineNo, "\033[1;32m", msg, "\033[0m"))
def warning(self, msg: str):
fileName = os.path.basename(currentframe().f_back.f_code.co_filename)
lineNo = currentframe().f_back.f_lineno
self.logger.warning("{:>26}[Line:{:>4d}] - {}WARNING: {}{}".format(fileName, lineNo, "\033[1;33m", msg, "\033[0m"))
def error(self, msg: str):
fileName = os.path.basename(currentframe().f_back.f_code.co_filename)
lineNo = currentframe().f_back.f_lineno
self.logger.error("{:>26}[Line:{:>4d}] - {}ERROR: {}{}".format(fileName, lineNo, "\033[1;31m", msg, "\033[0m"))
def debug(self, msg: str):
fileName = os.path.basename(currentframe().f_back.f_code.co_filename)
lineNo = currentframe().f_back.f_lineno
self.logger.debug("{:>26}[Line:{:>4d}] - {}DEBUG: {}{}".format(fileName, lineNo, "\033[1;35m", msg, "\033[0m"))