feat:插件日志文件独立
This commit is contained in:
parent
63643e6d26
commit
cb274d1587
@ -160,7 +160,7 @@ def get_message(token: str):
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/logging", summary="实时日志")
|
@router.get("/logging", summary="实时日志")
|
||||||
def get_logging(token: str, length: int = 50):
|
def get_logging(token: str, length: int = 50, logfile: str = "moviepilot.log"):
|
||||||
"""
|
"""
|
||||||
实时获取系统日志
|
实时获取系统日志
|
||||||
length = -1 时, 返回text/plain
|
length = -1 时, 返回text/plain
|
||||||
@ -172,7 +172,7 @@ def get_logging(token: str, length: int = 50):
|
|||||||
detail="认证失败!",
|
detail="认证失败!",
|
||||||
)
|
)
|
||||||
|
|
||||||
log_path = settings.LOG_PATH / 'moviepilot.log'
|
log_path = settings.LOG_PATH / logfile
|
||||||
|
|
||||||
def log_generator():
|
def log_generator():
|
||||||
# 读取文件末尾50行,不使用tailer模块
|
# 读取文件末尾50行,不使用tailer模块
|
||||||
|
98
app/log.py
98
app/log.py
@ -1,6 +1,8 @@
|
|||||||
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
@ -31,22 +33,47 @@ class CustomFormatter(logging.Formatter):
|
|||||||
return super().format(record)
|
return super().format(record)
|
||||||
|
|
||||||
|
|
||||||
|
class LoggerManager:
|
||||||
|
"""
|
||||||
|
日志管理
|
||||||
|
"""
|
||||||
|
# 管理所有的Logger
|
||||||
|
_loggers: Dict[str, Any] = {}
|
||||||
|
# 默认日志文件
|
||||||
|
_default_log_file = "moviepilot.log"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __setup_logger(log_file: str):
|
||||||
|
"""
|
||||||
|
设置日志
|
||||||
|
log_file:日志文件相对路径
|
||||||
|
"""
|
||||||
|
log_file_path = settings.LOG_PATH / log_file
|
||||||
|
if not log_file_path.parent.exists():
|
||||||
|
log_file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# 创建新实例
|
||||||
|
_logger = logging.getLogger(log_file_path.stem)
|
||||||
|
|
||||||
# DEBUG
|
# DEBUG
|
||||||
logger = logging.getLogger()
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
logger.setLevel(logging.DEBUG)
|
_logger.setLevel(logging.DEBUG)
|
||||||
else:
|
else:
|
||||||
logger.setLevel(logging.INFO)
|
_logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
# 移除已有的 handler,避免重复添加
|
||||||
|
for handler in _logger.handlers:
|
||||||
|
_logger.removeHandler(handler)
|
||||||
|
|
||||||
# 终端日志
|
# 终端日志
|
||||||
console_handler = logging.StreamHandler()
|
console_handler = logging.StreamHandler()
|
||||||
console_handler.setLevel(logging.DEBUG)
|
console_handler.setLevel(logging.DEBUG)
|
||||||
console_formatter = CustomFormatter("%(leveltext)s%(filename)s - %(message)s")
|
console_formatter = CustomFormatter("%(leveltext)s%(filename)s - %(message)s")
|
||||||
console_handler.setFormatter(console_formatter)
|
console_handler.setFormatter(console_formatter)
|
||||||
logger.addHandler(console_handler)
|
_logger.addHandler(console_handler)
|
||||||
|
|
||||||
# 文件日志
|
# 文件日志
|
||||||
file_handler = RotatingFileHandler(filename=settings.LOG_PATH / 'moviepilot.log',
|
file_handler = RotatingFileHandler(filename=log_file_path,
|
||||||
mode='w',
|
mode='w',
|
||||||
maxBytes=5 * 1024 * 1024,
|
maxBytes=5 * 1024 * 1024,
|
||||||
backupCount=3,
|
backupCount=3,
|
||||||
@ -54,4 +81,63 @@ file_handler = RotatingFileHandler(filename=settings.LOG_PATH / 'moviepilot.log'
|
|||||||
file_handler.setLevel(logging.INFO)
|
file_handler.setLevel(logging.INFO)
|
||||||
file_formater = CustomFormatter("【%(levelname)s】%(asctime)s - %(filename)s - %(message)s")
|
file_formater = CustomFormatter("【%(levelname)s】%(asctime)s - %(filename)s - %(message)s")
|
||||||
file_handler.setFormatter(file_formater)
|
file_handler.setFormatter(file_formater)
|
||||||
logger.addHandler(file_handler)
|
_logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
return _logger
|
||||||
|
|
||||||
|
def logger(self, path: str) -> logging.Logger:
|
||||||
|
"""
|
||||||
|
获取模块的logger
|
||||||
|
:param path: 当前运行程序路径
|
||||||
|
"""
|
||||||
|
filepath = Path(path)
|
||||||
|
|
||||||
|
# 区分插件日志
|
||||||
|
if "plugins" in filepath.parts:
|
||||||
|
# 使用插件日志文件
|
||||||
|
plugin_name = filepath.parts[filepath.parts.index("plugins") + 1]
|
||||||
|
logfile = Path("plugins") / f"{plugin_name}.log"
|
||||||
|
else:
|
||||||
|
# 使用默认日志文件
|
||||||
|
logfile = self._default_log_file
|
||||||
|
|
||||||
|
# 获取调用者的模块的logger
|
||||||
|
_logger = self._loggers.get(logfile)
|
||||||
|
if not _logger:
|
||||||
|
_logger = self.__setup_logger(logfile)
|
||||||
|
self._loggers[logfile] = _logger
|
||||||
|
return _logger
|
||||||
|
|
||||||
|
def info(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
重载info方法,按模块区分输出
|
||||||
|
"""
|
||||||
|
self.logger(inspect.stack()[1].filename).info(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def debug(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
重载debug方法,按模块区分输出
|
||||||
|
"""
|
||||||
|
self.logger(inspect.stack()[1].filename).debug(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def warning(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
重载warning方法,按模块区分输出
|
||||||
|
"""
|
||||||
|
self.logger(inspect.stack()[1].filename).warning(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def error(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
重载error方法,按模块区分输出
|
||||||
|
"""
|
||||||
|
self.logger(inspect.stack()[1].filename).error(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
def critical(self, msg, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
重载critical方法,按模块区分输出
|
||||||
|
"""
|
||||||
|
self.logger(inspect.stack()[1].filename).critical(msg, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# 初始化公共日志
|
||||||
|
logger = LoggerManager()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user