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.
Metadata
Release files for hub-error-logs-sdk 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hub_error_logs_sdk-0.1.3.tar.gz | 27.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hub_error_logs_sdk-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.5 kB
Release files / hub_error_logs_sdk-0.1.3.tar.gz
| Download URL | hub_error_logs_sdk-0.1.3.tar.gz |
|---|---|
| Size | 27.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f19580746f16e03731f404822cc57f4798947592822d0ed5f98d8fb7a97ba34f
|
|
BLAKE2b-256 checksum How to use checksums |
d960d3a959ee7533b0fc1010437873a43c30b2dc38398321e14ebedb52957d25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / hub_error_logs_sdk-0.1.3-py3-none-any.whl
| Download URL | hub_error_logs_sdk-0.1.3-py3-none-any.whl |
|---|---|
| Size | 22.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d6483cfbb8b368612fb81b4a152f987c5dd25e080b6a208e0c3ca8b7e0ec6802
|
|
BLAKE2b-256 checksum How to use checksums |
17fd99119ef9376e3db26fb7d776e90efc55484bad7065673ee03c7ad585a8ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|