- Move SystemLogger implementation to utils/logger_manager.py (pure utility, no deps) - services/logger_manager.py becomes a backward-compat re-export shim - database/manager.py and database/vendor_manager.py now import from utils layer - Extract get_dashboard_stats() to services/dashboard_service.py - services/task_runner.py no longer imports from routes layer - routes/dashboard_routes.py get_dashboard_stats() delegates to service layer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
import logging
|
|
import os
|
|
import sys
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
class SystemLogger:
|
|
"""
|
|
自定義系統日誌管理器
|
|
封裝 logging 模組,提供統一的日誌格式與輸出設定 (Console + File)
|
|
"""
|
|
def __init__(self, name="System", log_file='system.log'):
|
|
self.logger = logging.getLogger(name)
|
|
self.logger.setLevel(logging.DEBUG)
|
|
|
|
# 避免重複添加 Handler (防止日誌重複輸出)
|
|
if not self.logger.handlers:
|
|
# 取得專案根目錄 (假設此檔案位於 utils/ 目錄下,往上兩層為根目錄)
|
|
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
log_dir = os.path.join(base_dir, 'logs')
|
|
|
|
# 確保 logs 目錄存在
|
|
if not os.path.exists(log_dir):
|
|
try:
|
|
os.makedirs(log_dir)
|
|
except OSError:
|
|
pass # 忽略無法建立目錄的錯誤,改由 Console 輸出
|
|
|
|
file_path = os.path.join(log_dir, log_file)
|
|
|
|
# 1. 檔案輸出 (RotatingFileHandler) - 支援自動切割
|
|
try:
|
|
file_handler = RotatingFileHandler(
|
|
file_path,
|
|
maxBytes=10*1024*1024, # 10MB 切割
|
|
backupCount=5,
|
|
encoding='utf-8'
|
|
)
|
|
file_handler.setLevel(logging.DEBUG)
|
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
file_handler.setFormatter(formatter)
|
|
self.logger.addHandler(file_handler)
|
|
except Exception as e:
|
|
print(f"⚠️ Logger Init Warning: 無法建立日誌檔案 ({e})")
|
|
|
|
# 2. 控制台輸出 (StreamHandler)
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(logging.INFO)
|
|
console_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
|
console_handler.setFormatter(console_formatter)
|
|
self.logger.addHandler(console_handler)
|
|
|
|
def get_logger(self):
|
|
return self.logger
|