Jak logujesz błędy serwera w witrynach django


175

Tak więc, kiedy gra z rozwojem mogę po prostu ustawić settings.DEBUGsię Truei jeśli occures błędach widzę to ładnie sformatowany, z dobrym śladu stosu i informacji żądania.

Ale na czymś w rodzaju strony produkcyjnej wolałbym raczej użyć DEBUG=Falsei pokazać odwiedzającym jakąś standardową stronę błędu 500 z informacją, że pracuję nad naprawieniem tego błędu w tej chwili;)
Jednocześnie chciałbym mieć jakiś sposób na zalogowanie wszystkich te informacje (śledzenie stosu i informacje o żądaniach) do pliku na moim serwerze - więc mogę po prostu wyprowadzić je na moją konsolę i oglądać przewijanie błędów, e-mailem dziennik do mnie co godzinę lub coś w tym rodzaju.

Jakie rozwiązania do rejestrowania poleciłbyś dla witryny django, które spełniałyby te proste wymagania? Mam aplikację działającą jako fcgiserwer i używam serwera WWW Apache jako frontendu (chociaż myślę o przejściu na lighttpd).



2

Link, który udostępnił Cherian, jest teraz martwy. Jeśli spróbujesz wyszukać Sentry, prawdopodobnie znajdziesz materiały dotyczące ich płatnej, oficjalnej instancji, ale tutaj jest link do skonfigurowania instancji hostowanej na własnym serwerze: docs.sentry.io/server Ponadto, oto obecnie utrzymywane repozytorium: github .com / getsentry / sentry
— lehiester

Odpowiedzi:


103

Cóż, kiedy DEBUG = FalseDjango automatycznie wyśle ​​pełne śledzenie każdego błędu do każdej osoby wymienionej w ADMINSustawieniu, co dostaniesz powiadomienia prawie za darmo. Jeśli chcesz bardziej precyzyjnej kontroli, możesz napisać i dodać do swoich ustawień klasę oprogramowania pośredniego, która definiuje nazwaną metodę process_exception(), która będzie miała dostęp do zgłoszonego wyjątku:

http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception

Twoja process_exception()metoda może następnie wykonać dowolny typ logowania: zapis do konsoli, zapis do pliku itp., Itd.

Edycja: chociaż jest to trochę mniej przydatne, możesz również nasłuchiwać got_request_exceptionsygnału, który zostanie wysłany, gdy wystąpi wyjątek podczas przetwarzania żądania:

http://docs.djangoproject.com/en/dev/ref/signals/#got-request-exception

Ten sposób nie daje dostęp do obiektu wyjątku, jednak, więc metoda middleware jest znacznie łatwiej pracować.


7
Zauważ, że używanie logging.exception('Some message')ze standardowym modułem rejestrowania w Pythonie działa dobrze w programie obsługi sginal got_request_exception, jeśli wszystko, co chcesz zrobić, to wylogować ślady stosu. Innymi słowy, śledzenie jest nadal dostępne w got_request_exception.
— TM.

wyjątek przekazany do wyjątku_procesu nie wydaje się mieć śladu stosu, czy istnieje sposób, aby to uzyskać?
— Nick BL

79

Django Sentry to dobry sposób, jak już wspomniano, ale wymaga trochę pracy, aby go poprawnie skonfigurować (jako oddzielną stronę internetową). Jeśli chcesz tylko rejestrować wszystko w prostym pliku tekstowym, oto konfiguracja logowania, którą należy umieścić w plikusettings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/var/log/django/myapp.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'WARNING', # Or maybe INFO or DEBUG
            'propagate': False
        },
    },
}

Zgadzam się, kocham Sentry! Chcę mieć port .Net (ostatnio pracowałem nad projektami .Net).
— Gromer

1
Mała literówka na wypadek, gdyby ktoś wycinał i wklejał: na końcu „propaguj” zamiast „propaguj”.
— user1228295

3
'include_html': TrueNIE sprawia, że ​​e-maile są po prostu „milsze”! Zawiera pełne śledzenie, w tym wartości ustawień i zmiennych lokalnych. Zgodnie z dokumentacją jest to kwestia
— Thomas

1
Jestem ciekawy, czy program obsługi mail_admins (i rejestrator django.request) jest potrzebny, ponieważ masz opcję „disable_existing_loggers”: Fałsz i po prostu replikujesz domyślne logowanie django za pomocą tego modułu obsługi (i rejestratora). Zaktualizuję, kiedy przetestuję.
— DylanYoung

Zaktualizuj tę odpowiedź. Z django1.9 change-log: Domyślna konfiguracja logowania w Django nie definiuje już rejestratorów „django.request” i „django.security”.
— narendra-choudhary



15

Minęło trochę czasu od przesłania najbardziej pomocnego kodu przez EMP. Właśnie go zaimplementowałem i podczas miotania się z jakąś opcją manage.py, aby spróbować ścigać błąd, otrzymałem ostrzeżenie o wycofaniu, że w mojej obecnej wersji Django (1.5.?) Filtr require_debug_false jest teraz potrzebne dla programu obsługi mail_admins.

Oto poprawiony kod:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
         'require_debug_false': {
             '()': 'django.utils.log.RequireDebugFalse'
         }
     },
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
            'filters': ['require_debug_false'],
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/home/username/public_html/djangoprojectname/logfilename.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'DEBUG', # Or maybe INFO or WARNING
            'propagate': False
        },
    },
}

Jestem ciekawy, czy program obsługi mail_admins (i rejestrator django.request) jest potrzebny, ponieważ masz opcję „disable_existing_loggers”: Fałsz i po prostu replikujesz domyślne logowanie django za pomocą tego modułu obsługi (i rejestratora). Zaktualizuję, kiedy przetestuję.
— DylanYoung

1

Właśnie miałem irytujący problem z moim fcgiskryptem. Zdarzyło się to jeszcze zanim django się zaczęło. Brak logowania jest bardzo bolesny. W każdym razie, przekierowanie stderr do pliku jako pierwsza bardzo pomogło:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.