python log 支持error单独分开写文件,log自定义颜色

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))


你可能感兴趣的:(python log 支持error单独分开写文件,log自定义颜色)