python-tkinter-logger/examples/tkinter_logger_example.py
2025-11-26 08:27:14 +01:00

467 lines
14 KiB
Python

"""
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("<<ComboboxSelected>>", 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()