# --- START OF FILE logger_config.py --- import logging import os import sys # Per fallback print su stderr # Costante per il nome del file di log condivisa LOG_FILE = "git_svn_sync.log" # Formato standard per i messaggi di log nel file LOG_FORMAT = "%(asctime)s - %(levelname)s - [%(funcName)s] - %(message)s" LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" # Mappa per convertire livelli numerici in nomi (utile per logging) LOG_LEVEL_MAP = { logging.CRITICAL: "CRITICAL", logging.ERROR: "ERROR", logging.WARNING: "WARNING", logging.INFO: "INFO", logging.DEBUG: "DEBUG", logging.NOTSET: "NOTSET", } def get_log_level_name(level_no): """Restituisce il nome stringa leggibile per un livello di logging numerico.""" return LOG_LEVEL_MAP.get(level_no, f"LEVEL_{level_no}") def setup_file_logging(level=logging.INFO): """ Configura il logging di base dell'applicazione per scrivere su un file. Questa funzione aggiunge un FileHandler al logger root. NON gestisce più la configurazione del logger per la GUI (TextHandler rimosso). Args: level (int): Il livello minimo di log da scrivere nel file (es. logging.INFO, logging.DEBUG). Default è logging.INFO. """ try: # Crea un formattatore standard per i log su file log_formatter = logging.Formatter(LOG_FORMAT, datefmt=LOG_DATE_FORMAT) # Configura il File Handler # mode='a' per appendere al file esistente file_handler = logging.FileHandler(LOG_FILE, mode="a", encoding="utf-8") file_handler.setLevel(level) # Imposta il livello per questo handler file_handler.setFormatter(log_formatter) # Ottieni il logger root dell'applicazione # Aggiungere l'handler al root logger assicura che tutti i logger # (a meno che non abbiano propagate=False) inviino messaggi a questo file. root_logger = logging.getLogger() # Rimuovi eventuali handler di file preesistenti con lo stesso nome file # per evitare log duplicati se questa funzione viene chiamata più volte. log_file_abs_path = os.path.abspath(LOG_FILE) for handler in root_logger.handlers[:]: if isinstance(handler, logging.FileHandler): # Assumi che l'handler corrente punti allo stesso file # Nota: handler.baseFilename potrebbe non essere sempre impostato # a seconda di come è stato creato l'handler. # Questa logica di rimozione è opzionale ma può prevenire duplicati. try: if getattr(handler, "baseFilename", None) == log_file_abs_path: root_logger.removeHandler(handler) handler.close() # Chiudi l'handler rimosso print(f"Removed existing file handler for: {log_file_abs_path}") except Exception as e_rm: print( f"Warning: Could not check/remove existing file handler: {e_rm}" ) # Aggiungi il nuovo file handler configurato root_logger.addHandler(file_handler) # Imposta il livello del logger root. Questo è importante perché se un # logger specifico non ha un livello impostato esplicitamente, eredita # quello del genitore. Se il root è troppo restrittivo (es. WARNING), # i messaggi INFO/DEBUG non raggiungeranno mai l'handler. # Impostarlo al livello più permissivo degli handler collegati (o DEBUG # se si prevede di aggiungere handler DEBUG in futuro) è una buona pratica. effective_level = min( level, root_logger.level if root_logger.level != logging.NOTSET else level ) # Per sicurezza, impostiamo il livello root almeno al livello del nostro file handler root_logger.setLevel(effective_level) # Log su console per confermare la configurazione log_level_name = get_log_level_name(level) print( f"File logging configured. Minimum level for file: {log_level_name}. " f"File path: {log_file_abs_path}" ) # Scrivi un messaggio iniziale nel file di log stesso # Usa direttamente il modulo logging qui, dato che abbiamo appena configurato il root logger. logging.info(f"--- File logging initialized (Level: {log_level_name}) ---") except Exception as e: # Fallback critico: se il logging su file fallisce, logga errori sulla console # Usa print su stderr come ultima risorsa. error_message = f"CRITICAL: Failed to set up file logging for '{LOG_FILE}': {e}" print(error_message, file=sys.stderr) # Prova a usare basicConfig per loggare l'errore su console se possibile logging.basicConfig(level=logging.ERROR) logging.critical(error_message, exc_info=True) # --- END OF FILE logger_config.py ---