hub-error-logs-sdk
SDK Python para uma plataforma Django passar a enviar seus erros para a
Caixa de Logs do Mupi Hub (o inbox de erros estilo Sentry do mupihub),
com esforço quase zero — sem escrever view, middleware ou LOGGING à mão.
Depois de instalar e configurar a chave, erros não tratados (HTTP 500),
DisallowedHost e qualquer logger.error/logger.exception passam a fluir
automaticamente para um inbox central — com stacktrace e contexto de request
estruturado (método, rota, headers e query sanitizados, status, usuário) —
facilitando o debug.
Pacote de import:
hublogs· Distribuição (pip):hub-error-logs-sdk
Instalação
Via GitHub (recomendado por enquanto):
pip install hub-error-logs-sdk
Para atualizar (forçando o pip a baixar o commit novo, sem cache):
pip install --force-reinstall --no-cache-dir --no-deps \
hub-error-logs-sdk
Após atualizar, reinicie o servidor (
runserver/gunicorn). Opip installnão recarrega um processo que já está rodando.
Uso — setup de 2 passos
1. Gere um token de serviço (uma vez por plataforma)
No mupihub, logado como admin → Tokens da API → gere um token (user=None,
escopo de serviço). O token aparece uma única vez (mhb_...). Guarde como
segredo, ex. numa variável de ambiente. Nunca comite o token.
2. Configure o settings.py
import os
INSTALLED_APPS += ["hublogs"]
MUPIHUB_LOGS = {
"token": "mhb_...", # mhb_...
"source": "eagenda", # slug curto da plataforma
"environment": "", #producao/homolog
}
Pronto. No boot, o SDK liga sozinho:
- o handler de logging (no root logger e, quando necessário, direto em
django.request/django.security); - o middleware de contexto de request (
hublogs.middleware.RequestContext, injetado emsettings.MIDDLEWARE).
Testando
python manage.py shell -c "
import logging
try:
1/0
except ZeroDivisionError:
logging.getLogger('django.request').error('teste de integração', exc_info=True)
"
O erro deve aparecer no inbox em segundos. Repetir o mesmo erro não cria itens novos — incrementa o contador do grupo (dedup por fingerprint, feito no servidor).
Ambientes (dev × prod)
O endpoint é escolhido automaticamente pelo settings.DEBUG da plataforma:
settings.DEBUG |
Destino dos logs |
|---|---|
True |
mupihub local: http://127.0.0.1:8080/moop/api/v1/logs |
False |
produção: https://dev.mupisystems.com.br/moop/api/v1/logs |
- Um
endpointdefinido explicitamente (emMUPIHUB_LOGS["endpoint"]ou na envMUPIHUB_LOG_ENDPOINT) sempre prevalece, ignorando oDEBUG. - O destino de debug é ajustável via
MUPIHUB_LOGS["debug_endpoint"](ouMUPIHUB_LOG_DEBUG_ENDPOINT), caso seu mupihub local rode em outra porta.
Com
DEBUG=True, confira o inbox local (http://127.0.0.1:8080/moop/logs/), não o de produção. Os grupos aparecem na org dona do token.
Privacidade e dados sensíveis
Logar é "best-effort", mas vazar segredo/PII nunca. O que o SDK faz por padrão:
✅ Redigido automaticamente (vira [Filtered]), por nome de chave, em headers,
query string, extra e tags — em inglês e PT-BR:
password/senha, authorization, cookie, token/access_token/refresh_token,
api_key, secret, csrf, sessionid, private_key, credit_card/cartao/cvv,
cpf, cnpj, telefone, ssn. (Lista ajustável em scrub_fields.)
✅ PII do usuário desligada por padrão (send_default_pii=False): só o
user.id é enviado. Email, username e IP só vão se você ativar
send_default_pii=True.
✅ Nunca capturado: corpo do request (body), dados de formulário/POST, valor
do cookie (o header Cookie é redigido), e variáveis locais do stacktrace
(o stacktrace é só os frames, sem valores de variáveis).
⚠️ Atenção — não é sanitizado: o texto da mensagem (message), o valor
da exceção (exception.value) e a rota (path — ex.: /reset/<token>/)
são texto livre e não passam pelo scrub (só a query string é redigida por
chave). Não coloque segredos/PII em mensagens de erro nem em segmentos de URL
(ex.: evite logger.error(f"senha inválida: {senha}")). Isso vale para qualquer
ferramenta de error tracking.
Personalizar
MUPIHUB_LOGS = {
"token": os.environ["MUPIHUB_LOG_TOKEN"],
"source": "eagenda",
# adiciona termos à lista padrão de redação (substring, case-insensitive)
"scrub_fields": ("password", "senha", "token", "cpf", "cnpj", "rg_numero", "pin"),
# ative só se realmente precisar de email/username/IP do usuário no inbox
"send_default_pii": False,
}
scrub_fieldssubstitui a lista padrão — inclua os termos padrão que quiser manter. Casamento é por substring no nome da chave (normalizado), então prefira termos específicos (cpf,senha) a curtos demais (rgcasaria "organization").
Captura manual (opcional)
Além da captura automática, há uma API explícita:
import hublogs
hublogs.set_user({"id": 7}) # contexto do request atual
hublogs.set_tag("feature", "checkout")
hublogs.add_context("order_id", 1042)
try:
processa()
except Exception:
hublogs.capture_exception() # envia a exceção atual + stacktrace
hublogs.capture_message("algo estranho", level="warning")
hublogs.flush(timeout=5) # força o envio do que está na fila
Configuração
MUPIHUB_LOGS (dict no settings.py). Token e alguns campos também aceitam
variável de ambiente (a env preenche quando o campo não está no dict).
| Chave | Default | Env | Descrição |
|---|---|---|---|
token |
— (obrigatório) | MUPIHUB_LOG_TOKEN |
Token de serviço (mhb_...). |
source |
— (obrigatório) | MUPIHUB_LOG_SOURCE |
Slug curto da plataforma. |
environment |
"" |
MUPIHUB_LOG_ENVIRONMENT / ENV |
Ex.: production, staging. |
release |
"" |
MUPIHUB_LOG_RELEASE / RELEASE |
Versão/commit. |
endpoint |
auto (prod) | MUPIHUB_LOG_ENDPOINT |
Sobrepõe o DEBUG. |
debug_endpoint |
http://127.0.0.1:8080/moop/api/v1/logs |
MUPIHUB_LOG_DEBUG_ENDPOINT |
Usado quando DEBUG=True. |
level |
ERROR |
— | Nível mínimo capturado. |
send_default_pii |
False |
— | Inclui email/username/IP do usuário. |
scrub_fields |
lista padrão | — | Termos sensíveis a redigir. |
capture_loggers |
("django.request", "django.security") |
— | Loggers anexados direto quando não propagam ao root. |
auto_middleware |
True |
— | Injeta o RequestContext no MIDDLEWARE. |
verify_token |
True |
— | Ping em /auth/me/ no boot (avisa token inválido). |
enabled |
True |
— | Desliga o SDK quando False. |
batch_size |
50 |
— | Eventos por requisição (cap do servidor: 200). |
flush_interval |
2.0 |
— | Segundos entre flushes da fila. |
max_queue |
1000 |
— | Tamanho da fila em memória (descarta quando cheia). |
timeout |
5.0 |
— | Timeout de rede (s). |
Garantias de robustez
- Nunca derruba nem bloqueia o app host. Envio é em lote, numa thread daemon; fila cheia → descarta; erro de rede → engole (sem retry-storm).
- Funciona com
LOGGINGcustomizado. Mesmo que o projeto tenhadjango.request/django.securitycompropagate=False, o handler é anexado direto neles. E o SDK se re-anexa caso o Django reconfigure o logging (ex.: orunserver), então a captura não "some". - Respeita os limites do servidor: ≤ 200 eventos e ≤ 64 KB por requisição
(eventos grandes são truncados); back-off em
429. - Dedup é no servidor: o SDK só encaminha; você pode mandar um
fingerprintpróprio viacapture_*.
Troubleshooting
| Sintoma | Causa provável / solução |
|---|---|
| Nada chega no inbox | Confira a versão instalada: python -c "import hublogs; print(hublogs.__version__)". Atualize com --force-reinstall --no-cache-dir e reinicie o servidor. |
Chega no shell mas não no runserver |
Servidor rodando código antigo em memória → reinicie o runserver. |
202 ok:true mas não aparece |
Você está no inbox errado (prod × local) ou em outra organização. Com DEBUG=True, veja o :8080, na org do token. |
| Grupos não aparecem na aba "Aberto" | Podem estar Ignorados — troque o filtro de status. |
| Token rejeitado (boot loga aviso) | Token ausente/errado/revogado — gere outro em Tokens da API. |
Desenvolvimento
Python 3.12, Django 4.2 (alvo das plataformas), em .venv/.
source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest -q
Contrato de ingestão e arquitetura: veja .claude/CLAUDE.md e
.claude/INTEGRACAO_PLATAFORMAS_LOGS.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hub_error_logs_sdk-0.1.3.tar.gz.
File metadata
- Download URL: hub_error_logs_sdk-0.1.3.tar.gz
- Upload date:
- Size: 27.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f19580746f16e03731f404822cc57f4798947592822d0ed5f98d8fb7a97ba34f
|
|
| MD5 |
8988f2a3fb85ae9e9e389588dc90fd60
|
|
| BLAKE2b-256 |
d960d3a959ee7533b0fc1010437873a43c30b2dc38398321e14ebedb52957d25
|
File details
Details for the file hub_error_logs_sdk-0.1.3-py3-none-any.whl.
File metadata
- Download URL: hub_error_logs_sdk-0.1.3-py3-none-any.whl
- Upload date:
- Size: 22.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6483cfbb8b368612fb81b4a152f987c5dd25e080b6a208e0c3ca8b7e0ec6802
|
|
| MD5 |
5845ac67686b6c2f120cd3b81a27cfb3
|
|
| BLAKE2b-256 |
17fd99119ef9376e3db26fb7d776e90efc55484bad7065673ee03c7ad585a8ff
|