|
|
|
|
|
import logging |
|
|
import logging.handlers |
|
|
import sys |
|
|
from pathlib import Path |
|
|
from typing import Optional |
|
|
|
|
|
def setup_logging( |
|
|
log_level: str = "INFO", |
|
|
log_file: Optional[str] = None, |
|
|
enable_console: bool = True, |
|
|
max_file_size: int = 10 * 1024 * 1024, |
|
|
backup_count: int = 5 |
|
|
) -> logging.Logger: |
|
|
""" |
|
|
Setup centralized logging configuration |
|
|
|
|
|
Args: |
|
|
log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
|
|
log_file: Path to log file (optional) |
|
|
enable_console: Whether to enable console logging |
|
|
max_file_size: Maximum log file size in bytes |
|
|
backup_count: Number of backup files to keep |
|
|
|
|
|
Returns: |
|
|
Configured logger instance |
|
|
""" |
|
|
|
|
|
|
|
|
if log_file: |
|
|
log_path = Path(log_file) |
|
|
log_path.parent.mkdir(parents=True, exist_ok=True) |
|
|
|
|
|
|
|
|
logger = logging.getLogger("recipe_bot") |
|
|
logger.setLevel(getattr(logging, log_level.upper())) |
|
|
|
|
|
|
|
|
logger.handlers.clear() |
|
|
|
|
|
|
|
|
formatter = logging.Formatter( |
|
|
fmt="%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s", |
|
|
datefmt="%Y-%m-%d %H:%M:%S" |
|
|
) |
|
|
|
|
|
|
|
|
if enable_console: |
|
|
console_handler = logging.StreamHandler(sys.stdout) |
|
|
console_handler.setLevel(getattr(logging, log_level.upper())) |
|
|
console_handler.setFormatter(formatter) |
|
|
logger.addHandler(console_handler) |
|
|
|
|
|
|
|
|
if log_file: |
|
|
file_handler = logging.handlers.RotatingFileHandler( |
|
|
filename=log_file, |
|
|
maxBytes=max_file_size, |
|
|
backupCount=backup_count, |
|
|
encoding='utf-8' |
|
|
) |
|
|
file_handler.setLevel(getattr(logging, log_level.upper())) |
|
|
file_handler.setFormatter(formatter) |
|
|
logger.addHandler(file_handler) |
|
|
|
|
|
|
|
|
logger.propagate = False |
|
|
|
|
|
return logger |
|
|
|
|
|
def get_logger(name: str) -> logging.Logger: |
|
|
"""Get a child logger with the specified name""" |
|
|
return logging.getLogger(f"recipe_bot.{name}") |
|
|
|
|
|
|
|
|
def setup_default_logging(): |
|
|
"""Setup default logging configuration""" |
|
|
return setup_logging( |
|
|
log_level="INFO", |
|
|
log_file="./logs/recipe_bot.log", |
|
|
enable_console=True |
|
|
) |
|
|
|