Журнал Django отказывается показывать полный трассировочный откат в сообщении файла
В настоящее время я настраиваю логирование в Django, следуя документу https://docs.djangoproject.com/en/2.2/topics/logging/ (я использую Django 2.2 с python3.7) и Django rest framework. Вот мой settings.py:
# LOGGING
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': '{levelname} {asctime} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'ERROR',
'class': 'logging.FileHandler',
'filename': '/var/log/django_errors.log',
'formatter': 'simple'
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'ERROR',
},
},
}
Вот мое представление с использованием django-rest-framework:
import logging
logger = logging.getLogger(__name__)
class Countries(APIView):
permission_classes = ()
authentication_classes = []
def get(self, request):
try:
... some API process
except Exception as e:
import traceback
print(traceback.format_exc())
logger.error(traceback.format_exc())
return JsonResponse({'code': 500, 'message': str(e)}, status=500)
В консоли я вижу, что print() показывает правильный откат всего стека. Но в файле регистрации он не показывает никакого отката.
django_errors.log:
ERROR 2022-12-22 11:35:21,051 "GET /api/countries HTTP/1.1" 500 72
ERROR 2022-12-22 11:35:21,065 "GET /api/countries HTTP/1.1" 500 72
Я также попробовал logger.exception()
происходит то же самое, файл не регистрирует полный откат стека
Я пытался искать решения в Интернете и пробовал их, но безрезультатно, надеюсь, кто-нибудь поможет мне выяснить причину
Ожидалось, что журнал будет показывать правильный трассировочный откат, например, как консольный print():
File "/app/api/views/countries.py", line 40, in get
country["currency"] = get_currency_code_from_country_code(country["data"])
File "/app/utils/django_utils.py", line 470, in get_currency_code_from_country_code
return currency.alpha_3
AttributeError: 'NoneType' object has no attribute 'alpha_3'
Я даже пытался добавить {stack_info} в мой форматер, но он просто возвращает None:
ERROR 2022-12-22 11:58:18,921 "GET /api/countries HTTP/1.1" 500 72 None
Я неправильно понял, как Django использует свою собственную именованную иерархию . Я думал, что использование django
будет применяться ко всем логгерам, но это не так, потому что Django по умолчанию записывает только информацию без трассировки стека.
Для того чтобы это работало, я снова заглянул в документацию, мне нужно указать имя родителя регистратора, чтобы он действительно был записан системой регистрации.
Итак, мне нужно, чтобы логгер выглядел так, чтобы перехватывать логгеры, указанные в каждом файле:
'loggers': {
'app1': { # need to specify app parent folder in loggers
'handlers': ['file', 'mail_admins'],
'level': 'ERROR',
},
'app2': {
'handlers': ['file', 'mail_admins'],
'level': 'ERROR',
},
'base.celery': {
'handlers': ['file', 'mail_admins'],
'level': 'ERROR',
},
},
и для того, чтобы логгер показывал трассировку стека, мне нужно использовать logger.exception("") это вызовет уровень ERROR с трассировкой стека
Теперь мои файлы журнала и электронная почта содержат всю информацию о трассировке стека