Logging de Requisições e Respostas HTTP no Django com Django Rest Framework
Table of contents
O logging é um aspecto essencial de qualquer aplicação web, pois permite que os desenvolvedores rastreiem erros e depurem problemas que surgem durante o desenvolvimento e a produção. No Django, você pode usar a estrutura de logging integrada para registrar mensagens em vários destinos, como o console, arquivos ou email. No entanto, para registrar requisições e respostas HTTP, pode ser necessário criar um logger personalizado que capture essas informações.
Neste artigo, mostraremos como criar um logger personalizado no Django usando a classe LoggingMixin
, e como configurar o logger usando o arquivo de configurações do Django.
Usando a Classe LoggingMixin
A classe LoggingMixin
é um mixin reutilizável que você pode adicionar às suas views do Django para registrar requisições e respostas HTTP. A classe define dois métodos: initial()
e finalize_response()
. O método initial()
é chamado antes da view ser executada, e o método finalize_response()
é chamado depois que a view retorna uma resposta.
Aqui está um exemplo de implementação da classe LoggingMixin
:
import logging
class LoggingMixin:
"""
Fornece logging completo de requisições e respostas
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.logger = logging.getLogger('django.request')
def initial(self, request, *args, **kwargs):
try:
self.logger.debug({
"request": request.data,
"method": request.method,
"endpoint": request.path,
"user": request.user.username,
"ip_address": request.META.get('REMOTE_ADDR'),
"user_agent": request.META.get('HTTP_USER_AGENT')
})
except Exception:
self.logger.exception("Erro ao registrar dados da requisição")
super().initial(request, *args, **kwargs)
def finalize_response(self, request, response, *args, **kwargs):
try:
self.logger.debug({
"response": response.data,
"status_code": response.status_code,
"user": request.user.username,
"ip_address": request.META.get('REMOTE_ADDR'),
"user_agent": request.META.get('HTTP_USER_AGENT')
})
except Exception:
self.logger.exception("Erro ao registrar dados da resposta")
return super().finalize_response(request, response, *args, **kwargs)
eption:
self.logger.exception("Erro ao registrar dados da requisição")
super().initial(request, *args, **kwargs)
def finalize_response(self, request, response, *args, **kwargs):
try:
self.logger.debug({
"response": response.data,
"status_code": response.status_code,
"user": request.user.username,
"ip_address": request.META.get('REMOTE_ADDR'),
"user_agent": request.META.get('HTTP_USER_AGENT')
})
except Exception:
self.logger.exception("Erro ao registrar dados da resposta")
return super().finalize_response(request, response, *args, **kwargs)
A classe LoggingMixin
registra os dados da requisição e da resposta usando o método logger.debug()
, que escreve as mensagens de log no nível DEBUG do logger. As mensagens de log incluem informações como o método da requisição, endpoint, usuário, endereço IP, agente de usuário, código de status da resposta e dados da resposta.
Para usar a classe LoggingMixin
nas suas views do Django, você pode simplesmente adicioná-la como um mixin à sua classe de view, como neste exemplo:
from django.http import JsonResponse
from django.views import View
from .mixins import LoggingMixin
class MyView(LoggingMixin, View):
def get(self, request):
return JsonResponse({'message': 'Hello, world!'})
Configurando o Logger
Por padrão, o logger definido na classe MyView
escreve as mensagens de log no console. No entanto, você pode querer configurar o logger para escrever as mensagens de log em um arquivo, enviar por email ou outro destino. Para isso, você pode configurar o logger no arquivo de configurações do Django usando o dicionário LOGGING
.
Aqui está um exemplo de como configurar o logger para escrever as mensagens de log em um arquivo:
# settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/request.log',
'maxBytes': 10485760, # 10 MB
'backupCount': 5,
'encoding': 'utf-8',
'formatter': 'verbose'
},
},
'formatters': {
'verbose': {
'format': '%(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)',
},
},
'loggers': {
'django.request': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
Neste exemplo, declaramos a configuração do logger no dicionário LOGGING
, que pode ser colocado no arquivo de configurações do Django. Definimos um RotatingFileHandler
, que é responsável por gravar os logs em um arquivo, com detalhes como tamanho máximo do arquivo, número de backups e formato das mensagens.
Conclusão
Em conclusão, o logging é uma parte essencial de qualquer aplicação web, e registrar requisições e respostas HTTP pode ser particularmente útil para rastrear e depurar problemas que surgem durante o desenvolvimento e a produção. Criando um logger personalizado no Django usando o Django Rest Framework, você pode facilmente capturar e registrar requisições e respostas HTTP em um formato estruturado que é fácil de ler e analisar.
Usando a classe APIView
no Django Rest Framework, podemos definir métodos personalizados que manipulam requisições e respostas HTTP, e configurando o logger usando o arquivo de configurações do Django, podemos controlar onde as mensagens de log são escritas e como elas são formatadas. Seguindo as melhores práticas de logging, como definir níveis de log e usar arquivos de log rotativos, podemos garantir que nossas mensagens de log sejam eficientes, seguras e fáceis de manter.