import logging import sys from pathlib import Path from datetime import datetime from logging.handlers import RotatingFileHandler from app.config import settings class CustomFormatter(logging.Formatter): """Custom formatter với colors cho console""" grey = "\x1b[38;21m" blue = "\x1b[38;5;39m" yellow = "\x1b[38;5;226m" red = "\x1b[38;5;196m" bold_red = "\x1b[31;1m" reset = "\x1b[0m" format_str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" FORMATS = { logging.DEBUG: grey + format_str + reset, logging.INFO: blue + format_str + reset, logging.WARNING: yellow + format_str + reset, logging.ERROR: red + format_str + reset, logging.CRITICAL: bold_red + format_str + reset } def format(self, record): log_fmt = self.FORMATS.get(record.levelno) formatter = logging.Formatter(log_fmt, datefmt='%Y-%m-%d %H:%M:%S') return formatter.format(record) def setup_logger(name: str = "ai-core") -> logging.Logger: """ Setup logger với console và file handlers Args: name: Tên của logger Returns: Configured logger instance """ logger = logging.getLogger(name) # Set level log_level = logging.DEBUG if settings.DEBUG else logging.INFO logger.setLevel(log_level) # Tránh duplicate handlers if logger.handlers: return logger # Console Handler console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(log_level) console_handler.setFormatter(CustomFormatter()) logger.addHandler(console_handler) # File Handler logs_dir = Path("logs") logs_dir.mkdir(exist_ok=True) # Rotating file handler (10MB max, keep 5 backup files) file_handler = RotatingFileHandler( logs_dir / f"{name}.log", maxBytes=10 * 1024 * 1024, # 10MB backupCount=5, encoding='utf-8' ) file_handler.setLevel(logging.INFO) file_formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(funcName)s:%(lineno)d - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) file_handler.setFormatter(file_formatter) logger.addHandler(file_handler) # Error file handler (chỉ log errors) error_handler = RotatingFileHandler( logs_dir / f"{name}_error.log", maxBytes=10 * 1024 * 1024, backupCount=5, encoding='utf-8' ) error_handler.setLevel(logging.ERROR) error_handler.setFormatter(file_formatter) logger.addHandler(error_handler) return logger # Global logger instance logger = setup_logger()