feat: implement logging service with file output
- setup_logging() creates logs/ dir and writes timestamped log file - format: asctime name levelname message - falls back to console-only if log dir is not writable - main.py now calls setup_logging() at startup and logs app name/version Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+9
-1
@@ -1,18 +1,26 @@
|
|||||||
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from PySide6.QtWidgets import QApplication
|
from PySide6.QtWidgets import QApplication
|
||||||
|
|
||||||
from app.main_window import MainWindow
|
from app.main_window import MainWindow
|
||||||
from version import APP_NAME
|
from services.log_service import setup_logging
|
||||||
|
from version import APP_NAME, APP_VERSION
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
setup_logging()
|
||||||
|
logger.info("Application starting: %s %s", APP_NAME, APP_VERSION)
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
app.setApplicationName(APP_NAME)
|
app.setApplicationName(APP_NAME)
|
||||||
|
|
||||||
window = MainWindow()
|
window = MainWindow()
|
||||||
window.show()
|
window.show()
|
||||||
|
|
||||||
|
logger.info("Main window displayed")
|
||||||
return app.exec()
|
return app.exec()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,45 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging(log_dir=None):
|
||||||
logging.basicConfig(
|
"""Initialize file + console logging. Call once at application startup.
|
||||||
level=logging.INFO,
|
|
||||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
log_dir: absolute path to log directory. Defaults to <project_root>/logs/.
|
||||||
)
|
If the directory cannot be created, falls back to console-only logging.
|
||||||
|
"""
|
||||||
|
if log_dir is None:
|
||||||
|
# src/services/log_service.py -> src/services -> src -> project root
|
||||||
|
_here = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
log_dir = os.path.join(os.path.dirname(os.path.dirname(_here)), "logs")
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.makedirs(log_dir, exist_ok=True)
|
||||||
|
except OSError as exc:
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s %(name)s %(levelname)s %(message)s",
|
||||||
|
)
|
||||||
|
logging.getLogger(__name__).warning(
|
||||||
|
"Cannot create log directory %s: %s. Falling back to console only.", log_dir, exc
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
log_file = os.path.join(log_dir, "app_{}.log".format(timestamp))
|
||||||
|
|
||||||
|
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
|
||||||
|
|
||||||
|
root = logging.getLogger()
|
||||||
|
root.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
fh = logging.FileHandler(log_file, encoding="utf-8")
|
||||||
|
fh.setFormatter(formatter)
|
||||||
|
root.addHandler(fh)
|
||||||
|
|
||||||
|
sh = logging.StreamHandler()
|
||||||
|
sh.setFormatter(formatter)
|
||||||
|
root.addHandler(sh)
|
||||||
|
|
||||||
|
logging.getLogger(__name__).info("Logging initialized. Log file: %s", log_file)
|
||||||
|
|||||||
@@ -64,18 +64,18 @@
|
|||||||
|
|
||||||
任务:
|
任务:
|
||||||
|
|
||||||
- [ ] 先读取 `src/services/log_service.py` 现有内容
|
- [x] 先读取 `src/services/log_service.py` 现有内容
|
||||||
- [ ] 完善 `src/services/log_service.py`
|
- [x] 完善 `src/services/log_service.py`
|
||||||
- [ ] 启动时创建 `logs/` 目录
|
- [x] 启动时创建 `logs/` 目录
|
||||||
- [ ] 日志文件按启动时间或日期命名
|
- [x] 日志文件按启动时间或日期命名
|
||||||
- [ ] 日志格式包含时间、模块、级别、消息
|
- [x] 日志格式包含时间、模块、级别、消息
|
||||||
- [ ] 在 `src/main.py` 中初始化日志
|
- [x] 在 `src/main.py` 中初始化日志
|
||||||
|
|
||||||
验收:
|
验收:
|
||||||
|
|
||||||
- [ ] 启动程序后生成日志文件
|
- [x] 启动程序后生成日志文件
|
||||||
- [ ] 程序启动信息写入日志
|
- [x] 程序启动信息写入日志
|
||||||
- [ ] 不使用 `print` 作为正式日志
|
- [x] 不使用 `print` 作为正式日志
|
||||||
|
|
||||||
### 1.2 路径与资源服务
|
### 1.2 路径与资源服务
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user