LifeFlow-AI / src /infra /logger.py
Marco310's picture
feat(v1.0.1): upgrade planner reasoning, map visuals, and presenter output
9066e49
raw
history blame
2.35 kB
import logging
import os
from config import LOG_LEVEL
__all__ = ["get_logger"]
DEFAULT_LOG_LEVEL = LOG_LEVEL
class ColoredFormatter(logging.Formatter):
"""Optional: Add colors for better readability in terminal"""
# ANSI color codes
COLORS = {
'DEBUG': '\033[36m', # Cyan
'INFO': '\033[32m', # Green
'WARNING': '\033[33m', # Yellow
'ERROR': '\033[31m', # Red
'CRITICAL': '\033[35m', # Magenta
}
RESET = '\033[0m'
def format(self, record: logging.LogRecord) -> str:
if record.levelname in self.COLORS:
record.levelname = (
f"{self.COLORS[record.levelname]}"
f"[{record.levelname}]{self.RESET}"
)
return super().format(record)
def get_logger(
name: str = "lifeflow",
use_colors: bool = True,
level: str = None
) -> logging.Logger:
"""
取得 Logger 實例
Args:
name: Logger 名稱
use_colors: 是否使用彩色輸出(預設開啟)
Returns:
Logger
Example:
logger = get_logger(__name__)
logger.info("Operation completed")
try:
risky_operation()
except Exception as e:
logger.error("Operation failed", exc_info=True)
logger.debug(f"Processing {len(items)} items")
"""
logger = logging.getLogger(name)
# 避免重複設定
if logger.handlers:
return logger
log_level = os.getenv("LOG_LEVEL", DEFAULT_LOG_LEVEL) if level is None else level
logger.setLevel(log_level.upper() if isinstance(log_level, str) else log_level)
# 建立 Console Handler
handler = logging.StreamHandler()
handler.setLevel(log_level)
# 選擇 Formatter
if use_colors and os.getenv("NO_COLOR") is None:
# 終端機支援顏色
formatter = ColoredFormatter(
fmt="%(levelname)-7s | %(asctime)s | %(name)s: %(message)s",
datefmt="%H:%M:%S"
)
else:
# 純文字(例如:導向檔案、CI/CD 環境)
formatter = logging.Formatter(
fmt="%(levelname)-5s | (asctime)s | %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.propagate = False
return logger