import logging
import logging_loki
import os
from requests.auth import HTTPBasicAuth
from typing import Dict, Optional
class LokiLogger:
    """
    一个用于配置和获取Loki日志记录器的类。
    可以在其他文件里import后直接使用。

    用法示例：
    from loki_config import LokiLogger

    # 获取日志记录器实例 (使用默认配置或环境变量)
    loki_logger_instance = LokiLogger().get_logger()
    loki_logger_instance.info("这条日志会推送到Loki！")

    # 或者使用自定义配置
    my_loki_logger = LokiLogger(
        url="https://your-custom-loki-url.com/loki/api/v1/push",
        username="myuser",
        password="mypassword",
        tags={"app_name": "my-custom-app", "environment": "prod"},
        level=logging.DEBUG
    ).get_logger()
    my_loki_logger.debug("这条调试日志也推送到Loki。")
    """
    def __init__(self,
                 url: Optional[str] = None,
                 username: Optional[str] = None,
                 password: Optional[str] = None,
                 tags: Optional[Dict[str, str]] = None,
                 level: int = logging.INFO,
                 logger_name: str = "app_loki_logger"):
        """
        初始化LokiLogger。

        Args:
            url (str, optional): Loki的推送URL。默认从环境变量LOKI_URL获取，
                                 如果不存在则使用"https://loki.bwgdi.com/loki/api/v1/push"。
            username (str, optional): Loki的认证用户名。默认从环境变量LOKI_USERNAME获取。
            password (str, optional): Loki的认证密码。默认从环境变量LOKI_PASSWORD获取。
            tags (Dict[str, str], optional): 发送到Loki的默认标签。例如：{"application": "my-app"}。
                                              如果未提供，则默认为{"application": "default-app", "source": "python-app"}。
            level (int, optional): 日志级别（如logging.INFO, logging.DEBUG）。默认为logging.INFO。
            logger_name (str, optional): 日志记录器的名称。默认为"app_loki_logger"。
        """
        # 从环境变量获取配置，如果未通过参数提供
        self._url = url if url else os.getenv("LOKI_URL", "https://loki.bwgdi.com/loki/api/v1/push")
        self._username = username if username else os.getenv("LOKI_USERNAME",'admin')
        self._password = password if password else os.getenv("LOKI_PASSWORD",'admin')
        self._tags = tags if tags is not None else {"app": "jarvis", "env": "dev", "location": "gdi", "layer": "models"}

        # 获取或创建指定名称的日志记录器
        self._logger = logging.getLogger(logger_name)
        self._logger.setLevel(level)

        for handler in self._logger.handlers[:]:
            self._logger.removeHandler(handler)
        # 检查是否已存在LokiHandler，避免重复添加导致重复日志
        # 在多文件或多次初始化的情况下，同一个logger_name可能会获取到同一个logger实例
        if not any(isinstance(h, logging_loki.LokiHandler) for h in self._logger.handlers):
            try:
                auth = None
                if self._username and self._password:
                    auth = HTTPBasicAuth(self._username, self._password)

                loki_handler = logging_loki.LokiHandler(
                    url=self._url,
                    tags=self._tags,
                    version="1", # 通常Loki API版本为1
                    auth=auth
                )
                self._logger.addHandler(loki_handler)
                # 同时添加一个StreamHandler到控制台，以便在本地调试时也能看到日志输出
                if not any(isinstance(h, logging.StreamHandler) for h in self._logger.handlers):
                    self._logger.addHandler(logging.StreamHandler())
                self._logger.info(f"LokiLogger: 已成功配置Loki日志处理器，目标地址：{self._url}")
            except Exception as e:
                # 如果Loki配置失败，确保仍然有StreamHandler将日志输出到控制台
                if not any(isinstance(h, logging.StreamHandler) for h in self._logger.handlers):
                    self._logger.addHandler(logging.StreamHandler())
                self._logger.error(f"LokiLogger: 配置LokiHandler失败：{e}。将回退到控制台日志记录。", exc_info=True)
        else:
            # 如果LokiHandler已经存在，只确保StreamHandler存在
            if not any(isinstance(h, logging.StreamHandler) for h in self._logger.handlers):
                self._logger.addHandler(logging.StreamHandler())
            self._logger.debug(f"LokiLogger: '{logger_name}' 记录器已配置LokiHandler，跳过重新配置。")


    def get_logger(self) -> logging.Logger:
        """
        返回已配置的日志记录器实例。
        """
        self._logger.debug("LokiLogger: 获取已配置的日志记录器实例。")
        return self._logger

# 可选：如果希望有一个默认的全局LokiLogger实例
# 你可以在这里实例化，然后在其他文件直接从这里导入 `loki_logger`
# 例如：
# DEFAULT_LOKI_LOGGER_INSTANCE = LokiLogger().get_logger()
# 然后在其他文件里： `from loki_config import DEFAULT_LOKI_LOGGER_INSTANCE as logger`
