feat(logging): 为 aria2 安装器、服务和 Telegram 处理器添加详细日志记录

This commit is contained in:
dnslin
2025-12-12 08:39:36 +08:00
parent 3b2e0ee822
commit 342aef7e1e
3 changed files with 96 additions and 0 deletions

View File

@@ -11,6 +11,8 @@ from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
from urllib import error, request
from src.utils.logger import get_logger
from src.core import (
ARIA2_BIN,
ARIA2_CONFIG_DIR,
@@ -28,6 +30,9 @@ from src.core import (
)
logger = get_logger("installer")
class Aria2Installer:
GITHUB_API = "https://api.github.com/repos/P3TERX/Aria2-Pro-Core/releases/latest"
GITHUB_MIRROR = "https://gh-api.p3terx.com/repos/P3TERX/Aria2-Pro-Core/releases/latest"
@@ -45,11 +50,13 @@ class Aria2Installer:
async def get_latest_version(self) -> str:
"""从 GitHub API 获取最新版本号"""
logger.info("正在获取 aria2 最新版本...")
loop = asyncio.get_running_loop()
last_error: Exception | None = None
for url in (self.GITHUB_API, self.GITHUB_MIRROR):
try:
logger.info(f"尝试从 {url} 获取版本信息")
data = await loop.run_in_executor(
self._executor, functools.partial(self._fetch_url, url)
)
@@ -57,8 +64,10 @@ class Aria2Installer:
tag_name = payload.get("tag_name")
if not tag_name:
raise DownloadError("tag_name missing in GitHub API response")
logger.info(f"获取到最新版本: {tag_name}")
return tag_name
except Exception as exc: # noqa: PERF203
logger.error(f"{url} 获取版本失败: {exc}")
last_error = exc
continue
@@ -74,6 +83,8 @@ class Aria2Installer:
f"{resolved_version}/{archive_name}"
)
logger.info(f"正在下载 aria2 二进制文件: {archive_name}")
logger.info(f"下载地址: {download_url}")
loop = asyncio.get_running_loop()
with tempfile.TemporaryDirectory() as tmpdir:
@@ -89,14 +100,18 @@ class Aria2Installer:
await loop.run_in_executor(
self._executor, functools.partial(self._write_file, archive_path, data)
)
logger.info("二进制文件下载完成")
except Exception as exc: # noqa: PERF203
logger.error(f"下载二进制文件失败: {exc}")
raise DownloadError(f"Failed to download aria2 binary: {exc}") from exc
try:
logger.info("正在解压二进制文件...")
binary_path = await loop.run_in_executor(
self._executor, functools.partial(self._extract_binary, archive_path, extract_dir)
)
except Exception as exc: # noqa: PERF203
logger.error(f"解压二进制文件失败: {exc}")
raise DownloadError(f"Failed to extract aria2 binary: {exc}") from exc
try:
@@ -105,13 +120,16 @@ class Aria2Installer:
ARIA2_BIN.unlink()
shutil.move(str(binary_path), ARIA2_BIN)
ARIA2_BIN.chmod(0o755)
logger.info(f"aria2 二进制文件已安装到: {ARIA2_BIN}")
except Exception as exc: # noqa: PERF203
logger.error(f"安装二进制文件失败: {exc}")
raise DownloadError(f"Failed to install aria2 binary: {exc}") from exc
return ARIA2_BIN
async def download_config(self) -> None:
"""下载配置模板文件"""
logger.info("正在下载配置文件...")
ARIA2_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
loop = asyncio.get_running_loop()
@@ -127,16 +145,19 @@ class Aria2Installer:
await loop.run_in_executor(
self._executor, functools.partial(self._write_file, target, data)
)
logger.info(f"配置文件已下载: {filename}")
last_error = None
break
except Exception as exc: # noqa: PERF203
last_error = exc
continue
if last_error is not None:
logger.error(f"下载配置文件失败: {filename} - {last_error}")
raise DownloadError(f"Failed to download {filename}: {last_error}") from last_error
def render_config(self) -> None:
"""渲染配置文件,注入用户参数"""
logger.info("正在渲染配置文件...")
if not ARIA2_CONF.exists():
raise ConfigError("Config template not found. Run download_config first.")
@@ -156,6 +177,8 @@ class Aria2Installer:
"max-connection-per-server=": str(self.config.max_connection_per_server),
}
logger.info(f"配置参数: RPC端口={self.config.rpc_port}, 下载目录={self.config.download_dir}")
new_lines: list[str] = []
for line in content.splitlines():
stripped = line.lstrip()
@@ -174,16 +197,20 @@ class Aria2Installer:
ARIA2_SESSION.touch(exist_ok=True)
self.config.download_dir.mkdir(parents=True, exist_ok=True)
ARIA2_LOG.touch(exist_ok=True)
logger.info(f"配置文件已保存: {ARIA2_CONF}")
except OSError as exc:
logger.error(f"保存配置文件失败: {exc}")
raise ConfigError(f"Failed to render config: {exc}") from exc
async def install(self, version: str | None = None) -> dict:
"""完整安装流程"""
logger.info("开始安装 aria2...")
resolved_version = version or await self.get_latest_version()
await self.download_binary(resolved_version)
await self.download_config()
self.render_config()
logger.info(f"aria2 安装完成! 版本: {resolved_version}, 路径: {ARIA2_BIN}")
return {
"version": resolved_version,
"binary": str(ARIA2_BIN),
@@ -195,31 +222,40 @@ class Aria2Installer:
def uninstall(self) -> None:
"""卸载 aria2"""
logger.info("开始卸载 aria2...")
errors: list[Exception] = []
try:
if ARIA2_BIN.exists():
ARIA2_BIN.unlink()
logger.info(f"已删除二进制文件: {ARIA2_BIN}")
except Exception as exc: # noqa: PERF203
logger.error(f"删除二进制文件失败: {exc}")
errors.append(exc)
try:
if ARIA2_CONFIG_DIR.exists():
shutil.rmtree(ARIA2_CONFIG_DIR)
logger.info(f"已删除配置目录: {ARIA2_CONFIG_DIR}")
except Exception as exc: # noqa: PERF203
logger.error(f"删除配置目录失败: {exc}")
errors.append(exc)
try:
service_path = Path.home() / ".config" / "systemd" / "user" / "aria2.service"
if service_path.exists():
service_path.unlink()
logger.info(f"已删除服务文件: {service_path}")
except Exception as exc: # noqa: PERF203
logger.error(f"删除服务文件失败: {exc}")
errors.append(exc)
if errors:
messages = "; ".join(str(err) for err in errors)
raise Aria2Error(f"Failed to uninstall aria2: {messages}")
logger.info("aria2 卸载完成")
def _fetch_url(self, url: str) -> bytes:
"""阻塞式 URL 获取,放在线程池中运行"""
req = request.Request(url, headers={"User-Agent": "aria2-installer"})