Как мы можем сохранить все журналы в базе данных с некоторыми дополнительными колонками? (django)
Я работаю над проектом Django, в котором мне нужно сохранять все логи (не только логи error
), например, когда пользователь нажимает на вкладку или даже кнопку, я должен сохранить ее лог. И я хочу сохранить их в моей базе данных (или лучше в отдельной базе данных), потому что мне нужно проанализировать логи и извлечь из них некоторую информацию.
Я видел несколько сообщений в StackOverflow, но они были не очень полезны для меня. В этом сообщении были даны некоторые ответы, и я попробовал django-db-logger
пакет в третьем ответе.
Я добавил следующий код в settings.py
на основе файла README этого проекта:
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 %(asctime)s %(message)s'
},
},
'handlers': {
'db_log': {
'level': 'DEBUG',
'class': 'django_db_logger.db_log_handler.DatabaseLogHandler'
},
},
'loggers': {
'db': {
'handlers': ['db_log'],
'level': 'DEBUG'
},
'django.request': { # logging 500 errors to database
'handlers': ['db_log'],
'level': 'ERROR',
'propagate': False,
}
}
}
Я добавил несколько логов в один из моих API
в следующем коде:
import logging
db_logger = logging.getLogger('db')
# _____________ user Management ______________
@api_view(['POST'])
def user(request):
db_logger.info("In signup API")
if request.method == "POST":
body = json.loads(request.body.decode('utf-8'))
body['password'] = hash_sha256(body['password'])
duplicate = Profile.objects.filter(username=body['username'])
if len(duplicate) != 0:
db_logger.critical("The username is duplicate")
return Response({"message": "نام کاربری تکراری است."}, status=status.HTTP_409_CONFLICT)
instance = Profile.objects.create(**body)
db_logger.info(f'User with {instance.username} created successfully')
return Response({"username": body['username']})
После выполнения программы в моей базе данных (я использую MySQL workbench 8.0) была создана новая таблица, но она содержит только эти столбцы (которые были предоставлены в LOGGING
):
Но мне нужно сохранить некоторую дополнительную информацию, такую как имя пользователя каждого пользователя, который вызывает журнал, и даже URL страницы. Есть ли способ добавить некоторые параметры к объекту logger
и затем сохранить их в базе данных?
Если существует какой-либо другой способ сохранения такого рода информации, я буду благодарен за помощь. Я понятия не имею, как решить эту проблему.
Для этого существуют некоторые опции в Django
:
Обработчик - это механизм, который определяет, что происходит с каждым сообщением в регистраторе. Он описывает определенное поведение регистратора, такое как запись сообщения на экран, в файл или в сетевой сокет.
Возможно, ты сможешь найти сюда дорогу!
'handlers': {
'console': {
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
'filters': ['special']
}
},
'loggers': {
'django': {
'handlers': ['console'],
'propagate': True,
},
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': False,
},
'myproject.custom': {
'handlers': ['console', 'mail_admins'],
'level': 'INFO',
'filters': ['special']
}
}
Я нашел 2 ответа на свой вопрос.
1) Настройка пакета django-db-logger
Я думаю, что в этом учебнике youtube tutorial все было объяснено ясно. Но основная идея заключается в том, чтобы модифицировать пакет django-db-logger
после его установки в наш проект.
2) Написать API и вызывать его во всех HTML файлах
Единственная проблема с первым решением заключается в том, что в некоторых случаях мы не можем записать все действия, совершенные пользователем, и некоторые действия обрабатываются на стороне пользовательского интерфейса. Поэтому мы можем написать API, а затем вызывать его на каждом компоненте и HTML-странице. Например, когда пользователь переходит от одной панели к другой, я не смог записать журнал, используя первый подход.