import time, os
from inspect import currentframe, stack, getmodule
# 日志等级
DEFALUT_LOG = 0
DEBUG = 1
INFO = 2
WARNING = 3
ERROR = 4
CRITICAL = 5
# 日志类型
ALL_TYPE = 0 # 输出到所有
CONSOLE = 1 # 仅输出到控制台
FILE = 2 # 仅输出到文件
QT = 3 # 仅输出Qt控件
# 日志输出位置
CONSOLE = 0x0010 # 仅输出到控制台
FILE = 0x0100 # 仅输出到文件
QT = 0x1000 # 仅输出Qt控件
ALL_TYPE = (CONSOLE | FILE | QT) # 输出到所有
class MyLog():
"""自定义日志封装"""
def __init__(self):
pass
def log(self, type, level, msg):
"""
自定义日志实现
author:lsh
date:2022-10-21
:param type: 日志类型
:param level: 日志等级
:param msg: 日志消息
:return:
"""
mod = getmodule(stack()[1][0]) # 调用函数的信息
'''
30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色
'''
_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
_line = str(currentframe().f_back.f_lineno)
_file_path = mod.__file__
_callback_func = mod.__name__
_level = DEBUG
_begin_cocor = '\x1b[1;30;1m'
_begin_end = '\x1b[0m'
log_file_path = ''
try:
# 创建日志存放的目录
project_path = os.path.dirname(os.path.abspath(__file__)) # get_project_path()获取项目根目录
logs_dir = project_path + "\\logs"
if os.path.exists(logs_dir) and os.path.isdir(logs_dir):
pass
else:
os.mkdir(logs_dir)
# 日志文件以日期命名
log_file_name = '%s.log' % time.strftime("%Y-%m-%d", time.localtime())
log_file_path = os.path.join(logs_dir, log_file_name)
if (level == DEBUG):
_level = '[DEBUG]'
_begin_cocor = '\x1b[37m' # 灰色
elif (level == INFO):
_level = '[INFO] '
_begin_cocor = '\x1b[30m' # 白色
elif (level == WARNING):
_level = '[WARN] '
_begin_cocor = '\x1b[33m' # 黄色
elif (level == ERROR):
_level = '[ERROR]'
_begin_cocor = '\x1b[31m' # 红色
elif (level == CRITICAL):
_level = '[CRITI]'
_begin_cocor = '\x1b[1;31m' # 红色+加粗
if (type & CONSOLE):
if (level != DEFALUT_LOG):
final = _begin_cocor + '[' + _time + ']' + _level + '[' + _file_path + ':' + _line + ']' + ' | ' + str(msg) + '\x1b[0m'
else:
final = msg
print(final)
if (type & FILE):
if (level != DEFALUT_LOG):
final = '[' + _time + ']' + _level + '[' + _file_path + ':' + _line + ']' + ' | ' + str(msg) + '\n'
else:
final = msg
with open(log_file_path, "a") as dest, open(log_file_path, 'r') as src:
#文件大小限制在20M,超过满覆盖50%
if (os.path.getsize(log_file_path) < (20 * 1024 * 1024)):
dest.write(final)
else:
tmp = src.read()
with open(log_file_path, "w") as f:
f.write(tmp[-(10 * 1024 * 1024):]) # 超过了则从保留后面10M数据
except (ZeroDivisionError, TypeError) as err:
final = '\x1b[1;31m' + '[' + _time + ']' + ' [' + _file_path + ':' + _line + ']' + ' | ' + '日志格数错误!!! msg:[%s]'%err + '\x1b[0m'
print(final)
with open(log_file_path, "a") as f:
f.write('[' + _time + ']' + ' [' + _file_path + ':' + _line + ']' + ' | ' + '日志格数错误!!! msg:[%s]'%err + '\n')
if __name__ == '__main__':
mylog = MyLog()
mylog.log(ALL_TYPE, INFO, '信息')
mylog.log(ALL_TYPE, DEBUG, '调试')
mylog.log(ALL_TYPE, WARNING, '警告')
mylog.log(ALL_TYPE, ERROR, '报错')
mylog.log(ALL_TYPE, CRITICAL, '严重')
list = [1, 2, 5]
mylog.log(ALL_TYPE, CRITICAL, list)
mylog.log(ALL_TYPE, 'CRITICAL', list)
mylog.log(CONSOLE, INFO, '仅控制台输出')
mylog.log(FILE, INFO, '仅文件输出')
mylog.log(CONSOLE|FILE, INFO, '控制台|文件都输出')
控制台执行结果
文件输出