feat(logger)

This commit is contained in:
SXP-Simon
2026-02-08 23:28:56 +08:00
parent b8ea7adf5a
commit e73fd99e26
31 changed files with 100 additions and 72 deletions
+9 -4
View File
@@ -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:
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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
+25 -27
View File
@@ -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 分析文本
"""
+4 -2
View File
@@ -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,
)
+6 -2
View File
@@ -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:
+1 -1
View File
@@ -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
+1 -1
View File
@@ -7,7 +7,7 @@
import datetime
from typing import Any
from astrbot.api import logger
from ..utils.logger import logger
class HistoryManager:
+1 -1
View File
@@ -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
+1 -1
View File
@@ -2,7 +2,7 @@ import base64
import aiohttp
from astrbot.api import logger
from ..utils.logger import logger
from ..utils.trace_context import TraceContext
+1 -1
View File
@@ -7,7 +7,7 @@
from typing import Any, Dict, List, Optional
from astrbot.api import logger
from ...utils.logger import logger
class ConfigManager:
+4 -2
View File
@@ -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]]:
"""
获取最近的分析结果。
+11 -8
View File
@@ -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
+1 -1
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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:
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+16
View File
@@ -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, {})
+1 -1
View File
@@ -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 -1
View File
@@ -1,7 +1,7 @@
import asyncio
import time
from astrbot.api import logger
from .logger import logger
class CircuitBreaker: