467 lines
14 KiB
Python
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()
|