mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-28 19:47:41 +08:00
Merge pull request #3680 from InfinityPacer/feature/module
This commit is contained in:
+71
-30
@@ -1,5 +1,6 @@
|
|||||||
import inspect
|
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional
|
||||||
@@ -95,6 +96,8 @@ class LoggerManager:
|
|||||||
_loggers: Dict[str, Any] = {}
|
_loggers: Dict[str, Any] = {}
|
||||||
# 默认日志文件名称
|
# 默认日志文件名称
|
||||||
_default_log_file = "moviepilot.log"
|
_default_log_file = "moviepilot.log"
|
||||||
|
# 线程锁
|
||||||
|
_lock = threading.Lock()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __get_caller():
|
def __get_caller():
|
||||||
@@ -106,35 +109,53 @@ class LoggerManager:
|
|||||||
caller_name = None
|
caller_name = None
|
||||||
# 调用者插件名称
|
# 调用者插件名称
|
||||||
plugin_name = None
|
plugin_name = None
|
||||||
for i in inspect.stack()[3:]:
|
|
||||||
filepath = Path(i.filename)
|
try:
|
||||||
|
frame = sys._getframe(3)
|
||||||
|
except (AttributeError, ValueError):
|
||||||
|
# 如果无法获取帧,返回默认值
|
||||||
|
return "log.py", None
|
||||||
|
|
||||||
|
while frame:
|
||||||
|
filepath = Path(frame.f_code.co_filename)
|
||||||
parts = filepath.parts
|
parts = filepath.parts
|
||||||
|
# 设定调用者文件名称
|
||||||
if not caller_name:
|
if not caller_name:
|
||||||
# 设定调用者文件名称
|
if parts[-1] == "__init__.py" and len(parts) >= 2:
|
||||||
if parts[-1] == "__init__.py":
|
|
||||||
caller_name = parts[-2]
|
caller_name = parts[-2]
|
||||||
else:
|
else:
|
||||||
caller_name = parts[-1]
|
caller_name = parts[-1]
|
||||||
|
# 设定调用者插件名称
|
||||||
if "app" in parts:
|
if "app" in parts:
|
||||||
if not plugin_name and "plugins" in parts:
|
if not plugin_name and "plugins" in parts:
|
||||||
# 设定调用者插件名称
|
try:
|
||||||
plugin_name = parts[parts.index("plugins") + 1]
|
plugins_index = parts.index("plugins")
|
||||||
if plugin_name == "__init__.py":
|
if plugins_index + 1 < len(parts):
|
||||||
plugin_name = "plugin"
|
plugin_candidate = parts[plugins_index + 1]
|
||||||
break
|
if plugin_candidate == "__init__.py":
|
||||||
|
plugin_name = "plugin"
|
||||||
|
else:
|
||||||
|
plugin_name = plugin_candidate
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
if "main.py" in parts:
|
if "main.py" in parts:
|
||||||
# 已经到达程序的入口
|
# 已经到达程序的入口,停止遍历
|
||||||
break
|
break
|
||||||
elif len(parts) != 1:
|
elif len(parts) != 1:
|
||||||
# 已经超出程序范围
|
# 已经超出程序范围,停止遍历
|
||||||
|
break
|
||||||
|
# 获取上一个帧
|
||||||
|
try:
|
||||||
|
frame = frame.f_back
|
||||||
|
except AttributeError:
|
||||||
break
|
break
|
||||||
return caller_name or "log.py", plugin_name
|
return caller_name or "log.py", plugin_name
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __setup_logger(log_file: str):
|
def __setup_logger(log_file: str):
|
||||||
"""
|
"""
|
||||||
设置日志
|
初始化日志实例
|
||||||
|
|
||||||
:param log_file:日志文件相对路径
|
:param log_file:日志文件相对路径
|
||||||
"""
|
"""
|
||||||
log_file_path = log_settings.LOG_PATH / log_file
|
log_file_path = log_settings.LOG_PATH / log_file
|
||||||
@@ -143,13 +164,8 @@ class LoggerManager:
|
|||||||
# 创建新实例
|
# 创建新实例
|
||||||
_logger = logging.getLogger(log_file_path.stem)
|
_logger = logging.getLogger(log_file_path.stem)
|
||||||
|
|
||||||
if log_settings.DEBUG:
|
# 设置日志级别
|
||||||
_logger.setLevel(logging.DEBUG)
|
_logger.setLevel(LoggerManager.__get_log_level())
|
||||||
|
|
||||||
# 全局日志等级
|
|
||||||
else:
|
|
||||||
loglevel = getattr(logging, log_settings.LOG_LEVEL.upper(), logging.INFO)
|
|
||||||
_logger.setLevel(loglevel)
|
|
||||||
|
|
||||||
# 移除已有的 handler,避免重复添加
|
# 移除已有的 handler,避免重复添加
|
||||||
for handler in _logger.handlers:
|
for handler in _logger.handlers:
|
||||||
@@ -179,16 +195,41 @@ class LoggerManager:
|
|||||||
"""
|
"""
|
||||||
更新日志实例
|
更新日志实例
|
||||||
"""
|
"""
|
||||||
_new_loggers: Dict[str, Any] = {}
|
with LoggerManager._lock:
|
||||||
for log_file, _logger in self._loggers.items():
|
for _logger in self._loggers.values():
|
||||||
# 移除已有的 handler,避免重复添加
|
self.__update_logger_handlers(_logger)
|
||||||
for handler in _logger.handlers:
|
|
||||||
_logger.removeHandler(handler)
|
|
||||||
# 重新设置日志实例
|
|
||||||
_new_logger = self.__setup_logger(log_file=log_file)
|
|
||||||
_new_loggers[log_file] = _new_logger
|
|
||||||
|
|
||||||
self._loggers = _new_loggers
|
@staticmethod
|
||||||
|
def __update_logger_handlers(_logger: logging.Logger):
|
||||||
|
"""
|
||||||
|
更新 Logger 的 handler 配置
|
||||||
|
:param _logger: 需要更新的 Logger 实例
|
||||||
|
"""
|
||||||
|
# 更新现有 handler
|
||||||
|
for handler in _logger.handlers:
|
||||||
|
try:
|
||||||
|
if isinstance(handler, RotatingFileHandler):
|
||||||
|
# 更新最大文件大小和备份数量
|
||||||
|
handler.maxBytes = log_settings.LOG_MAX_FILE_SIZE_BYTES
|
||||||
|
handler.backupCount = log_settings.LOG_BACKUP_COUNT
|
||||||
|
# 更新日志文件输出格式
|
||||||
|
file_formatter = CustomFormatter(log_settings.LOG_FILE_FORMAT)
|
||||||
|
handler.setFormatter(file_formatter)
|
||||||
|
elif isinstance(handler, logging.StreamHandler):
|
||||||
|
# 更新控制台输出格式
|
||||||
|
console_formatter = CustomFormatter(log_settings.LOG_CONSOLE_FORMAT)
|
||||||
|
handler.setFormatter(console_formatter)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to update handler: {handler}. Error: {e}")
|
||||||
|
# 更新日志级别
|
||||||
|
_logger.setLevel(LoggerManager.__get_log_level())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_log_level():
|
||||||
|
"""
|
||||||
|
获取当前日志级别
|
||||||
|
"""
|
||||||
|
return logging.DEBUG if log_settings.DEBUG else getattr(logging, log_settings.LOG_LEVEL.upper(), logging.INFO)
|
||||||
|
|
||||||
def logger(self, method: str, msg: str, *args, **kwargs):
|
def logger(self, method: str, msg: str, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user