mirror of
https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT.git
synced 2026-04-05 17:16:31 +00:00
feat(core): 集成日志记录功能以增强调试和错误处理
- 在多个模块中添加日志记录功能,替代原有的打印输出,提升调试信息的管理。 - 更新主窗口、下载管理器、离线模式管理器等,确保在关键操作中记录详细日志。 - 优化异常处理逻辑,确保在发生错误时能够记录相关信息,便于后续排查。 - 增强用户体验,通过日志记录提供更清晰的操作反馈和状态信息。
This commit is contained in:
@@ -4,6 +4,11 @@ import webbrowser
|
||||
from PySide6.QtCore import QThread, Signal
|
||||
from PySide6.QtWidgets import QMessageBox
|
||||
import sys
|
||||
from utils.logger import setup_logger
|
||||
from utils.url_censor import censor_url
|
||||
|
||||
# 初始化logger
|
||||
logger = setup_logger("config_fetch")
|
||||
|
||||
class ConfigFetchThread(QThread):
|
||||
finished = Signal(object, str) # data, error_message
|
||||
@@ -17,28 +22,27 @@ class ConfigFetchThread(QThread):
|
||||
def run(self):
|
||||
try:
|
||||
if self.debug_mode:
|
||||
print("--- Starting to fetch cloud config ---")
|
||||
logger.info("--- Starting to fetch cloud config ---")
|
||||
# 完全隐藏URL
|
||||
print(f"DEBUG: Requesting URL: ***URL protection***")
|
||||
print(f"DEBUG: Using Headers: {self.headers}")
|
||||
logger.debug(f"DEBUG: Requesting URL: ***URL protection***")
|
||||
logger.debug(f"DEBUG: Using Headers: {self.headers}")
|
||||
|
||||
response = requests.get(self.url, headers=self.headers, timeout=10)
|
||||
|
||||
if self.debug_mode:
|
||||
print(f"DEBUG: Response Status Code: {response.status_code}")
|
||||
print(f"DEBUG: Response Headers: {response.headers}")
|
||||
logger.debug(f"DEBUG: Response Status Code: {response.status_code}")
|
||||
logger.debug(f"DEBUG: Response Headers: {response.headers}")
|
||||
|
||||
# 解析并隐藏响应中的敏感URL
|
||||
try:
|
||||
response_data = response.json()
|
||||
# 创建安全版本用于日志输出
|
||||
safe_response = self._create_safe_config_for_logging(response_data)
|
||||
print(f"DEBUG: Response Text: {json.dumps(safe_response, indent=2)}")
|
||||
logger.debug(f"DEBUG: Response Text: {json.dumps(safe_response, indent=2)}")
|
||||
except:
|
||||
# 如果不是JSON,直接打印文本
|
||||
from utils.helpers import censor_url
|
||||
censored_text = censor_url(response.text)
|
||||
print(f"DEBUG: Response Text: {censored_text}")
|
||||
logger.debug(f"DEBUG: Response Text: {censored_text}")
|
||||
|
||||
response.raise_for_status()
|
||||
|
||||
@@ -74,7 +78,7 @@ class ConfigFetchThread(QThread):
|
||||
self.finished.emit(None, error_msg)
|
||||
finally:
|
||||
if self.debug_mode:
|
||||
print("--- Finished fetching cloud config ---")
|
||||
logger.info("--- Finished fetching cloud config ---")
|
||||
|
||||
def _create_safe_config_for_logging(self, config_data):
|
||||
"""创建用于日志记录的安全配置副本,隐藏敏感URL
|
||||
|
||||
@@ -8,9 +8,14 @@ from PySide6.QtCore import (Qt, Signal, QThread, QTimer)
|
||||
from PySide6.QtWidgets import (QLabel, QProgressBar, QVBoxLayout, QDialog, QHBoxLayout)
|
||||
from utils import resource_path
|
||||
from data.config import APP_NAME, UA
|
||||
from utils.logger import setup_logger
|
||||
import signal
|
||||
import ctypes
|
||||
import time
|
||||
from utils.url_censor import censor_url
|
||||
|
||||
# 初始化logger
|
||||
logger = setup_logger("download")
|
||||
|
||||
if sys.platform == 'win32':
|
||||
kernel32 = ctypes.windll.kernel32
|
||||
@@ -49,7 +54,7 @@ class DownloadThread(QThread):
|
||||
try:
|
||||
subprocess.run(['taskkill', '/F', '/T', '/PID', str(self.process.pid)], check=True, creationflags=subprocess.CREATE_NO_WINDOW)
|
||||
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
||||
print(f"停止下载进程时出错: {e}")
|
||||
logger.error(f"停止下载进程时出错: {e}")
|
||||
|
||||
def _get_process_threads(self, pid):
|
||||
"""获取进程的所有线程ID"""
|
||||
@@ -80,7 +85,7 @@ class DownloadThread(QThread):
|
||||
if sys.platform == 'win32':
|
||||
self.threads = self._get_process_threads(self.process.pid)
|
||||
if not self.threads:
|
||||
print("未找到可暂停的线程")
|
||||
logger.warning("未找到可暂停的线程")
|
||||
return False
|
||||
|
||||
for thread_id in self.threads:
|
||||
@@ -90,15 +95,15 @@ class DownloadThread(QThread):
|
||||
kernel32.CloseHandle(h_thread)
|
||||
|
||||
self._is_paused = True
|
||||
print(f"下载进程已暂停: PID {self.process.pid}, 线程数: {len(self.threads)}")
|
||||
logger.info(f"下载进程已暂停: PID {self.process.pid}, 线程数: {len(self.threads)}")
|
||||
return True
|
||||
else:
|
||||
os.kill(self.process.pid, signal.SIGSTOP)
|
||||
self._is_paused = True
|
||||
print(f"下载进程已暂停: PID {self.process.pid}")
|
||||
logger.info(f"下载进程已暂停: PID {self.process.pid}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"暂停下载进程时出错: {e}")
|
||||
logger.error(f"暂停下载进程时出错: {e}")
|
||||
return False
|
||||
return False
|
||||
|
||||
@@ -114,15 +119,15 @@ class DownloadThread(QThread):
|
||||
kernel32.CloseHandle(h_thread)
|
||||
|
||||
self._is_paused = False
|
||||
print(f"下载进程已恢复: PID {self.process.pid}, 线程数: {len(self.threads)}")
|
||||
logger.info(f"下载进程已恢复: PID {self.process.pid}, 线程数: {len(self.threads)}")
|
||||
return True
|
||||
else:
|
||||
os.kill(self.process.pid, signal.SIGCONT)
|
||||
self._is_paused = False
|
||||
print(f"下载进程已恢复: PID {self.process.pid}")
|
||||
logger.info(f"下载进程已恢复: PID {self.process.pid}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"恢复下载进程时出错: {e}")
|
||||
logger.error(f"恢复下载进程时出错: {e}")
|
||||
return False
|
||||
return False
|
||||
|
||||
@@ -155,7 +160,7 @@ class DownloadThread(QThread):
|
||||
if hasattr(self.parent(), 'config'):
|
||||
ipv6_enabled = self.parent().config.get("ipv6_enabled", False)
|
||||
|
||||
print(f"IPv6支持状态: {ipv6_enabled}")
|
||||
logger.info(f"IPv6支持状态: {ipv6_enabled}")
|
||||
|
||||
command.extend([
|
||||
'--dir', download_dir,
|
||||
@@ -192,9 +197,9 @@ class DownloadThread(QThread):
|
||||
|
||||
if not ipv6_enabled:
|
||||
command.append('--disable-ipv6=true')
|
||||
print("已禁用IPv6支持")
|
||||
logger.info("已禁用IPv6支持")
|
||||
else:
|
||||
print("已启用IPv6支持")
|
||||
logger.info("已启用IPv6支持")
|
||||
|
||||
command.append('--check-certificate=false')
|
||||
|
||||
@@ -208,7 +213,7 @@ class DownloadThread(QThread):
|
||||
if isinstance(url, str) and url.startswith("http"):
|
||||
safe_command[-1] = "***URL protection***"
|
||||
|
||||
print(f"即将执行的 Aria2c 命令: {' '.join(safe_command)}")
|
||||
logger.info(f"即将执行的 Aria2c 命令: {' '.join(safe_command)}")
|
||||
|
||||
creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
|
||||
self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, encoding='utf-8', errors='replace', creationflags=creation_flags)
|
||||
@@ -229,10 +234,9 @@ class DownloadThread(QThread):
|
||||
break
|
||||
|
||||
# 处理输出行,隐藏可能包含的URL
|
||||
from utils.helpers import censor_url
|
||||
censored_line = censor_url(line)
|
||||
full_output.append(censored_line)
|
||||
print(censored_line.strip())
|
||||
logger.debug(censored_line.strip())
|
||||
|
||||
match = progress_pattern.search(line)
|
||||
if match:
|
||||
|
||||
@@ -7,6 +7,11 @@ from urllib.parse import urlparse
|
||||
|
||||
from PySide6.QtCore import QThread, Signal
|
||||
from utils import resource_path
|
||||
from utils.logger import setup_logger
|
||||
from utils.url_censor import censor_url
|
||||
|
||||
# 初始化logger
|
||||
logger = setup_logger("ip_optimizer")
|
||||
|
||||
class IpOptimizer:
|
||||
def __init__(self):
|
||||
@@ -25,7 +30,7 @@ class IpOptimizer:
|
||||
try:
|
||||
cst_path = resource_path("cfst.exe")
|
||||
if not os.path.exists(cst_path):
|
||||
print(f"错误: cfst.exe 未在资源路径中找到。")
|
||||
logger.error(f"错误: cfst.exe 未在资源路径中找到。")
|
||||
return None
|
||||
|
||||
ip_txt_path = resource_path("ip.txt")
|
||||
@@ -51,8 +56,8 @@ class IpOptimizer:
|
||||
|
||||
creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
|
||||
|
||||
print("--- CloudflareSpeedTest 开始执行 ---")
|
||||
print(f"执行命令: {' '.join(safe_command)}")
|
||||
logger.info("--- CloudflareSpeedTest 开始执行 ---")
|
||||
logger.info(f"执行命令: {' '.join(safe_command)}")
|
||||
|
||||
self.process = subprocess.Popen(
|
||||
command,
|
||||
@@ -74,7 +79,7 @@ class IpOptimizer:
|
||||
|
||||
stdout = self.process.stdout
|
||||
if not stdout:
|
||||
print("错误: 无法获取子进程的输出流。")
|
||||
logger.error("错误: 无法获取子进程的输出流。")
|
||||
return None
|
||||
|
||||
optimal_ip = None
|
||||
@@ -94,7 +99,7 @@ class IpOptimizer:
|
||||
if not ready or not line:
|
||||
timeout_counter += 1
|
||||
if timeout_counter > max_timeout:
|
||||
print("超时: CloudflareSpeedTest 响应超时")
|
||||
logger.warning("超时: CloudflareSpeedTest 响应超时")
|
||||
break
|
||||
time.sleep(1)
|
||||
continue
|
||||
@@ -102,18 +107,17 @@ class IpOptimizer:
|
||||
timeout_counter = 0
|
||||
|
||||
# 处理输出行,隐藏可能包含的URL
|
||||
from utils.helpers import censor_url
|
||||
cleaned_line = censor_url(line.strip())
|
||||
if cleaned_line:
|
||||
print(cleaned_line)
|
||||
logger.debug(cleaned_line)
|
||||
|
||||
if "IP 地址" in cleaned_line and "平均延迟" in cleaned_line:
|
||||
print("检测到IP结果表头,准备获取IP地址...")
|
||||
logger.info("检测到IP结果表头,准备获取IP地址...")
|
||||
found_header = True
|
||||
continue
|
||||
|
||||
if "完整测速结果已写入" in cleaned_line or "按下 回车键 或 Ctrl+C 退出" in cleaned_line:
|
||||
print("检测到测速完成信息")
|
||||
logger.info("检测到测速完成信息")
|
||||
found_completion = True
|
||||
|
||||
if optimal_ip:
|
||||
@@ -123,17 +127,17 @@ class IpOptimizer:
|
||||
match = ip_pattern.search(cleaned_line)
|
||||
if match and not optimal_ip:
|
||||
optimal_ip = match.group(1)
|
||||
print(f"找到最优 IP: {optimal_ip}")
|
||||
logger.info(f"找到最优 IP: {optimal_ip}")
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"读取输出时发生错误: {e}")
|
||||
logger.error(f"读取输出时发生错误: {e}")
|
||||
break
|
||||
|
||||
if self.process and self.process.poll() is None:
|
||||
try:
|
||||
if self.process.stdin and not self.process.stdin.closed:
|
||||
print("发送退出信号...")
|
||||
logger.debug("发送退出信号...")
|
||||
self.process.stdin.write('\n')
|
||||
self.process.stdin.flush()
|
||||
except:
|
||||
@@ -141,11 +145,11 @@ class IpOptimizer:
|
||||
|
||||
self.stop()
|
||||
|
||||
print("--- CloudflareSpeedTest 执行结束 ---")
|
||||
logger.info("--- CloudflareSpeedTest 执行结束 ---")
|
||||
return optimal_ip
|
||||
|
||||
except Exception as e:
|
||||
print(f"执行 CloudflareSpeedTest 时发生错误: {e}")
|
||||
logger.error(f"执行 CloudflareSpeedTest 时发生错误: {e}")
|
||||
return None
|
||||
|
||||
def get_optimal_ipv6(self, url: str) -> str | None:
|
||||
@@ -161,12 +165,12 @@ class IpOptimizer:
|
||||
try:
|
||||
cst_path = resource_path("cfst.exe")
|
||||
if not os.path.exists(cst_path):
|
||||
print(f"错误: cfst.exe 未在资源路径中找到。")
|
||||
logger.error(f"错误: cfst.exe 未在资源路径中找到。")
|
||||
return None
|
||||
|
||||
ipv6_txt_path = resource_path("data/ipv6.txt")
|
||||
if not os.path.exists(ipv6_txt_path):
|
||||
print(f"错误: ipv6.txt 未在资源路径中找到。")
|
||||
logger.error(f"错误: ipv6.txt 未在资源路径中找到。")
|
||||
return None
|
||||
|
||||
# 隐藏敏感URL
|
||||
@@ -190,8 +194,8 @@ class IpOptimizer:
|
||||
|
||||
creation_flags = subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
|
||||
|
||||
print("--- CloudflareSpeedTest IPv6 开始执行 ---")
|
||||
print(f"执行命令: {' '.join(safe_command)}")
|
||||
logger.info("--- CloudflareSpeedTest IPv6 开始执行 ---")
|
||||
logger.info(f"执行命令: {' '.join(safe_command)}")
|
||||
|
||||
self.process = subprocess.Popen(
|
||||
command,
|
||||
@@ -213,7 +217,7 @@ class IpOptimizer:
|
||||
|
||||
stdout = self.process.stdout
|
||||
if not stdout:
|
||||
print("错误: 无法获取子进程的输出流。")
|
||||
logger.error("错误: 无法获取子进程的输出流。")
|
||||
return None
|
||||
|
||||
optimal_ipv6 = None
|
||||
@@ -233,7 +237,7 @@ class IpOptimizer:
|
||||
if not ready or not line:
|
||||
timeout_counter += 1
|
||||
if timeout_counter > max_timeout:
|
||||
print("超时: CloudflareSpeedTest IPv6 响应超时")
|
||||
logger.warning("超时: CloudflareSpeedTest IPv6 响应超时")
|
||||
break
|
||||
time.sleep(1)
|
||||
continue
|
||||
@@ -241,18 +245,17 @@ class IpOptimizer:
|
||||
timeout_counter = 0
|
||||
|
||||
# 处理输出行,隐藏可能包含的URL
|
||||
from utils.helpers import censor_url
|
||||
cleaned_line = censor_url(line.strip())
|
||||
if cleaned_line:
|
||||
print(cleaned_line)
|
||||
logger.debug(cleaned_line)
|
||||
|
||||
if "IP 地址" in cleaned_line and "平均延迟" in cleaned_line:
|
||||
print("检测到IPv6结果表头,准备获取IPv6地址...")
|
||||
logger.info("检测到IPv6结果表头,准备获取IPv6地址...")
|
||||
found_header = True
|
||||
continue
|
||||
|
||||
if "完整测速结果已写入" in cleaned_line or "按下 回车键 或 Ctrl+C 退出" in cleaned_line:
|
||||
print("检测到IPv6测速完成信息")
|
||||
logger.info("检测到IPv6测速完成信息")
|
||||
found_completion = True
|
||||
|
||||
if optimal_ipv6:
|
||||
@@ -262,17 +265,17 @@ class IpOptimizer:
|
||||
match = ipv6_pattern.search(cleaned_line)
|
||||
if match and not optimal_ipv6:
|
||||
optimal_ipv6 = match.group(1)
|
||||
print(f"找到最优 IPv6: {optimal_ipv6}")
|
||||
logger.info(f"找到最优 IPv6: {optimal_ipv6}")
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"读取输出时发生错误: {e}")
|
||||
logger.error(f"读取输出时发生错误: {e}")
|
||||
break
|
||||
|
||||
if self.process and self.process.poll() is None:
|
||||
try:
|
||||
if self.process.stdin and not self.process.stdin.closed:
|
||||
print("发送退出信号...")
|
||||
logger.debug("发送退出信号...")
|
||||
self.process.stdin.write('\n')
|
||||
self.process.stdin.flush()
|
||||
except:
|
||||
@@ -280,16 +283,16 @@ class IpOptimizer:
|
||||
|
||||
self.stop()
|
||||
|
||||
print("--- CloudflareSpeedTest IPv6 执行结束 ---")
|
||||
logger.info("--- CloudflareSpeedTest IPv6 执行结束 ---")
|
||||
return optimal_ipv6
|
||||
|
||||
except Exception as e:
|
||||
print(f"执行 CloudflareSpeedTest IPv6 时发生错误: {e}")
|
||||
logger.error(f"执行 CloudflareSpeedTest IPv6 时发生错误: {e}")
|
||||
return None
|
||||
|
||||
def stop(self):
|
||||
if self.process and self.process.poll() is None:
|
||||
print("正在终止 CloudflareSpeedTest 进程...")
|
||||
logger.info("正在终止 CloudflareSpeedTest 进程...")
|
||||
try:
|
||||
if self.process.stdin and not self.process.stdin.closed:
|
||||
self.process.stdin.write('\n')
|
||||
@@ -304,7 +307,7 @@ class IpOptimizer:
|
||||
except subprocess.TimeoutExpired:
|
||||
self.process.kill()
|
||||
self.process.wait()
|
||||
print("CloudflareSpeedTest 进程已终止。")
|
||||
logger.info("CloudflareSpeedTest 进程已终止。")
|
||||
|
||||
|
||||
class IpOptimizerThread(QThread):
|
||||
|
||||
Reference in New Issue
Block a user