francis-botcon / src /logger.py
Rojaldo
Initialize Francis Botcon Gradio Space with model files
4e5fc16
"""Logging configuration for Francis Botcon project."""
import logging
import sys
from pathlib import Path
from typing import Optional
class LoggerSetup:
"""Setup and manage application logging."""
_logger_instance: Optional[logging.Logger] = None
@classmethod
def setup(cls, log_level: str = "INFO", log_file: Optional[str] = None) -> logging.Logger:
"""Setup logging configuration.
Args:
log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
log_file: Optional file path for logging output
Returns:
Configured logger instance
"""
if cls._logger_instance is not None:
return cls._logger_instance
logger = logging.getLogger("francis_botcon")
logger.setLevel(getattr(logging, log_level.upper()))
# Console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(getattr(logging, log_level.upper()))
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# File handler (if log_file provided)
if log_file:
log_path = Path(log_file)
log_path.parent.mkdir(parents=True, exist_ok=True)
file_handler = logging.FileHandler(log_path)
file_handler.setLevel(getattr(logging, log_level.upper()))
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
cls._logger_instance = logger
return logger
@classmethod
def get_logger(cls) -> logging.Logger:
"""Get logger instance (creates with defaults if not yet setup)."""
if cls._logger_instance is None:
cls.setup()
return cls._logger_instance
def get_logger(name: str = "francis_botcon") -> logging.Logger:
"""Get a logger instance.
Args:
name: Logger name
Returns:
Logger instance
"""
return logging.getLogger(name)