Skip to content

Commit b791d7b

Browse files
committed
feat: 导出日志
1 parent 4ea34d5 commit b791d7b

2 files changed

Lines changed: 77 additions & 1 deletion

File tree

aao/ui/settings_page.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,17 @@ def _build_ui(self) -> None:
356356
bg_form.addRow("透明度:", bg_op_row)
357357
self._add_collapsible(root, "settings_background", "背景图", bg_box, "设置主控台背景图片")
358358

359+
# --- 日志 ---
360+
log_box = QGroupBox("日志")
361+
log_layout = QVBoxLayout(log_box)
362+
log_layout.addWidget(QLabel("导出全部日志,便于反馈排查。"))
363+
self.btn_export_log = QPushButton("📦 导出日志")
364+
log_row = QHBoxLayout()
365+
log_row.addWidget(self.btn_export_log)
366+
log_row.addStretch()
367+
log_layout.addLayout(log_row)
368+
self._add_collapsible(root, "settings_log", "日志", log_box, "导出运行时日志")
369+
359370
root.addStretch()
360371

361372
# 日志
@@ -374,6 +385,7 @@ def _build_ui(self) -> None:
374385
self.btn_preview.clicked.connect(self._preview_window)
375386
self.btn_save_win.clicked.connect(self._save_window)
376387
self.btn_token_eye.clicked.connect(self._toggle_token_visible)
388+
self.btn_export_log.clicked.connect(self._on_export_log)
377389

378390
self._windows: list = [] # DesktopWindow 列表(与 list_windows 行对应)
379391
self._preview_thread: QThread | None = None
@@ -513,6 +525,39 @@ def _toggle_token_visible(self) -> None:
513525
self.edit_github_token.setEchoMode(QLineEdit.EchoMode.Password)
514526
self.btn_token_eye.setText("👁")
515527

528+
def _on_export_log(self) -> None:
529+
"""导出 debug/ 全部日志为 zip:弹保存对话框 → 打包 → 打开所在文件夹。"""
530+
from datetime import datetime
531+
532+
from aao.utils.logger import export_logs
533+
534+
default_name = f"aao-logs-{datetime.now().strftime('%Y%m%d-%H%M%S')}.zip"
535+
dest, _ = QFileDialog.getSaveFileName(self, "导出日志", default_name, "ZIP 压缩包 (*.zip)")
536+
if not dest:
537+
return
538+
try:
539+
n = export_logs(Path(dest))
540+
except Exception as e: # noqa: BLE001
541+
logger.exception("导出日志失败")
542+
QMessageBox.warning(self, "导出失败", f"导出日志失败:{e}")
543+
return
544+
if n == 0:
545+
self.lbl_op.setText("无日志可导出(debug/ 不存在)")
546+
return
547+
self.lbl_op.setText(f"已导出 {n} 个日志文件到 {dest}")
548+
# 打开所在文件夹并选中(Windows explorer /select)
549+
from aao.utils.runtime_paths import is_frozen
550+
551+
if is_frozen():
552+
import subprocess
553+
554+
subprocess.Popen(["explorer", "/select,", str(Path(dest).resolve())])
555+
else:
556+
from PySide6.QtCore import QUrl
557+
from PySide6.QtGui import QDesktopServices
558+
559+
QDesktopServices.openUrl(QUrl.fromLocalFile(str(Path(dest).parent)))
560+
516561
def _on_theme_changed(self, idx: int) -> None:
517562
"""主题下拉切换:即时应用 + 持久化(纯 UI 偏好,无需重启或点保存按钮)。"""
518563
mode = theme.MODES[idx]

aao/utils/logger.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,35 @@ def add_qt_sink(callback: Callable[[str], None], level: str = "INFO") -> Any:
138138
return _loguru_logger.add(callback, format=_CONSOLE_FORMAT, level=level, colorize=False)
139139

140140

141-
__all__ = ["setup_logging", "add_qt_sink", "logger"]
141+
def export_logs(dest_zip: Path) -> int:
142+
"""把整个 debug/ 目录打成 zip(aao 日志 + maafw.log + 历史压缩包)。
143+
144+
用于用户反馈/排查:一键导出全部运行时日志。当前正在写的日志文件会被
145+
读取后写入 zip(loguru enqueue 的文件句柄不阻止读取)。
146+
147+
Args:
148+
dest_zip: 目标 zip 路径。
149+
150+
Returns:
151+
打入 zip 的文件数;debug/ 不存在返回 0。
152+
"""
153+
import zipfile
154+
155+
from aao.utils.runtime_paths import project_root
156+
157+
debug_dir = project_root() / "debug"
158+
if not debug_dir.exists():
159+
return 0
160+
161+
dest_zip.parent.mkdir(parents=True, exist_ok=True)
162+
count = 0
163+
with zipfile.ZipFile(dest_zip, "w", zipfile.ZIP_DEFLATED) as zf:
164+
for p in sorted(debug_dir.rglob("*")):
165+
if p.is_file():
166+
# zip 内相对路径保留 debug/aao/... 与 debug/maafw.log 结构
167+
zf.write(p, p.relative_to(debug_dir.parent))
168+
count += 1
169+
return count
170+
171+
172+
__all__ = ["setup_logging", "add_qt_sink", "export_logs", "logger"]

0 commit comments

Comments
 (0)