LeadGenPro / lead_gen /utils /logger.py
MaSTer-suFYan
feat: LeadGen Pro v2.0 β€” full system with bug fixes
beec01d
"""
utils/logger.py β€” Centralised logging configuration.
Writes simultaneously to stdout (coloured) and a rotating file log.
"""
import logging
import os
import sys
from datetime import datetime
from logging.handlers import RotatingFileHandler
import config
class _ColourFormatter(logging.Formatter):
"""ANSI colour codes for terminal output."""
GREY = "\033[38;5;240m"
CYAN = "\033[36m"
YELLOW = "\033[33m"
RED = "\033[31m"
BOLD_R = "\033[1;31m"
RESET = "\033[0m"
LEVEL_COLOURS = {
logging.DEBUG : GREY,
logging.INFO : CYAN,
logging.WARNING : YELLOW,
logging.ERROR : RED,
logging.CRITICAL: BOLD_R,
}
def format(self, record: logging.LogRecord) -> str:
colour = self.LEVEL_COLOURS.get(record.levelno, self.RESET)
fmt = (
f"{self.GREY}%(asctime)s{self.RESET} "
f"{colour}%(levelname)-8s{self.RESET} "
f"%(name)-20s %(message)s"
)
formatter = logging.Formatter(fmt, datefmt="%H:%M:%S")
return formatter.format(record)
def get_logger(name: str) -> logging.Logger:
"""
Return a configured logger for *name*.
All loggers share the same handlers so duplicate lines never appear.
Call once per module: logger = get_logger(__name__)
"""
logger = logging.getLogger(name)
# Avoid adding handlers more than once (module re-imports)
if logger.handlers:
return logger
level = getattr(logging, config.LOG_LEVEL.upper(), logging.INFO)
logger.setLevel(level)
# ── Console handler ──────────────────────────────────────────────────
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(level)
ch.setFormatter(_ColourFormatter())
logger.addHandler(ch)
# ── File handler ─────────────────────────────────────────────────────
if config.LOG_TO_FILE:
log_filename = os.path.join(
config.LOGS_DIR,
f"scraper_{datetime.now().strftime('%Y%m%d')}.log",
)
fh = RotatingFileHandler(
log_filename,
maxBytes=5 * 1024 * 1024, # 5 MB
backupCount=7,
encoding="utf-8",
)
fh.setLevel(level)
plain_fmt = logging.Formatter(
"%(asctime)s %(levelname)-8s %(name)-20s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
fh.setFormatter(plain_fmt)
logger.addHandler(fh)
# Prevent propagation to root logger (avoids double-printing)
logger.propagate = False
return logger