# scraper/logger.py import logging from io import StringIO # In-memory buffer (voor eindresultaat) LOG_BUFFER = StringIO() # List van callbacks (SSE-clients) LISTENERS = [] def add_listener(callback): """Registreer een SSE listener callback.""" LISTENERS.append(callback) def remove_listener(callback): """Verwijder SSE listener (bij disconnect).""" if callback in LISTENERS: LISTENERS.remove(callback) def broadcast(line): """Stuur logregel naar alle listeners.""" for cb in LISTENERS[:]: try: cb(line) except Exception: LISTENERS.remove(cb) def setup_logger(): """Creëer logger die naar console, buffer én SSE broadcast.""" logger = logging.getLogger("bookscraper") logger.setLevel(logging.DEBUG) logger.handlers = [] # formatter fmt = logging.Formatter("[%(levelname)s] %(message)s") # console handler ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(fmt) # buffer handler bh = logging.StreamHandler(LOG_BUFFER) bh.setLevel(logging.DEBUG) bh.setFormatter(fmt) # SSE handler class SSEHandler(logging.Handler): def emit(self, record): msg = self.format(record) broadcast(msg) sh = SSEHandler() sh.setLevel(logging.DEBUG) sh.setFormatter(fmt) logger.addHandler(ch) logger.addHandler(bh) logger.addHandler(sh) return logger # Globale logger LOGGER = setup_logger() def log_debug(msg): LOGGER.debug(msg)