mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
feat(logger)
This commit is contained in:
@@ -17,11 +17,16 @@ sys.path.insert(0, project_root)
|
||||
print(f"Project Root: {project_root}")
|
||||
|
||||
# Mock logger before importing anything that uses it
|
||||
from astrbot.api import logger # noqa: E402
|
||||
# Mock logger
|
||||
from data.plugins.astrbot_plugin_qq_group_daily_analysis.src.utils import (
|
||||
logger as plugin_logger_module,
|
||||
)
|
||||
|
||||
logger.info = lambda msg, *args, **kwargs: print(f"[INFO] {msg}")
|
||||
logger.error = lambda msg, *args, **kwargs: print(f"[ERROR] {msg}")
|
||||
logger.warning = lambda msg, *args, **kwargs: print(f"[WARN] {msg}")
|
||||
plugin_logger_module.logger.info = lambda msg, *args, **kwargs: print(f"[INFO] {msg}")
|
||||
plugin_logger_module.logger.error = lambda msg, *args, **kwargs: print(f"[ERROR] {msg}")
|
||||
plugin_logger_module.logger.warning = lambda msg, *args, **kwargs: print(
|
||||
f"[WARN] {msg}"
|
||||
)
|
||||
|
||||
# Now import plugin modules
|
||||
try:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
from ...models.data_models import TokenUsage
|
||||
from ..utils.json_utils import parse_json_response
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
from ...models.data_models import GoldenQuote, TokenUsage
|
||||
from ..utils import InfoUtils
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
from ...models.data_models import SummaryTopic, TokenUsage
|
||||
from ..utils import InfoUtils
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
专门处理用户称号和MBTI类型分析
|
||||
"""
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
from ...models.data_models import TokenUsage, UserTitle
|
||||
from ..utils.json_utils import extract_user_titles_with_regex
|
||||
|
||||
@@ -5,7 +5,7 @@ LLM分析器模块
|
||||
|
||||
import asyncio
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..models.data_models import GoldenQuote, SummaryTopic, TokenUsage, UserTitle
|
||||
from .analyzers.golden_quote_analyzer import GoldenQuoteAnalyzer
|
||||
|
||||
@@ -6,7 +6,7 @@ JSON处理工具模块
|
||||
import json
|
||||
import re
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
|
||||
def fix_json(text: str) -> str:
|
||||
|
||||
@@ -6,7 +6,7 @@ LLM API请求处理工具模块
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
from ...utils.resilience import CircuitBreaker, global_llm_rate_limiter
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
from typing import Optional, List, Dict, Any
|
||||
from dataclasses import dataclass
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..domain.value_objects.unified_message import UnifiedMessage
|
||||
from ..domain.value_objects.platform_capabilities import PlatformCapabilities
|
||||
@@ -23,6 +23,7 @@ from .message_converter import MessageConverter
|
||||
@dataclass
|
||||
class AnalysisConfig:
|
||||
"""分析操作配置"""
|
||||
|
||||
days: int = 1
|
||||
max_messages: int = 1000
|
||||
min_messages_threshold: int = 10
|
||||
@@ -32,13 +33,13 @@ class AnalysisConfig:
|
||||
class AnalysisOrchestrator:
|
||||
"""
|
||||
分析编排器 - 协调分析工作流。
|
||||
|
||||
|
||||
职责:
|
||||
1. 使用 PlatformAdapter 获取消息(DDD 方式)
|
||||
2. 转换消息以兼容现有分析器
|
||||
3. 协调分析流程
|
||||
4. 提供平台能力检查
|
||||
|
||||
|
||||
此类作为以下组件之间的桥梁:
|
||||
- 新的 DDD 基础设施(PlatformAdapter, UnifiedMessage)
|
||||
- 现有分析逻辑(MessageHandler, LLMAnalyzer 等)
|
||||
@@ -51,7 +52,7 @@ class AnalysisOrchestrator:
|
||||
):
|
||||
"""
|
||||
初始化编排器。
|
||||
|
||||
|
||||
参数:
|
||||
adapter: 用于消息操作的平台适配器
|
||||
config: 分析配置
|
||||
@@ -69,13 +70,13 @@ class AnalysisOrchestrator:
|
||||
) -> Optional["AnalysisOrchestrator"]:
|
||||
"""
|
||||
工厂方法 - 为特定平台创建编排器。
|
||||
|
||||
|
||||
参数:
|
||||
platform_name: 平台名称(如 "aiocqhttp", "telegram")
|
||||
bot_instance: 来自 AstrBot 的 bot 实例
|
||||
config: 平台特定配置
|
||||
analysis_config: 分析配置
|
||||
|
||||
|
||||
返回:
|
||||
AnalysisOrchestrator 或 None(如果平台不支持)
|
||||
"""
|
||||
@@ -83,7 +84,7 @@ class AnalysisOrchestrator:
|
||||
if adapter is None:
|
||||
logger.warning(f"平台 '{platform_name}' 不支持分析功能")
|
||||
return None
|
||||
|
||||
|
||||
return cls(adapter, analysis_config)
|
||||
|
||||
def get_capabilities(self) -> PlatformCapabilities:
|
||||
@@ -106,29 +107,26 @@ class AnalysisOrchestrator:
|
||||
) -> List[UnifiedMessage]:
|
||||
"""
|
||||
使用平台适配器获取消息。
|
||||
|
||||
|
||||
参数:
|
||||
group_id: 要获取消息的群组 ID
|
||||
days: 天数(默认使用配置值)
|
||||
max_count: 最大消息数量(默认使用配置值)
|
||||
|
||||
|
||||
返回:
|
||||
UnifiedMessage 列表
|
||||
"""
|
||||
days = days or self.config.days
|
||||
max_count = max_count or self.config.max_messages
|
||||
|
||||
|
||||
# 应用平台能力限制
|
||||
caps = self.adapter.get_capabilities()
|
||||
effective_days = caps.get_effective_days(days)
|
||||
effective_count = caps.get_effective_count(max_count)
|
||||
|
||||
|
||||
if effective_days < days:
|
||||
logger.info(
|
||||
f"平台限制:请求 {days} 天,"
|
||||
f"实际使用 {effective_days} 天"
|
||||
)
|
||||
|
||||
logger.info(f"平台限制:请求 {days} 天,实际使用 {effective_days} 天")
|
||||
|
||||
return await self.adapter.fetch_messages(
|
||||
group_id=group_id,
|
||||
days=effective_days,
|
||||
@@ -143,15 +141,15 @@ class AnalysisOrchestrator:
|
||||
) -> List[dict]:
|
||||
"""
|
||||
获取消息并转换为原始字典格式。
|
||||
|
||||
|
||||
此方法提供与现有分析器的向后兼容性,
|
||||
这些分析器期望原始字典格式的消息。
|
||||
|
||||
|
||||
参数:
|
||||
group_id: 要获取消息的群组 ID
|
||||
days: 天数
|
||||
max_count: 最大消息数量
|
||||
|
||||
|
||||
返回:
|
||||
原始消息字典列表(通用格式,由适配器决定具体格式)
|
||||
"""
|
||||
@@ -178,11 +176,11 @@ class AnalysisOrchestrator:
|
||||
# }
|
||||
# for msg in unified_messages
|
||||
# ]
|
||||
|
||||
|
||||
# 暂时直接使用适配器获取 raw 格式,如果适配器支持
|
||||
# 这是为了确保现有逻辑完全兼容,因为 convert_to_raw_format 可能有损
|
||||
# 但我们希望尽可能使用新的 fetch_messages
|
||||
|
||||
|
||||
unified_messages = await self.fetch_messages(group_id, days, max_count)
|
||||
return self.adapter.convert_to_raw_format(unified_messages)
|
||||
|
||||
@@ -197,11 +195,11 @@ class AnalysisOrchestrator:
|
||||
) -> Dict[str, Optional[str]]:
|
||||
"""
|
||||
批量获取用户头像 URL。
|
||||
|
||||
|
||||
参数:
|
||||
user_ids: 用户 ID 列表
|
||||
size: 头像尺寸
|
||||
|
||||
|
||||
返回:
|
||||
用户 ID 到头像 URL 的映射字典(URL 可能为 None)
|
||||
"""
|
||||
@@ -232,10 +230,10 @@ class AnalysisOrchestrator:
|
||||
def validate_message_count(self, messages: List[UnifiedMessage]) -> bool:
|
||||
"""
|
||||
检查消息数量是否达到最小阈值。
|
||||
|
||||
|
||||
参数:
|
||||
messages: 消息列表
|
||||
|
||||
|
||||
返回:
|
||||
如果数量足够返回 True
|
||||
"""
|
||||
@@ -244,10 +242,10 @@ class AnalysisOrchestrator:
|
||||
def get_analysis_text(self, messages: List[UnifiedMessage]) -> str:
|
||||
"""
|
||||
将消息转换为 LLM 分析文本格式。
|
||||
|
||||
|
||||
参数:
|
||||
messages: UnifiedMessage 列表
|
||||
|
||||
|
||||
返回:
|
||||
格式化的 LLM 分析文本
|
||||
"""
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..domain.services import ReportGenerator
|
||||
from ..domain.value_objects.topic import Topic
|
||||
@@ -78,7 +78,9 @@ class ReportingService:
|
||||
statistics=statistics,
|
||||
topics=topics if self.config.get_include_topics() else [],
|
||||
user_titles=user_titles if self.config.get_include_user_titles() else [],
|
||||
golden_quotes=golden_quotes if self.config.get_include_golden_quotes() else [],
|
||||
golden_quotes=golden_quotes
|
||||
if self.config.get_include_golden_quotes()
|
||||
else [],
|
||||
include_header=True,
|
||||
include_footer=True,
|
||||
)
|
||||
|
||||
@@ -9,10 +9,14 @@ import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Callable, Dict, List, Optional, Set
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..infrastructure.config import ConfigManager
|
||||
from ..shared.constants import TASK_STATE_PENDING, TASK_STATE_RUNNING, TASK_STATE_COMPLETED
|
||||
from ..shared.constants import (
|
||||
TASK_STATE_PENDING,
|
||||
TASK_STATE_RUNNING,
|
||||
TASK_STATE_COMPLETED,
|
||||
)
|
||||
|
||||
|
||||
class ScheduledTask:
|
||||
|
||||
@@ -7,7 +7,7 @@ Bot实例管理模块
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..infrastructure.platform import PlatformAdapter, PlatformAdapterFactory
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import datetime
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
|
||||
class HistoryManager:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..models.data_models import EmojiStatistics, GroupStatistics, TokenUsage
|
||||
from ..visualization.activity_charts import ActivityVisualizer
|
||||
|
||||
@@ -2,7 +2,7 @@ import base64
|
||||
|
||||
import aiohttp
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..utils.trace_context import TraceContext
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
|
||||
@@ -7,7 +7,7 @@ LLM 客户端 - 包装 AstrBot 的 LLM 提供商系统
|
||||
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
from ...domain.value_objects.statistics import TokenUsage
|
||||
from ...domain.exceptions import LLMException, LLMRateLimitException
|
||||
@@ -110,7 +110,9 @@ class LLMClient:
|
||||
if hasattr(response, "completion_text"):
|
||||
response_text = response.completion_text
|
||||
elif isinstance(response, dict):
|
||||
response_text = response.get("completion_text", response.get("text", ""))
|
||||
response_text = response.get(
|
||||
"completion_text", response.get("text", "")
|
||||
)
|
||||
else:
|
||||
response_text = str(response)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
|
||||
class HistoryRepository:
|
||||
@@ -121,9 +121,7 @@ class HistoryRepository:
|
||||
history = self.load_group_history(group_id)
|
||||
return history.get("daily", {}).get(date_str)
|
||||
|
||||
def get_recent_results(
|
||||
self, group_id: str, limit: int = 7
|
||||
) -> List[Dict[str, Any]]:
|
||||
def get_recent_results(self, group_id: str, limit: int = 7) -> List[Dict[str, Any]]:
|
||||
"""
|
||||
获取最近的分析结果。
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
平台适配器工厂
|
||||
"""
|
||||
|
||||
from typing import Optional, Any, Dict, Type
|
||||
from typing import Any, Dict, List, Optional, Type
|
||||
|
||||
from ...utils.logger import logger
|
||||
|
||||
from .base import PlatformAdapter
|
||||
|
||||
@@ -10,7 +12,7 @@ from .base import PlatformAdapter
|
||||
class PlatformAdapterFactory:
|
||||
"""
|
||||
平台适配器工厂
|
||||
|
||||
|
||||
根据平台名称创建适配器实例。
|
||||
使用注册表模式便于扩展。
|
||||
"""
|
||||
@@ -31,12 +33,12 @@ class PlatformAdapterFactory:
|
||||
) -> Optional[PlatformAdapter]:
|
||||
"""
|
||||
创建平台适配器
|
||||
|
||||
|
||||
参数:
|
||||
platform_name: 平台名称(如 "aiocqhttp"、"telegram")
|
||||
bot_instance: AstrBot 机器人实例
|
||||
config: 配置字典
|
||||
|
||||
|
||||
返回:
|
||||
平台适配器实例,如果不支持则返回 None
|
||||
"""
|
||||
@@ -49,8 +51,7 @@ class PlatformAdapterFactory:
|
||||
return adapter_class(bot_instance, config)
|
||||
except Exception:
|
||||
# 记录异常,但不崩溃
|
||||
import logging
|
||||
logging.getLogger(__name__).error(f"为 {platform_name} 创建适配器时出错", exc_info=True)
|
||||
logger.error(f"为 {platform_name} 创建适配器时出错", exc_info=True)
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
@@ -68,15 +69,17 @@ class PlatformAdapterFactory:
|
||||
def _register_adapters():
|
||||
try:
|
||||
from .adapters.onebot_adapter import OneBotAdapter
|
||||
|
||||
PlatformAdapterFactory.register("aiocqhttp", OneBotAdapter)
|
||||
PlatformAdapterFactory.register("onebot", OneBotAdapter)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
from .adapters.discord_adapter import DiscordAdapter
|
||||
|
||||
PlatformAdapterFactory.register("discord", DiscordAdapter)
|
||||
PlatformAdapterFactory.register("discord_bot", DiscordAdapter) # 添加别名
|
||||
PlatformAdapterFactory.register("discord_bot", DiscordAdapter) # 添加别名
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Callable, Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
|
||||
class CircuitState(Enum):
|
||||
|
||||
@@ -9,7 +9,7 @@ import time
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -10,7 +10,7 @@ from dataclasses import dataclass
|
||||
from functools import wraps
|
||||
from typing import Callable, Optional, Tuple, Type, Union
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...utils.logger import logger
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..utils.trace_context import TraceContext
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from pathlib import Path
|
||||
|
||||
import aiohttp
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..visualization.activity_charts import ActivityVisualizer
|
||||
from .templates import HTMLTemplates
|
||||
|
||||
@@ -9,7 +9,7 @@ import threading
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
|
||||
class HTMLTemplates:
|
||||
|
||||
@@ -8,7 +8,7 @@ import weakref
|
||||
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
from ..core.message_sender import MessageSender
|
||||
from ..reports.dispatcher import ReportDispatcher
|
||||
|
||||
@@ -6,7 +6,7 @@ import aiohttp
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..utils.logger import logger
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from astrbot.api import logger
|
||||
from .logger import logger
|
||||
|
||||
from ..analysis.llm_analyzer import LLMAnalyzer
|
||||
from ..analysis.statistics import UserAnalyzer
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import logging
|
||||
from astrbot.api import logger as astrbot_logger
|
||||
|
||||
|
||||
class PluginLoggerAdapter(logging.LoggerAdapter):
|
||||
"""
|
||||
插件日志适配器
|
||||
自动为日志添加 [QQ群分析] 前缀,方便区分
|
||||
"""
|
||||
|
||||
def process(self, msg, kwargs):
|
||||
return f"[QQ群分析] {msg}", kwargs
|
||||
|
||||
|
||||
# 导出带前缀的 logger
|
||||
logger = PluginLoggerAdapter(astrbot_logger, {})
|
||||
@@ -7,7 +7,7 @@ import asyncio
|
||||
import sys
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from astrbot.api import logger
|
||||
from .logger import logger
|
||||
|
||||
|
||||
class PDFInstaller:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
from astrbot.api import logger
|
||||
from .logger import logger
|
||||
|
||||
|
||||
class CircuitBreaker:
|
||||
|
||||
Reference in New Issue
Block a user