Integração com Django
Integre o ImmutableLog em qualquer aplicação Django com um middleware que captura automaticamente todas as requisições HTTP — erros, sucessos e avisos — sem alterar uma linha do seu código de negócio.
Instalação
O middleware não requer nenhuma dependência além do Django e da biblioteca `requests`, que provavelmente já está instalada no seu projeto. Copie o arquivo `middleware.py` para dentro do módulo de configuração da sua aplicação (ex: `api_core/middleware.py`) e instale a dependência se necessário.
pip install requestsCopie o arquivo middleware.py para o diretório do seu módulo de configuração (ex: api_core/middleware.py).
Configuração
Adicione as seguintes variáveis ao seu `settings.py`. As variáveis `IMTBL_API_KEY` e `IMTBL_URL` são obrigatórias — sem elas o middleware não enviará nenhum evento. As demais são opcionais e enriquecem os metadados registrados.
# settings.py
# Obrigatório / Required
IMTBL_API_KEY = "iml_live_xxxxxxxxxxxxxxxx" # sua chave de API / your API key
IMTBL_URL = "https://api.immutablelog.com" # URL base da API / API base URL
# Opcional / Optional
IMTBL_SERVICE_NAME = "meu-servico-django" # identifica o serviço / identifies the service
IMTBL_ENV = "production" # "production", "staging", "development"
IMTBL_HEADERS = {} # headers adicionais / extra headersNunca exponha o IMTBL_API_KEY em código cliente ou repositórios públicos. Use variáveis de ambiente no servidor e carregue-as via os.environ.get() ou ferramentas como django-environ.
import os
IMTBL_API_KEY = os.environ.get("IMTBL_API_KEY", "")
IMTBL_URL = os.environ.get("IMTBL_URL", "https://api.immutablelog.com")Registrar o Middleware
Adicione o middleware à lista `MIDDLEWARE` no seu `settings.py`. A ordem importa: coloque o `ImmutableLogAuditMiddleware` logo após os middlewares de segurança padrão do Django para garantir que todas as requisições sejam capturadas, incluindo as que geram exceções não tratadas.
# settings.py
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
# ImmutableLog — adicione após os middlewares padrão
# ImmutableLog — add after standard middlewares
"api_core.middleware.ImmutableLogAuditMiddleware",
]Como funciona
O middleware intercepta o ciclo de vida completo de cada requisição HTTP. Em `process_request`, registra o timestamp de início e gera um `request_id` único (ou reutiliza o header `X-Request-Id` se presente). Em `process_response`, calcula a latência e envia o evento ao ImmutableLog. Em `process_exception`, captura exceções não tratadas e envia um evento de erro com detalhes da exceção.
process_request
Registra timestamp de início e gera request_id único
process_response
Calcula latência, classifica o evento e envia ao ImmutableLog
process_exception
Captura exceções não tratadas e envia evento de erro com detalhes
O header X-Request-Id é retornado em todas as respostas, permitindo rastrear a requisição end-to-end entre sistemas.
Estrutura do Payload
Cada evento enviado ao ImmutableLog contém um payload rico e estruturado com contexto completo da requisição. O payload é serializado como string JSON (campo `payload`) e acompanhado de metadados de classificação (campo `meta`). O servidor calcula o hash SHA-256 sobre o payload exatamente como enviado.
{
"payload": "{\"id\":\"d6b6c2e5-0c1a-4b92-9a62-2f2c4c2e9a2a\",\"kind\":\"success\",\"message\":\"GET /api/users/ concluído com sucesso\",\"timestamp\":\"2026-02-21T14:32:11.000Z\",\"context\":{\"ip\":\"192.168.1.100\",\"user_agent\":\"Mozilla/5.0\",\"user_id\":42,\"email\":\"user@example.com\"},\"request\":{\"request_id\":\"8d0b5f06-6d1f-4d3c-9b4f-9f5a2d7b3c1a\",\"method\":\"GET\",\"path\":\"/api/users/\",\"query_params\":null},\"metrics\":{\"latency_ms\":38,\"status_code\":200},\"severity\":\"low\",\"success\":{\"status_code\":200,\"result\":\"ok\"}}",
"meta": {
"type": "success",
"event_name": "http.GET.api:user-list",
"service": "meu-servico-django",
"request_id": "8d0b5f06-6d1f-4d3c-9b4f-9f5a2d7b3c1a",
"env": "production"
}
}Limite: Limite de payload: 12KB por evento. Se o payload superar o limite, campos grandes (`error`, `request_body`) são removidos automaticamente. Em último caso, apenas campos essenciais (`id`, `kind`, `message`, `timestamp`) são mantidos.
Classificação de eventos
O middleware classifica automaticamente cada evento baseado no status HTTP da resposta ou na presença de uma exceção. Exceções não tratadas resultam em `error`. Status 2xx resultam em `success`. Status 3xx resultam em `info`. Status 4xx e 5xx resultam em `error`. Redirects e respostas informacionais resultam em `info`.
| Condição | Tipo (kind) | Severidade |
|---|---|---|
| Exceção não tratada | error | high |
| 4xx / 5xx | error | high |
| 3xx | info | low |
| 2xx | success | low |
Nomes de evento customizados
Por padrão, o middleware gera o nome do evento a partir do método HTTP e da rota nomeada do Django (ex: `http.GET.api:user-me`). Para sobrescrever esse nome em uma view específica, atribua `request.imtbl_event_name` antes do retorno da resposta. Isso permite rastreabilidade granular por evento de negócio.
from django.http import JsonResponse
def process_payment(request):
# Sobrescreve o nome do evento para este endpoint
# Override the event name for this endpoint
request.imtbl_event_name = "payment.processed"
# ... lógica de negócio / business logic ...
return JsonResponse({"status": "ok"})Se não definido, o middleware usa o padrão http.METHOD.view_name baseado no resolver de URL do Django.
Exclusão de health check
O middleware ignora automaticamente eventos com nome `http.GET.health-check`, evitando que chamadas de health check de load balancers e orquestradores poluam o ledger. Certifique-se de que sua rota de health check tenha o nome `health-check` no Django URL resolver.
# urls.py
from django.urls import path
from . import views
urlpatterns = [
# Nome "health-check" → ignorado automaticamente pelo middleware
# Name "health-check" → automatically ignored by the middleware
path("health/", views.health_check, name="health-check"),
path("api/users/", views.user_list, name="user-list"),
]Enriquecimento em erros
Em eventos de erro (`status >= 400` ou exceção), o middleware inclui detalhes adicionais: hash SHA-256 do body da requisição (para auditoria sem expor dados), body completo se menor que 2KB, nome e mensagem da exceção (se houver), e um flag `retryable` indicando se o erro é transitório (408, 429, 500, 502, 503, 504).
{
"payload": "{\"id\":\"a1b2c3d4-...\",\"kind\":\"error\",\"message\":\"POST /api/checkout/ falhou com exceção: ValueError\",\"context\":{\"ip\":\"10.0.0.1\",\"user_id\":7},\"request\":{\"method\":\"POST\",\"path\":\"/api/checkout/\"},\"metrics\":{\"latency_ms\":12,\"status_code\":500},\"severity\":\"high\",\"error\":{\"status_code\":500,\"retryable\":true,\"exception\":\"ValueError\",\"exception_message\":\"Invalid product SKU\",\"request_body_hash\":\"4f2b8e9a3c5d...\",\"request_body\":\"{\\"sku\\":\\"INVALID\\"}\"}}",
"meta": {
"type": "error",
"event_name": "http.POST.api:checkout",
"service": "meu-servico-django",
"env": "production"
}
}error.exception
Nome da classe da exceção
error.exception_message
Mensagem da exceção
error.request_body_hash
SHA-256 do body (sempre presente em erros)
error.retryable
True para: 408, 429, 500, 502, 503, 504
Esta documentação reflete o comportamento atual da integração. Para dúvidas ou integrações avançadas, entre em contato com o time de suporte.
