import logging
import sys
import os
from logging.handlers import RotatingFileHandler
import threading


class MyLogger(object):
    instance = None
    init_flag = None

    def __init__(self, name=""):
        """此处设计为，如果已经存在实例时，不再执行初始化"""
        if self.init_flag:
            return
        else:
            self.init_flag = True

        self.logger_lock = threading.Lock()
        self.name = name
        self.init()

    def init(self):
        # 创建日志器
        self.logger = logging.getLogger("图片抠图工具")
        self.logger.setLevel("DEBUG")

        if not os.path.exists("{}\log".format(os.getcwd())):
            os.mkdir("{}\log".format(os.getcwd()))

        # 定义日志处理器
        cl = logging.StreamHandler()  # 将日志输出到终端
        fl = RotatingFileHandler("log\logging_text.log", mode="a", encoding="utf-8", maxBytes=10 * 1024 * 1024,
                                 backupCount=5)  # 输出日志到文本

        # 定义初始化格式 # 定义两个日志布局
        fmt1 = ("%(asctime)s---%(name)s---%(message)s")
        fmt2 = ("%(asctime)s---%(lineno)d---%(name)s---%(message)s")

        # 创建初始化器
        a = logging.Formatter(fmt=fmt1)
        b = logging.Formatter(fmt=fmt2)

        # 添加处理器格式 将上面创建的初始化器添加
        cl.setFormatter(a)
        fl.setFormatter(b)

        # 将处理器添加到日志器
        self.logger.addHandler(cl)
        self.logger.addHandler(fl)

        sys.excepthook = self.handle_exception

    # 函数，用来记录系统报错
    def handle_exception(self, exc_type, exc_value, exc_traceback):
        if issubclass(exc_type, KeyboardInterrupt):
            sys.__excepthook__(exc_type, exc_value, exc_traceback)
            return
        self.logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))

    def __new__(cls, *args, **kwargs):
        """如果当前没有实例时，调用父类__new__方法，生成示例，有则返回保存的内存地址。"""
        if not cls.instance:
            cls.instance = super().__new__(cls)
        return cls.instance

# logger.debug("debug message")
# logger.info("debug message")
# logger.warning("warning message")
# logger.error("error message")
# logger.critical("critical message")
