> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/pt-br/configuration/error-monitoring.md).

# Monitoramento de Erros (Sentry)

Integração opcional com Sentry para o frontend e o backend, incluindo o túnel à prova de bloqueadores de anúncios.

O MyIP vem com instrumentação opcional [Sentry](https://sentry.io/) nas duas metades do app. Ele é totalmente controlado por variáveis de ambiente.

{% hint style="success" %}
**Se você não definir nenhuma dessas variáveis, sua implantação se comporta exatamente como uma versão que nunca teve Sentry.** Nenhum código do Sentry é incluído no bundle do frontend, `@sentry/node` nunca é importado pelo backend, e a rota de túnel não é montada. Nada é enviado para lugar nenhum.
{% endhint %}

| Variável                   | Metade               | Quando é lido                                                       |
| -------------------------- | -------------------- | ------------------------------------------------------------------- |
| `VITE_SENTRY_DSN_FRONTEND` | Frontend + backend   | **Tempo de build** para o bundle, em tempo de execução para o túnel |
| `SENTRY_DSN_BACKEND`       | Backend              | Tempo de execução                                                   |
| `SENTRY_ENVIRONMENT`       | Backend              | Tempo de execução (e tempo de build, para source maps)              |
| `SENTRY_ORG`               | Ferramentas de build | Tempo de build                                                      |
| `SENTRY_PROJECT_FRONTEND`  | Ferramentas de build | Tempo de build                                                      |
| `SENTRY_AUTH_TOKEN`        | Ferramentas de build | Tempo de build                                                      |

As duas metades são independentes. Habilitar apenas o monitoramento do backend é uma configuração perfeitamente normal, e a mais simples para usuários do Docker.

## Como as peças se encaixam

```
Navegador (SPA Vue)
   │  erros, rastreamentos, replays
   ▼
POST /api/monitoring   ← túnel de primeira parte, mesma origem
   │  (o backend valida o DSN do envelope e então encaminha)
   ▼
Sentry  ◀── conexão direta ── backend Express (erros, traces, logs de aviso+)
```

## Backend — `SENTRY_DSN_BACKEND`

Defina o DSN e reinicie. Essa é toda a configuração.

{% code title=".env" %}

```bash
SENTRY_DSN_BACKEND="https://<key>@oNNNNN.ingest.sentry.io/<project-id>"
```

{% endcode %}

O que é ativado:

* **Erros não tratados e respostas 5xx** de qualquer `/api/*` rota, por meio do manipulador de erros do Express do Sentry.
* **Rastreamento de performance** com amostragem de 100% — latência, throughput e taxa de erro por rota.
* **Encaminhamento de logs.** O logger pino compartilhado espelha `warn` e acima em Sentry Logs; `erro JSON` e acima também se tornam um Issue agrupado e acionável por alerta. Então o `logger.error({ err }, '…')` chamadas em todo `api/` são sinais deliberados, e não apenas linhas de log. Veja [Logs](/developer/pt-br/configuration/logging.md).
* **Monitoramento de cron** para os jobs agendados do conjunto de dados (atualização automática do MaxMind, atualização do CAIDA, polling do status do serviço). Os monitores são criados no primeiro check-in — não há nada a pré-criar na interface do Sentry.

O SDK é inicializado por meio de `node --import ./sentry-instrument.js`, que registra hooks de carregamento antes de o Express ser carregado. O `dev`, `start`, e os comandos pm2 start já passam esse argumento, então não há nada a adicionar.

{% hint style="info" %}
A inicialização imprime `🛰️ Monitoramento de backend do Sentry ativado` quando o DSN foi detectado. Nenhuma linha significa que nenhum DSN foi visto.
{% endhint %}

## Frontend — `VITE_SENTRY_DSN_FRONTEND`

Esta é uma **de build** variável. O Vite a embute como uma constante, e a importação dinâmica do módulo do Sentry fica atrás dessa constante. Sem ela, a eliminação de código morto remove o ramo e o chunk do SDK nem chega a ser emitido.

```bash
VITE_SENTRY_DSN_FRONTEND="https://<key>@oNNNNN.ingest.sentry.io/<project-id>"
pnpm run build
```

O que é ativado:

* Exceções não tratadas e `console.error()` chamadas, agrupadas por mensagem.
* Rastreamento de performance em nível de rota com amostragem de 10%, com Web Vitals.
* Session Replay apenas para erros — nada é gravado a menos que um erro ocorra.

{% hint style="warning" %}
**O mesmo valor também precisa estar presente em tempo de execução.** O backend lê `VITE_SENTRY_DSN_FRONTEND` para decidir se deve montar `/api/monitoring` e para saber qual DSN ele tem permissão para encaminhar. Faça o build com ele, mas esqueça de passá-lo para o processo em execução, e o SDK do navegador faz POST para um `404`.
{% endhint %}

### Replay e privacidade

O texto da página é deliberadamente **não** mascarado nos replays: toda a interface deste app é a própria informação de rede do visitante, que é exatamente o contexto necessário para depurá-la. A entrada digitada continua mascarada. Na instância pública do IPCheck.ing isso é divulgado na política de privacidade — se você ativar o monitoramento do frontend para seus próprios usuários, divulgue também.

As duas metades rodam com `sendDefaultPii: false`, então os IPs e cabeçalhos dos visitantes não são anexados automaticamente pelos SDKs. Parâmetros de consulta que parecem credenciais (`chave`, `api_key`, `token`, `segredo`, `senha`, `auth`) são removidos dos breadcrumbs, spans e contextos de requisição antes de qualquer coisa ser enviada — URLs de upstream carregam suas chaves de API, e o Sentry registra URLs em vários lugares.

## A `/api/monitoring` túnel

Bloqueadores de anúncios e extensões de privacidade bloqueiam solicitações para `*.ingest.sentry.io`. Para um público de usuários familiarizados com redes, isso representa uma grande parcela dos visitantes, e apaga silenciosamente a maior parte dos seus dados de erro.

Então o SDK do navegador não fala diretamente com o Sentry. Ele faz POST de seus envelopes para `/api/monitoring` na sua própria origem, e o backend os encaminha.

Como a rota se comporta:

* **Montado somente quando `VITE_SENTRY_DSN_FRONTEND` está definido** em tempo de execução. Caso contrário, o caminho é um simples `404`.
* **Não é um relay aberto.** O cabeçalho do envelope carrega o DSN com o qual o SDK do navegador foi configurado. Se ele não corresponder exatamente a `VITE_SENTRY_DSN_FRONTEND`, a solicitação é rejeitada com `403`. Sem essa verificação, qualquer pessoa poderia usar seu servidor para enviar posts para contas arbitrárias do Sentry.
* **Seu próprio limite de taxa**: 600 solicitações por IP a cada 20 minutos, e ele é **isento do `/api` limitador**. A telemetria que compartilha a cota do app é assim que o envio de relatórios morre silenciosamente — um `429` e o SDK do navegador descarta cada evento no minuto seguinte.
* **Registro do IP do visitante**: quando um envelope sai do relay, o Sentry só vê o endereço do seu servidor. O backend grava o IP real do visitante (de `CF-Connecting-IP`, quando presente e válido) nos itens do evento antes de encaminhar.
* **As falhas são suaves**: um erro do relay responde `502` e registra um `warn`. Ele nunca quebra a página.

## `SENTRY_ENVIRONMENT`

Marca eventos do backend para que você possa filtrar produção de desenvolvimento na interface do Sentry.

* Não definido significa `produção`.
* Set `SENTRY_ENVIRONMENT="development"` em máquinas de desenvolvimento. Isso também desativa os check-ins de cron, então fechar o notebook não gera alertas de "perdido" para você.
* O frontend se marca automaticamente com base no modo de build do Vite — não há nada a configurar.

{% hint style="info" %}
"Por que não há dados no Sentry?" geralmente é o filtro de ambiente na interface do Sentry, e não uma configuração quebrada. Verifique isso antes de conferir sua configuração.
{% endhint %}

## Source maps — `SENTRY_ORG` / `SENTRY_PROJECT_FRONTEND` / `SENTRY_AUTH_TOKEN`

Sem source maps, as stack traces do frontend apontam para deslocamentos minificados do bundle. O build pode enviá-las ao Sentry para que os rastreamentos sejam resolvidos de volta aos arquivos-fonte reais.

{% code title=".env" %}

```bash
SENTRY_ORG="your-org-slug"
SENTRY_PROJECT_FRONTEND="your-frontend-project-slug"
SENTRY_AUTH_TOKEN="sntrys_..."
```

{% endcode %}

O upload só é executado quando **ambos** as condições são atendidas:

1. `SENTRY_AUTH_TOKEN` está definido, e
2. `SENTRY_ENVIRONMENT` é `produção` (ou não definido, o que significa produção).

Portanto, builds de desenvolvimento e teste não geram nem enviam maps.

{% hint style="danger" %}
`SENTRY_AUTH_TOKEN` é um segredo real e exclusivo do tempo de build. Ele nunca é embutido no bundle e nunca chega ao navegador. Mantenha-o fora da sua imagem, fora do seu repositório e restrito ao upload de source maps.
{% endhint %}

Os maps são gerados como hidden source maps, enviados e então excluídos de `dist/` — os visitantes não podem baixá-los.

## Docker

Monitorar o backend é fácil; monitorar o frontend não é, e vale a pena entender o motivo.

{% tabs %}
{% tab title="Somente backend (recomendado)" %}

```bash
docker run -d -p 18966:18966 \
  -e SENTRY_DSN_BACKEND="https://<key>@oNNNNN.ingest.sentry.io/<id>" \
  -e SENTRY_ENVIRONMENT="production" \
  --name myip \
  jason5ng32/myip:latest
```

Lido em tempo de execução. Funciona com a imagem pré-compilada oficial, sem necessidade de rebuild.
{% endtab %}

{% tab title="Frontend (precisa de um build personalizado)" %}
`VITE_SENTRY_DSN_FRONTEND` é consumida por `pnpm run build` **dentro de** da build da imagem. Passá-lo com `docker run -e` portanto não consegue colocar o Sentry em um bundle já construído.

A imagem oficial é construída sem nenhum DSN, então seu frontend é permanentemente livre de Sentry. Para habilitar o monitoramento do frontend, você precisa construir sua própria imagem e tornar o valor visível para a etapa de build — por exemplo, adicionando um `ARG` / `ENV` ao par no `Dockerfile` antes de `RUN pnpm run build`.

Depois, passe o mesmo DSN também em tempo de execução, para que a rota de túnel seja montada:

```bash
docker run -d -p 18966:18966 \
  -e VITE_SENTRY_DSN_FRONTEND="https://<key>@oNNNNN.ingest.sentry.io/<id>" \
  --name myip \
  your-image:latest
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
`.env` é excluído do contexto de build do Docker, então um simples `docker build` nunca pega um DSN dele por acidente.
{% endhint %}

## Verificando sua configuração

* **Backend**: procure `🛰️ Monitoramento de backend do Sentry ativado` no log de inicialização.
* **Túnel**: `POST /api/monitoring` não deve retornar `404`. Um `404` significa que o tempo de execução não vê `VITE_SENTRY_DSN_FRONTEND`.
* **Bundle do frontend**: se você construiu sem um DSN, nenhum chunk do Sentry existe em `dist/assets/` algum.
* **Nada chegando**: verifique o filtro de ambiente, o seletor de projeto e o intervalo de tempo na interface do Sentry, nessa ordem.

## Páginas relacionadas

* [Logs](/developer/pt-br/configuration/logging.md) — os níveis do pino que alimentam Sentry Logs e Issues
* [Opções de Segurança](/developer/pt-br/configuration/security-options.md) — por que o túnel é isento do limitador global
* [Variáveis de Ambiente](/developer/pt-br/reference/environment-variables.md) — a lista completa
* [Implantar com Docker](/developer/pt-br/getting-started/deploy-with-docker.md) — noções básicas de build e tempo de execução


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/pt-br/configuration/error-monitoring.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
