Logging
Il logging e essenziale per monitorare il comportamento di unâapplicazione in produzione e diagnosticare problemi. Django utilizza il modulo logging standard di Python, estendendolo con configurazioni specifiche per il framework.
Livelli di Logging
Python definisce cinque livelli di severita, in ordine crescente:
- DEBUG: Informazioni dettagliate per il debug.
- INFO: Conferma che le operazioni funzionano come previsto.
- WARNING: Indica una situazione inaspettata o un potenziale problema.
- ERROR: Un errore che impedisce lâesecuzione di una funzionalita.
- CRITICAL: Un errore grave che potrebbe compromettere lâintera applicazione.
Componenti del Sistema di Logging
Il sistema di logging di Django si basa su quattro componenti principali:
- Loggers: Punti di ingresso per i messaggi di log.
- Handlers: Determinano dove inviare i messaggi (file, console, email).
- Formatters: Definiscono il formato dei messaggi.
- Filters: Consentono un filtraggio avanzato dei messaggi.
Configurazione Base
La configurazione avviene tramite il dizionario LOGGING in settings.py:
# settings.py
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "{levelname} {asctime} {module} {message}",
"style": "{",
},
"semplice": {
"format": "{levelname} {message}",
"style": "{",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "semplice",
},
"file": {
"class": "logging.FileHandler",
"filename": "django.log",
"formatter": "verbose",
},
},
"loggers": {
"django": {
"handlers": ["console", "file"],
"level": "INFO",
"propagate": True,
},
"myapp": {
"handlers": ["console", "file"],
"level": "DEBUG",
"propagate": False,
},
},
}
Usare il Logger nel Codice
import logging
logger = logging.getLogger(__name__)
def elabora_ordine(ordine_id):
logger.info(f"Elaborazione ordine #{ordine_id} iniziata")
try:
ordine = Ordine.objects.get(pk=ordine_id)
ordine.stato = "in_lavorazione"
ordine.save()
logger.debug(f"Ordine #{ordine_id}: stato aggiornato a in_lavorazione")
except Ordine.DoesNotExist:
logger.error(f"Ordine #{ordine_id} non trovato nel database")
except Exception as e:
logger.critical(f"Errore critico nell'ordine #{ordine_id}: {e}", exc_info=True)
Logger Predefiniti di Django
Django fornisce diversi logger integrati:
django.request
Registra le richieste HTTP. Errori 5xx generano messaggi ERROR, errori 4xx generano WARNING:
LOGGING = {
# ...
"loggers": {
"django.request": {
"handlers": ["file"],
"level": "WARNING",
"propagate": False,
},
},
}
django.db.backends
Registra tutte le query SQL eseguite dallâORM, utile per il debug delle prestazioni:
LOGGING = {
# ...
"loggers": {
"django.db.backends": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": False,
},
},
}
Filtri Personalizzati
I filtri permettono un controllo granulare su quali messaggi vengono registrati:
# myapp/log_filters.py
import logging
class SoloProduzioneFilter(logging.Filter):
def filter(self, record):
from django.conf import settings
return not settings.DEBUG
# settings.py
LOGGING = {
# ...
"filters": {
"solo_produzione": {
"()": "myapp.log_filters.SoloProduzioneFilter",
},
},
"handlers": {
"file_produzione": {
"class": "logging.FileHandler",
"filename": "produzione.log",
"formatter": "verbose",
"filters": ["solo_produzione"],
},
},
}
Handler per Rotazione File
Per evitare che i file di log crescano indefinitamente:
LOGGING = {
# ...
"handlers": {
"file_rotante": {
"class": "logging.handlers.RotatingFileHandler",
"filename": "django.log",
"maxBytes": 1024 * 1024 * 5, # 5 MB
"backupCount": 5,
"formatter": "verbose",
},
"file_giornaliero": {
"class": "logging.handlers.TimedRotatingFileHandler",
"filename": "django.log",
"when": "midnight",
"backupCount": 30,
"formatter": "verbose",
},
},
}
Notifiche Email per Errori Critici
Django puo inviare email quando si verificano errori gravi:
LOGGING = {
# ...
"handlers": {
"mail_admins": {
"class": "django.utils.log.AdminEmailHandler",
"level": "ERROR",
"formatter": "verbose",
},
},
"loggers": {
"django.request": {
"handlers": ["mail_admins", "file"],
"level": "ERROR",
"propagate": False,
},
},
}
Conclusione
Un sistema di logging ben configurato e indispensabile per qualsiasi applicazione Django in produzione. Configura handler diversi per sviluppo e produzione, usa i logger predefiniti di Django come django.request e django.db.backends per il monitoraggio, e implementa la rotazione dei file per una gestione efficiente dello spazio su disco.