
import os
import traceback
from datetime import datetime
from pathlib import Path

path="D:\\flightinfo"
class ErrorLogger:
    """
    错误日志记录器（单例模式，固定配置）
    功能：
    - 自动创建日志目录和文件
    - 限制单个日志文件大小
    - 自动滚动保留最近备份
    - 最新错误显示在最前面
    - 包含详细时间戳和错误堆栈
    """

    # 固定配置（类属性）
    _DEFAULT_FILENAME = "app_errors.log"
    _DEFAULT_LOG_DIR = Path(f"{path}\logs")  # 默认存储目录
    _DEFAULT_MAX_SIZE_KB = 1024  # 默认1MB大小限制
    _DEFAULT_BACKUP_COUNT = 5  # 默认保留5个备份

    _instance = None  # 单例实例

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance.__init__()  # 确保初始化只执行一次
        return cls._instance

    def __init__(self):
        if not hasattr(self, '_initialized'):  # 防止重复初始化
            self.filename = self._DEFAULT_LOG_DIR / self._DEFAULT_FILENAME
            self.max_size = self._DEFAULT_MAX_SIZE_KB * 1024
            self.backup_count = self._DEFAULT_BACKUP_COUNT
            self._ensure_directory_exists()
            self._ensure_file_exists()
            self._initialized = True

    def _ensure_directory_exists(self):
        """确保日志目录存在"""
        try:
            self._DEFAULT_LOG_DIR.mkdir(parents=True, exist_ok=True)
        except Exception as e:
            raise RuntimeError(f"无法创建日志目录 {self._DEFAULT_LOG_DIR}: {e}")

    def _ensure_file_exists(self):
        """确保日志文件存在"""
        try:
            if not self.filename.exists():
                with open(self.filename, 'w', encoding='utf-8') as f:
                    f.write("")  # 创建空文件
        except Exception as e:
            raise RuntimeError(f"无法创建日志文件 {self.filename}: {e}")

    def _rotate_files(self):
        """执行日志文件滚动"""
        if self.filename.exists() and os.path.getsize(self.filename) >= self.max_size:
            try:
                # 删除最旧的备份
                oldest = f"{self.filename}.{self.backup_count}"
                if os.path.exists(oldest):
                    os.remove(oldest)

                # 重命名其他备份
                for i in range(self.backup_count - 1, 0, -1):
                    src = f"{self.filename}.{i}"
                    if os.path.exists(src):
                        os.rename(src, f"{self.filename}.{i + 1}")

                # 重命名当前日志
                os.rename(self.filename, f"{self.filename}.1")

                # 创建新日志文件
                self._ensure_file_exists()
            except Exception as e:
                print(f"日志滚动失败: {e}")

    def log_error(self, error_msg=None):
        """
        记录错误信息
        :param error_msg: 可以是Exception对象或任意可转换为字符串的内容
        """
        self._rotate_files()

        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]  # 带毫秒的时间戳

        if isinstance(error_msg, Exception):
            error_details = "".join(traceback.format_exception(
                type(error_msg), error_msg, error_msg.__traceback__))
        else:
            error_details = str(error_msg) if error_msg else "Unknown error"

        log_entry = f"[{timestamp}]\n{error_details}\n{'=' * 50}\n"

        try:
            if os.path.exists(self.filename):
                with open(self.filename, 'r+', encoding='utf-8') as f:
                    content = f.read()
                    f.seek(0)
                    f.write(log_entry + content)
            else:
                with open(self.filename, 'w', encoding='utf-8') as f:
                    f.write(log_entry)
        except Exception as e:
            print(f"无法写入错误日志: {e}")
# 创建单例实例（推荐直接使用这个实例）
app_logger = ErrorLogger()