""" Esempi di utilizzo del modulo TkinterLogger. Questo file contiene diversi esempi pratici di come integrare TkinterLogger nelle tue applicazioni Python, sia con che senza GUI Tkinter. """ import sys import time import threading from pathlib import Path # Aggiungi il path del progetto per poter importare il modulo sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent)) from target_simulator.utils.tkinter_logger import ( TkinterLogger, get_logger, temporary_log_level ) import logging def esempio_1_console_semplice(): """ Esempio 1: Logging console semplice (senza GUI). Questo esempio mostra come usare TkinterLogger per logging solo console, senza bisogno di una GUI Tkinter. """ print("\n" + "="*70) print("ESEMPIO 1: Console logging semplice") print("="*70 + "\n") # Setup logger (no Tkinter, solo console) logger_system = TkinterLogger(tk_root=None) logger_system.setup( enable_console=True, enable_tkinter=False, root_level=logging.DEBUG ) # Ottieni logger e usa normalmente logger = get_logger(__name__) logger.debug("Questo è un messaggio DEBUG") logger.info("Questo è un messaggio INFO") logger.warning("Questo è un messaggio WARNING") logger.error("Questo è un messaggio ERROR") logger.critical("Questo è un messaggio CRITICAL") # Cleanup logger_system.shutdown() print() def esempio_2_console_con_file(): """ Esempio 2: Logging console + file. Mostra come salvare i log sia su console che su file con rotazione automatica. """ print("\n" + "="*70) print("ESEMPIO 2: Console + File logging") print("="*70 + "\n") import tempfile import os # Crea file temporaneo per i log temp_dir = tempfile.gettempdir() log_file = os.path.join(temp_dir, "tkinter_logger_test.log") # Setup con file handler logger_system = TkinterLogger(tk_root=None) logger_system.setup( enable_console=True, enable_file=True, file_path=log_file, file_max_bytes=1024 * 1024, # 1MB file_backup_count=2, enable_tkinter=False ) logger = get_logger(__name__) logger.info("Log salvato su console E file") logger.warning(f"File log: {log_file}") # Genera diversi log for i in range(5): logger.info(f"Messaggio {i+1}/5") logger_system.shutdown() # Verifica che il file esista if os.path.exists(log_file): print(f"\n✓ File log creato: {log_file}") with open(log_file, "r", encoding="utf-8") as f: content = f.read() print(f"✓ Dimensione: {len(content)} bytes") print(f"✓ Righe: {len(content.splitlines())}") else: print(f"\n✗ File log non trovato: {log_file}") print() def esempio_3_livelli_logger_multipli(): """ Esempio 3: Logger multipli con livelli diversi. Mostra come usare logger diversi per moduli diversi con livelli separati. """ print("\n" + "="*70) print("ESEMPIO 3: Logger multipli con livelli diversi") print("="*70 + "\n") logger_system = TkinterLogger(tk_root=None) logger_system.setup( enable_console=True, enable_tkinter=False, root_level=logging.WARNING # Root a WARNING ) # Logger per moduli diversi logger_main = get_logger("app.main") logger_db = get_logger("app.database") logger_ui = get_logger("app.ui") # Imposta livelli diversi logger_main.setLevel(logging.INFO) logger_db.setLevel(logging.DEBUG) logger_ui.setLevel(logging.WARNING) print("Logger 'app.main' (INFO):") logger_main.debug("Debug - NON verrà mostrato") logger_main.info("Info - verrà mostrato") print("\nLogger 'app.database' (DEBUG):") logger_db.debug("Debug - verrà mostrato") logger_db.info("Info - verrà mostrato") print("\nLogger 'app.ui' (WARNING):") logger_ui.info("Info - NON verrà mostrato") logger_ui.warning("Warning - verrà mostrato") logger_system.shutdown() print() def esempio_4_temporary_log_level(): """ Esempio 4: Cambio temporaneo livello logger. Mostra come usare il context manager per debug temporaneo. """ print("\n" + "="*70) print("ESEMPIO 4: Temporary log level context manager") print("="*70 + "\n") logger_system = TkinterLogger(tk_root=None) logger_system.setup(enable_console=True, enable_tkinter=False) logger = get_logger("app.module") logger.setLevel(logging.INFO) print("Logger a livello INFO:") logger.debug("Debug 1 - NON visibile") logger.info("Info 1 - visibile") print("\nAbilitazione DEBUG temporanea:") with temporary_log_level(logger, logging.DEBUG): logger.debug("Debug 2 - ORA visibile!") logger.info("Info 2 - visibile") print("\nRitorno a INFO:") logger.debug("Debug 3 - DI NUOVO non visibile") logger.info("Info 3 - visibile") logger_system.shutdown() print() def esempio_5_multithreading(): """ Esempio 5: Logging da thread multipli. Dimostra che TkinterLogger è thread-safe e gestisce correttamente log da thread diversi. """ print("\n" + "="*70) print("ESEMPIO 5: Logging da thread multipli") print("="*70 + "\n") logger_system = TkinterLogger(tk_root=None) logger_system.setup(enable_console=True, enable_tkinter=False) logger = get_logger("multithread") def worker_thread(thread_id: int, num_messages: int): """Worker che genera log.""" thread_logger = get_logger(f"worker.{thread_id}") for i in range(num_messages): thread_logger.info(f"Thread {thread_id}: Message {i+1}/{num_messages}") time.sleep(0.01) # Simula lavoro # Avvia thread multipli threads = [] for i in range(3): t = threading.Thread(target=worker_thread, args=(i+1, 5)) t.start() threads.append(t) # Aspetta completamento for t in threads: t.join() logger.info("Tutti i thread completati!") logger_system.shutdown() print() def esempio_6_tkinter_gui_completo(): """ Esempio 6: Applicazione Tkinter completa con logging. Esempio più completo di una vera applicazione con GUI Tkinter che usa il sistema di logging integrato. """ print("\n" + "="*70) print("ESEMPIO 6: Applicazione Tkinter completa") print("="*70) print("Apertura GUI... chiudi la finestra per continuare\n") import tkinter as tk from tkinter import ttk from tkinter.scrolledtext import ScrolledText class LoggingApp(tk.Tk): """Applicazione di esempio con logging integrato.""" def __init__(self): super().__init__() self.title("TkinterLogger - Demo Application") self.geometry("900x700") # Logger system self.logger_system = TkinterLogger(self) self.logger = get_logger("DemoApp") self._setup_ui() self._setup_logging() # Log iniziale self.logger.info("Application started") self.protocol("WM_DELETE_WINDOW", self.on_closing) def _setup_ui(self): """Crea l'interfaccia utente.""" # Main container main_frame = ttk.Frame(self, padding=10) main_frame.pack(fill=tk.BOTH, expand=True) # Title title_label = ttk.Label( main_frame, text="TkinterLogger Demo Application", font=("Arial", 16, "bold") ) title_label.pack(pady=(0, 10)) # Control panel control_frame = ttk.LabelFrame(main_frame, text="Controls", padding=10) control_frame.pack(fill=tk.X, pady=(0, 10)) # Log level selector level_frame = ttk.Frame(control_frame) level_frame.pack(side=tk.LEFT, fill=tk.X, expand=True) ttk.Label(level_frame, text="Log Level:").pack(side=tk.LEFT, padx=(0, 5)) self.level_var = tk.StringVar(value="INFO") level_combo = ttk.Combobox( level_frame, textvariable=self.level_var, values=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], state="readonly", width=10 ) level_combo.pack(side=tk.LEFT) level_combo.bind("<>", self.on_level_change) # Buttons btn_frame = ttk.Frame(control_frame) btn_frame.pack(side=tk.RIGHT) ttk.Button(btn_frame, text="Test Log", command=self.test_log).pack(side=tk.LEFT, padx=2) ttk.Button(btn_frame, text="Batch Logs", command=self.batch_logs).pack(side=tk.LEFT, padx=2) ttk.Button(btn_frame, text="Clear", command=self.clear_logs).pack(side=tk.LEFT, padx=2) # Log display log_frame = ttk.LabelFrame(main_frame, text="Log Output", padding=5) log_frame.pack(fill=tk.BOTH, expand=True) self.log_widget = ScrolledText( log_frame, height=30, width=100, state=tk.DISABLED, wrap=tk.WORD ) self.log_widget.pack(fill=tk.BOTH, expand=True) # Status bar self.status_var = tk.StringVar(value="Ready") status_bar = ttk.Label( self, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W ) status_bar.pack(side=tk.BOTTOM, fill=tk.X) def _setup_logging(self): """Configura il sistema di logging.""" self.logger_system.setup( enable_console=True, root_level=logging.INFO ) self.logger_system.add_tkinter_handler(self.log_widget) self.logger.setLevel(logging.INFO) def on_level_change(self, event=None): """Cambia livello logger.""" level_name = self.level_var.get() level = getattr(logging, level_name) self.logger.setLevel(level) self.logger.info(f"Log level changed to {level_name}") self.status_var.set(f"Log level: {level_name}") def test_log(self): """Genera log di test per tutti i livelli.""" self.logger.debug("This is a DEBUG message") self.logger.info("This is an INFO message") self.logger.warning("This is a WARNING message") self.logger.error("This is an ERROR message") self.logger.critical("This is a CRITICAL message") self.status_var.set("Test log generated") def batch_logs(self): """Genera batch di log per testare performance.""" self.status_var.set("Generating 200 logs...") self.update() for i in range(200): self.logger.info(f"Batch message {i+1}/200") self.status_var.set("200 logs generated") def clear_logs(self): """Pulisce il widget log.""" self.log_widget.configure(state=tk.NORMAL) self.log_widget.delete("1.0", tk.END) self.log_widget.configure(state=tk.DISABLED) self.logger.info("Log cleared") self.status_var.set("Logs cleared") def on_closing(self): """Handler chiusura applicazione.""" self.logger.info("Application closing...") self.logger_system.shutdown() self.destroy() app = LoggingApp() app.mainloop() def esempio_7_format_personalizzato(): """ Esempio 7: Formato log personalizzato. Mostra come personalizzare il formato dei messaggi di log. """ print("\n" + "="*70) print("ESEMPIO 7: Formato log personalizzato") print("="*70 + "\n") # Formato personalizzato custom_format = "[%(levelname)s] %(name)s - %(message)s" logger_system = TkinterLogger(tk_root=None) logger_system.setup( log_format=custom_format, date_format=None, # Nessun timestamp enable_console=True, enable_tkinter=False ) logger = get_logger("custom.module") print("Formato personalizzato (senza timestamp):") logger.info("Messaggio con formato custom") logger.warning("Attenzione!") logger.error("Errore!") logger_system.shutdown() print() def main(): """Menu principale per scegliere l'esempio da eseguire.""" print("\n" + "="*70) print("ESEMPI DI UTILIZZO DEL TKINTER LOGGER") print("="*70) esempi = [ ("Console logging semplice", esempio_1_console_semplice), ("Console + File logging", esempio_2_console_con_file), ("Logger multipli con livelli", esempio_3_livelli_logger_multipli), ("Temporary log level", esempio_4_temporary_log_level), ("Logging da thread multipli", esempio_5_multithreading), ("Applicazione Tkinter completa", esempio_6_tkinter_gui_completo), ("Formato log personalizzato", esempio_7_format_personalizzato), ] print("\nScegli un esempio da eseguire:") for i, (nome, _) in enumerate(esempi, 1): print(f" {i}. {nome}") print(f" {len(esempi) + 1}. Esegui tutti gli esempi (GUI esclusa)") print(" 0. Esci") try: scelta = input("\nScelta: ").strip() if scelta == "0": print("Uscita.") return scelta_num = int(scelta) if scelta_num == len(esempi) + 1: # Esegui tutti tranne GUI for i, (nome, func) in enumerate(esempi): if i != 5: # Skip GUI example func() time.sleep(0.5) elif 1 <= scelta_num <= len(esempi): # Esegui singolo esempio esempi[scelta_num - 1][1]() else: print("Scelta non valida.") except (ValueError, KeyboardInterrupt): print("\nUscita.") print("\n" + "="*70) print("Fine esempi.") print("="*70 + "\n") if __name__ == "__main__": main()