import xmltodict
from os import getenv
import logging
import time
import colorlog
from logging.handlers import RotatingFileHandler
import os
import inspect
# LOG_PATH
LOG_PATH = getenv("LOG_PATH", "../")
# level info 20 debug 10
log_level = getenv("LOG_LEVEL", logging.INFO)
### 日志 ###
# 定义不同日志等级颜色
log_colors_config = {
'DEBUG': 'bold_cyan',
'INFO': 'bold_green',
'WARNING': 'bold_yellow',
'ERROR': 'bold_red',
'CRITICAL': 'red',
}
class Logger(logging.Logger):
def __init__(self, name, level='DEBUG', log_path=None, encoding='utf-8'):
super().__init__(name)
self.encoding = encoding
self.level = level
self.timestamp = time.strftime("%Y-%m-%d", time.localtime())
self.__all_log_path = os.path.join(log_path, f"all-{self.timestamp}.log")
self.__error_log_path = os.path.join(log_path, f"error-{self.timestamp}.log")
self.__logger = logging.getLogger()
self.__logger.setLevel(self.level)
# 针对所需要的日志信息 手动调整颜色
self.formatter = colorlog.ColoredFormatter(
'%(log_color)s%(levelname)1.1s %(asctime)s %(reset)s| '
'%(message_log_color)s%(levelname)-8s %(reset)s| '
'%(white)s%(message)s',
reset=True,
log_colors=log_colors_config,
secondary_log_colors={
'message': {
'DEBUG': 'blue',
'INFO': 'blue',
'WARNING': 'blue',
'ERROR': 'red',
'CRITICAL': 'bold_red'
}
},
style='%'
) # 日志输出格式
# 创建一个FileHandler,用于写到本地
@staticmethod
def __init_logger_handler(log_path):
# 日志大于50M时,切割。
return logging.handlers.RotatingFileHandler(
filename=log_path,
# when="D",
maxBytes=1024*1024*50,
backupCount=20
)
def __set_log_color_formatter(self, console_handle):
console_handle.setFormatter(self.formatter)
def __set_log_handler(self, logger_handler, level=logging.DEBUG):
logger_handler.setLevel(level=level)
self.__logger.addHandler(logger_handler)
@staticmethod
def __close_handler(file_handler):
file_handler.close()
def __console(self, level, message):
# 创建日志文件
all_logger_handler = self.__init_logger_handler(self.__all_log_path)
error_logger_handler = self.__init_logger_handler(self.__error_log_path)
console_handle = colorlog.StreamHandler()
# 设置日志文件格式
self.__set_log_color_formatter(all_logger_handler)
self.__set_log_color_formatter(error_logger_handler)
self.__set_log_color_formatter(console_handle)
self.__set_log_handler(all_logger_handler, level=self.level)
self.__set_log_handler(error_logger_handler, level=logging.ERROR)
self.__set_log_handler(console_handle)
# 使用frame 还原log所在位置
frame = inspect.currentframe()
co_filename, f_lineno, f_name = frame.f_back.f_back.f_code.co_filename, frame.f_back.f_back.f_lineno, frame.f_back.f_back.f_code.co_name
_message = f"[{co_filename}:{f_lineno}:{f_name}] - {message}"
if level == "debug":
self.__logger.debug(_message)
if level == "info":
self.__logger.info(_message)
if level == "warning":
self.__logger.warning(_message)
if level == "error":
self.__logger.error(_message)
if level == "exception":
self.__logger.exception(_message)
if level == "critical":
self.__logger.critical(_message)
self.__logger.removeHandler(all_logger_handler)
self.__logger.removeHandler(error_logger_handler)
self.__logger.removeHandler(console_handle)
self.__close_handler(all_logger_handler)
self.__close_handler(error_logger_handler)
def debug(self, message):
self.__console("debug", message)
def info(self, message):
self.__console("info", message)
def warning(self, message):
self.__console("warning", message)
def error(self, message):
self.__console("error", message)
def exception(self, message):
self.__console("exception", message)
def critical(self, message):
self.__console("critical", message)
log_path = os.path.join("../", "logs")
if not os.path.exists(log_path): os.mkdir(log_path)
log_name = "server"
logger = Logger(name=log_name, log_path=log_path, level=int(log_level))