diff --git a/.env.example b/.env.example index 2a8f07f..ba2dfeb 100644 --- a/.env.example +++ b/.env.example @@ -27,3 +27,10 @@ ADMINS=[{ "username": "", "user_id": -1 }] # 群验证功能 VERIFY_GROUPS=[] + +# logger 配置 +LOGGER_WIDTH=180 +LOGGER_LOG_PATH="logs" +LOGGER_TIME_FORMAT="[%Y-%m-%d %X]" +LOGGER_TRACEBACK_MAX_FRAMES=20 +LOGGER_RENDER_KEYWORDS=["BOT"] \ No newline at end of file diff --git a/core/config.py b/core/config.py index 5eec427..b791043 100644 --- a/core/config.py +++ b/core/config.py @@ -1,3 +1,4 @@ +from pathlib import Path from typing import ( List, Optional, @@ -13,6 +14,8 @@ from pydantic import ( __all__ = ['BotConfig', 'config'] +from utils.const import PROJECT_ROOT + dotenv.load_dotenv() @@ -36,6 +39,12 @@ class BotConfig(BaseSettings): admins: List['ConfigUser'] = [] verify_groups: List[Union[int, str]] = [] + logger_width: int = 180 + logger_log_path: str = './logs' + logger_time_format: str = "[%Y-%m-%d %X]" + logger_traceback_max_frames: int = 20 + logger_render_keywords: List[str] = ['BOT'] + class Config: case_sensitive = False json_loads = json.loads @@ -59,6 +68,16 @@ class BotConfig(BaseSettings): database=self.redis_db, ) + @property + def logger(self) -> "LoggerConfig": + return LoggerConfig( + width=self.logger_width, + traceback_max_frames=self.logger_traceback_max_frames, + path=PROJECT_ROOT.joinpath(self.logger_log_path).resolve(), + time_format=self.logger_time_format, + render_keywords=self.logger_render_keywords, + ) + class ConfigChannel(BaseModel): name: str @@ -84,5 +103,13 @@ class RedisConfig(BaseModel): database: int = 0 +class LoggerConfig(BaseModel): + width: int = 180 + time_format: str = "[%Y-%m-%d %X]" + traceback_max_frames: int = 20 + path: Path = PROJECT_ROOT / 'logs' + render_keywords: List[str] = ['BOT'] + + BotConfig.update_forward_refs() config = BotConfig() diff --git a/utils/log/_logger.py b/utils/log/_logger.py index 7dcbf33..c353ff4 100644 --- a/utils/log/_logger.py +++ b/utils/log/_logger.py @@ -71,14 +71,13 @@ else: color_system = 'truecolor' # noinspection SpellCheckingInspection log_console = Console( - color_system=color_system, theme=Theme(DEFAULT_STYLE), - width=180 if "PYCHARM_HOSTED" in os.environ else None # 针对 Pycharm + color_system=color_system, theme=Theme(DEFAULT_STYLE), width=config.logger.width ) class Traceback(BaseTraceback): def __init__(self, *args, **kwargs): - kwargs.update({'show_locals': True, 'max_frames': 20}) + kwargs.update({'show_locals': True, 'max_frames': config.logger.traceback_max_frames}) super(Traceback, self).__init__(*args, **kwargs) self.theme = PygmentsSyntaxTheme(MonokaiProStyle) @@ -213,7 +212,7 @@ class LogRender(DefaultLogRender): def __init__(self, *args, **kwargs): super(LogRender, self).__init__(*args, **kwargs) self.show_level = True - self.time_format = "[%Y-%m-%d %X]" + self.time_format = config.logger.time_format def __call__( self, @@ -279,7 +278,7 @@ class Handler(DefaultRichHandler): self.console = log_console self.rich_tracebacks = True self.tracebacks_show_locals = True - self.keywords = [*self.KEYWORDS, 'BOT'] + self.keywords = self.KEYWORDS + config.logger.render_keywords def render( self, @@ -455,11 +454,13 @@ class Logger(logging.Logger): with _lock: if not __initialized__: + if "PYCHARM_HOSTED" in os.environ: + print() # 针对 pycharm 的控制台 bug logging.captureWarnings(True) handler, debug_handler, error_handler = ( - Handler(locals_max_length=4, locals_max_string=10), - FileHandler(level=10, path=PROJECT_ROOT.joinpath("logs/debug/debug.log")), - FileHandler(level=40, path=PROJECT_ROOT.joinpath("logs/error/error.log")) + Handler(locals_max_length=4), + FileHandler(level=10, path=config.logger.path.joinpath("debug/debug.log")), + FileHandler(level=40, path=config.logger.path.joinpath("error/error.log")) ) level_ = 10 if config.debug else 20