diff --git a/bot.py b/bot.py
index 9d1c0d5..c75c6f0 100644
--- a/bot.py
+++ b/bot.py
@@ -7,6 +7,10 @@ from nonebot.adapters.discord import Adapter as DiscordAdapter
from nonebot.adapters.minecraft import Adapter as MinecraftAdapter
from nonebot.adapters.onebot.v11 import Adapter as OnebotAdapter
+from konabot.common.log import init_logger
+from konabot.common.nb.exc import BotExceptionMessage
+from konabot.common.path import LOG_PATH
+
dotenv.load_dotenv()
env = os.environ.get("ENVIRONMENT", "prod")
env_enable_console = os.environ.get("ENABLE_CONSOLE", "none")
@@ -14,7 +18,12 @@ env_enable_qq = os.environ.get("ENABLE_QQ", "none")
env_enable_discord = os.environ.get("ENABLE_DISCORD", "none")
env_enable_minecraft = os.environ.get("ENABLE_MINECRAFT", "none")
+
def main():
+ init_logger(LOG_PATH, [
+ BotExceptionMessage,
+ ])
+
nonebot.init()
driver = nonebot.get_driver()
diff --git a/konabot/common/log.py b/konabot/common/log.py
new file mode 100644
index 0000000..753dbac
--- /dev/null
+++ b/konabot/common/log.py
@@ -0,0 +1,79 @@
+import sys
+from pathlib import Path
+from typing import TYPE_CHECKING, List, Type
+
+from loguru import logger
+
+if TYPE_CHECKING:
+ from loguru import Record
+
+
+def file_exception_filter(
+ record: "Record",
+ ignored_exceptions: tuple[Type[Exception], ...]
+) -> bool:
+ """
+ 一个自定义的 Loguru 过滤器函数。
+ 如果日志记录包含异常信息,并且该异常的类型在 ignored_exceptions 中,则返回 False(忽略)。
+ 否则,返回 True(允许记录)。
+ """
+ exception_info = record.get("exception")
+
+ if exception_info:
+ exception_type = exception_info[0]
+
+ if exception_type and issubclass(exception_type, ignored_exceptions):
+ return False
+
+ return True
+
+
+def init_logger(
+ log_dir: Path,
+ ignored_exceptions: List[Type[Exception]]
+) -> None:
+ """
+ 配置全局 Loguru Logger。
+
+ Args:
+ log_dir (Path): 存放日志文件的文件夹路径,会自动创建。
+ ignored_exceptions (List[Type[Exception]]): 在 WARNING 级别文件日志中需要忽略的异常类型列表。
+ """
+
+ ignored_exceptions_tuple = tuple(ignored_exceptions)
+ logger.remove()
+
+ log_dir.mkdir(parents=True, exist_ok=True)
+
+ logger.add(
+ sys.stderr,
+ level="INFO",
+ colorize=True,
+ format="{time:HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
+ )
+
+ info_log_path = log_dir / "log.log"
+ logger.add(
+ str(info_log_path),
+ level="INFO",
+ rotation="10 MB",
+ retention="7 days",
+ enqueue=True,
+ backtrace=False,
+ diagnose=False,
+ )
+
+ warning_error_log_path = log_dir / "error.log"
+ logger.add(
+ str(warning_error_log_path),
+ level="WARNING",
+ rotation="10 MB",
+ compression="zip",
+ enqueue=True,
+ filter=lambda record: file_exception_filter(record, ignored_exceptions_tuple),
+ backtrace=True,
+ diagnose=True,
+ )
+
+ logger.info("Loguru Logger 初始化完成!")
+ logger.info(f"控制台日志级别: INFO")
diff --git a/konabot/common/path.py b/konabot/common/path.py
index 813a82b..6bea695 100644
--- a/konabot/common/path.py
+++ b/konabot/common/path.py
@@ -4,6 +4,8 @@ ASSETS_PATH = Path(__file__).resolve().parent.parent.parent / "assets"
FONTS_PATH = ASSETS_PATH / "fonts"
SRC_PATH = Path(__file__).resolve().parent.parent
+DATA_PATH = SRC_PATH.parent / "data"
+LOG_PATH = DATA_PATH / "logs"
DOCS_PATH = SRC_PATH / "docs"
DOCS_PATH_MAN1 = DOCS_PATH / "user"