Wiem, że to już rozwiązana odpowiedź, ale zgodnie z django> = 1.3 jest nowe ustawienie logowania.
Przejście ze starego do nowego nie jest automatyczne, więc pomyślałem, że zapiszę to tutaj.
I oczywiście sprawdź dokumentację django, aby uzyskać więcej informacji.
To jest podstawowa konfiguracja, utworzona domyślnie za pomocą django-admin createproject v1.3 - przebieg może się zmienić w najnowszych wersjach django:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
}
}
}
Ta struktura jest oparta na standardowym dzienniku Python dictConfig , który dyktuje następujące bloki:
formatters - odpowiednią wartością będzie dict, w którym każdy klucz jest identyfikatorem programu formatującego, a każda wartość to dykt opisujący, jak skonfigurować odpowiednią instancję programu Formatter.
filters - odpowiednią wartością będzie dict, w którym każdy klucz jest identyfikatorem filtru, a każda wartość to dykt opisujący, jak skonfigurować odpowiednią instancję filtru.
handlers- odpowiednią wartością będzie dict, w którym każdy klucz jest identyfikatorem programu obsługi, a każda wartość jest dictem opisującym, jak skonfigurować odpowiednią instancję programu Handler. Każdy program obsługi ma następujące klucze:
class(obowiązkowy). To jest w pełni kwalifikowana nazwa klasy obsługi.
level(opcjonalny). Poziom przewodnika.
formatter(opcjonalny). Identyfikator programu formatującego dla tego programu obsługi.
filters(opcjonalny). Lista identyfikatorów filtrów dla tego modułu obsługi.
Zwykle robię przynajmniej to:
- dodaj plik .log
- skonfigurować moje aplikacje do zapisywania w tym dzienniku
Co przekłada się na:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'null': {
'level':'DEBUG',
'class':'django.utils.log.NullHandler',
},
'console':{
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
# I always add this handler to facilitate separating loggings
'log_file':{
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(VAR_ROOT, 'logs/django.log'),
'maxBytes': '16777216', # 16megabytes
'formatter': 'verbose'
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
'apps': { # I keep all my of apps under 'apps' folder, but you can also add them one by one, and this depends on how your virtualenv/paths are set
'handlers': ['log_file'],
'level': 'INFO',
'propagate': True,
},
},
# you can also shortcut 'loggers' and just configure logging for EVERYTHING at once
'root': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO'
},
}
edytować
Zobacz wyjątki żądań są teraz zawsze rejestrowane, a numer biletu 16288 :
Zaktualizowałem powyższą przykładową konfigurację, aby wyraźnie uwzględnić poprawny filtr dla administratorów poczty, aby domyślnie wiadomości e-mail nie były wysyłane, gdy debugowanie ma wartość True.
Powinieneś dodać filtr:
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
i zastosuj go do programu obsługi mail_admins:
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
'include_html': True,
}
W przeciwnym razie django.core.handers.base.handle_uncaught_exceptionnie przekazuje błędów do programu rejestrującego „django.request”, jeśli settings.DEBUG ma wartość True.
Jeśli nie zrobisz tego w Django 1.5, otrzymasz plik
DeprecationWarning: nie masz żadnych filtrów zdefiniowanych w module obsługi logowania „mail_admins”: dodanie niejawnego filtru debug-false-only
ale to nadal będzie działać poprawnie ZARÓWNO w django 1.4 i django 1.5.
** koniec edycji **
To conf jest silnie inspirowane przykładowym conf w dokumencie django, ale dodaje część pliku dziennika.
Często też wykonuję następujące czynności:
LOG_LEVEL = 'DEBUG' if DEBUG else 'INFO'
...
'level': LOG_LEVEL
...
Następnie w moim kodzie Pythona zawsze dodaję NullHandler na wypadek, gdyby w ogóle nie została zdefiniowana konfiguracja logowania. Pozwala to uniknąć ostrzeżeń dla nieokreślonego programu obsługi. Szczególnie przydatne dla bibliotek, które niekoniecznie są wywoływane tylko w Django ( ref )
import logging
# Get an instance of a logger
logger = logging.getLogger(__name__)
class NullHandler(logging.Handler): #exists in python 3.1
def emit(self, record):
pass
nullhandler = logger.addHandler(NullHandler())
# here you can also add some local logger should you want: to stdout with streamhandler, or to a local file...
[…]
logger.warning('etc.etc.')
Mam nadzieję że to pomoże!