From cbc653ffd0ea9abf4360623dc7a7651e1a49cc61 Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Sat, 25 Oct 2025 00:30:48 +0800 Subject: feat: Implement plugin system with combat tracker and dice analyzer - Added `plugin_system_demo.py` to demonstrate basic plugin usage, processing, and analysis. - Created `CombatTrackerPlugin` for tracking combat statistics including damage and healing. - Developed `DiceAnalyzerPlugin` for analyzing dice rolls and calculating success rates. - Introduced `renderer_demo.py` for rendering output in HTML, Markdown, and JSON formats. - Implemented `rule_system_demo.py` to showcase rule engine capabilities with various examples. - Established core rule engine functionality in `rules.py` with support for conditions and actions. - Enhanced base plugin structure in `base.py` to support different plugin types (Processor, Renderer, Analyzer). - Added custom exception handling in `exceptions.py` for better error management. - Configured logging setup in `logging_config.py` for improved logging capabilities. - Created unit tests in `test_rust_core.py` to validate core functionalities and performance. --- src/conventionalrp/utils/logging_config.py | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/conventionalrp/utils/logging_config.py (limited to 'src/conventionalrp/utils/logging_config.py') diff --git a/src/conventionalrp/utils/logging_config.py b/src/conventionalrp/utils/logging_config.py new file mode 100644 index 0000000..956d6d4 --- /dev/null +++ b/src/conventionalrp/utils/logging_config.py @@ -0,0 +1,77 @@ +import logging +import sys +from pathlib import Path +from typing import Optional +from datetime import datetime + + +def setup_logging( + level: str = "INFO", + log_file: Optional[str] = None, + format_string: Optional[str] = None, + include_timestamp: bool = True, + include_module: bool = True +) -> logging.Logger: + log_level = getattr(logging, level.upper(), logging.INFO) + + if format_string is None: + parts = [] + if include_timestamp: + parts.append("%(asctime)s") + parts.append("[%(levelname)s]") + if include_module: + parts.append("%(name)s") + parts.append("%(message)s") + format_string = " - ".join(parts) + + logging.basicConfig( + level=log_level, + format=format_string, + datefmt="%Y-%m-%d %H:%M:%S", + handlers=[] + ) + + logger = logging.getLogger("conventionalrp") + logger.setLevel(log_level) + + logger.handlers.clear() + + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setLevel(log_level) + console_formatter = logging.Formatter(format_string, datefmt="%Y-%m-%d %H:%M:%S") + console_handler.setFormatter(console_formatter) + logger.addHandler(console_handler) + + if log_file: + log_path = Path(log_file) + log_path.parent.mkdir(parents=True, exist_ok=True) + + file_handler = logging.FileHandler(log_file, encoding="utf-8") + file_handler.setLevel(log_level) + file_handler.setFormatter(console_formatter) + logger.addHandler(file_handler) + + logger.info(f"Logging to file: {log_file}") + + logger.info(f"Logging configured at {level} level") + return logger + + +def get_logger(name: str) -> logging.Logger: + return logging.getLogger(f"conventionalrp.{name}") + + +class LogContext: + def __init__(self, logger: logging.Logger, level: str): + self.logger = logger + self.level = getattr(logging, level.upper()) + self.original_level = None + + def __enter__(self): + self.original_level = self.logger.level + self.logger.setLevel(self.level) + return self.logger + + def __exit__(self, exc_type, exc_val, exc_tb): + self.logger.setLevel(self.original_level) + return False -- cgit v1.2.3-70-g09d2