> 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/ru/configuration/error-monitoring.md).

# Мониторинг ошибок (Sentry)

MyIP поставляется с необязательным [Sentry](https://sentry.io/) инструментированием обеих половин приложения. Оно полностью управляется переменными окружения.

{% hint style="success" %}
**Если вы не зададите ни одну из этих переменных, ваше развертывание будет вести себя точно так же, как версия, в которой Sentry никогда не было.** В бандл фронтенда не входит никакой код Sentry, `@sentry/node` никогда не импортируется бэкендом, а маршрут туннеля не монтируется. Ничего никуда не отправляется.
{% endhint %}

| Переменная                 | Половина           | Когда читается                                                  |
| -------------------------- | ------------------ | --------------------------------------------------------------- |
| `VITE_SENTRY_DSN_FRONTEND` | Фронтенд + бэкенд  | **На этапе сборки** для бандла, во время выполнения для туннеля |
| `SENTRY_DSN_BACKEND`       | Backend            | Время выполнения                                                |
| `SENTRY_ENVIRONMENT`       | Backend            | Во время выполнения (и на этапе сборки — для карт исходников)   |
| `SENTRY_ORG`               | Инструменты сборки | На этапе сборки                                                 |
| `SENTRY_PROJECT_FRONTEND`  | Инструменты сборки | На этапе сборки                                                 |
| `SENTRY_AUTH_TOKEN`        | Инструменты сборки | На этапе сборки                                                 |

Две половины независимы. Включить только мониторинг бэкенда — совершенно нормальная схема, и самая простая для пользователей Docker.

## Как части сочетаются

```
Браузер (Vue SPA)
   │  ошибки, трассировки, записи сеансов
   ▼
POST /api/monitoring   ← туннель первой стороны, тот же origin
   │  (бэкенд проверяет DSN в envelope, затем пересылает)
   ▼
Sentry  ◀── прямое соединение ── бэкенд Express (ошибки, трассировки, логи warn+ )
```

## Бэкенд — `SENTRY_DSN_BACKEND`

Задайте DSN и перезапустите. Это вся настройка.

{% code title=".env" %}

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

{% endcode %}

Что включается:

* **Необработанные ошибки и ответы 5xx** с любого `/api/*` маршрута, через обработчик ошибок Sentry для Express.
* **Трассировка производительности** при 100% выборке — задержка, пропускная способность и частота ошибок по каждому маршруту.
* **Пересылка логов.** Общий логгер pino зеркалирует `warn` и выше в Sentry Logs; `ошибкой` и выше дополнительно становятся сгруппированным Issue с возможностью алерта. Так что `logger.error({ err }, '…')` вызовы по всему `api/` — это намеренные сигналы, а не просто строки логов. См. [Логирование](/developer/ru/configuration/logging.md).
* **Мониторинг cron** для запланированных заданий набора данных (автообновление MaxMind, обновление CAIDA, опрос статуса сервиса). Мониторы создаются при первом check-in — заранее ничего создавать в интерфейсе Sentry не нужно.

SDK инициализируется через `node --import ./sentry-instrument.js`, который регистрирует хуки загрузчика до того, как Express загружается. Команды `dev`, `запуска`, и pm2 start уже передают этот флаг, так что добавлять ничего не нужно.

{% hint style="info" %}
При запуске выводится `🛰️ Мониторинг backend в Sentry включён` когда DSN был подхвачен. Нет строки — значит, DSN не был замечен.
{% endhint %}

## Фронтенд — `VITE_SENTRY_DSN_FRONTEND`

Это **этапа сборки** переменная. Vite встраивает её как константу, а динамический импорт модуля Sentry находится за этой константой. Без неё устранение мёртвого кода удаляет ветку, и chunk SDK даже не будет создан.

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

Что включается:

* Необработанные исключения и `console.error()` вызовы, сгруппированные по сообщению.
* Трассировка производительности на уровне маршрута при 10% выборке, с Web Vitals.
* Session Replay только при ошибках — ничего не записывается, пока не произойдёт ошибка.

{% hint style="warning" %}
**Тот же самый value также должен присутствовать во время выполнения.** Бэкенд читает `VITE_SENTRY_DSN_FRONTEND` чтобы решить, монтировать ли `/api/monitoring` и чтобы знать, какой DSN ему разрешено ретранслировать. Соберите с ним, но забудьте передать его запущенному процессу, и браузерный SDK будет отправлять данные в `404`.
{% endhint %}

### Записи сеансов и конфиденциальность

Текст страницы намеренно **не** маскируется в записях сеансов: весь интерфейс этого приложения — это собственная сетевой информация посетителя, а это именно тот контекст, который нужен для отладки. Введённый текст остаётся скрытым. В публичном экземпляре IPCheck.ing это раскрыто в политике конфиденциальности — если вы включаете мониторинг фронтенда для своих пользователей, сообщите об этом тоже.

Обе половины работают с `sendDefaultPii: false`, поэтому IP посетителей и заголовки не прикрепляются SDK автоматически. Параметры запроса, похожие на учётные данные (`key`, `api_key`, `token`, `secret`, `password`, `auth`), удаляются из breadcrumbs, spans и контекстов запросов до того, как что-либо будет отправлено — исходящие URL содержат ваши API-ключи, а Sentry записывает URL в нескольких местах.

## Промежуточный слой `/api/monitoring` туннель

Блокировщики рекламы и расширения для конфиденциальности блокируют запросы к `*.ingest.sentry.io`. Для аудитории, хорошо знакомой с сетью, это большая доля посетителей, и это молча уничтожает большую часть данных об ошибках.

Поэтому браузерный SDK не общается с Sentry напрямую. Он POST-ит свои envelope в `/api/monitoring` на вашем собственном origin, а бэкенд их пересылает.

Как ведёт себя маршрут:

* **Монтируется только когда `VITE_SENTRY_DSN_FRONTEND` задано** во время выполнения. В противном случае путь — обычный `404`.
* **Не открытый ретранслятор.** Заголовок envelope содержит DSN, с которым был настроен браузерный SDK. Если он не совпадает точно с `VITE_SENTRY_DSN_FRONTEND`, запрос отклоняется с `403`. Без этой проверки любой мог бы использовать ваш сервер для отправки данных в произвольные учётные записи Sentry.
* **Собственный лимит скорости**: 600 запросов на IP за 20 минут, и он **не подпадает под глобальный `/api` ограничитель**. Телеметрия, использующая квоту приложения, — это то, как отчётность тихо умирает: один `429` и браузерный SDK сбрасывает все события в течение следующей минуты.
* **Подстановка IP посетителя**: как только envelope покидает ретранслятор, Sentry видит только адрес вашего сервера. Бэкенд записывает реальный IP посетителя (из `CF-Connecting-IP`, когда он присутствует и валиден) в элементы события перед пересылкой.
* **Сбои мягкие**: ошибка ретрансляции отвечает `502` и записывает `warn`. Это никогда не ломает страницу.

## `SENTRY_ENVIRONMENT`

Помечает события бэкенда, чтобы вы могли фильтровать production и development в интерфейсе Sentry.

* Не задано означает `production`.
* Set `SENTRY_ENVIRONMENT="development"` на машинах разработчика. Это также отключает cron check-ins, так что закрытие ноутбука не будет будить вас пропущенными оповещениями.
* Фронтенд автоматически помечает себя по режиму сборки Vite — ничего настраивать не нужно.

{% hint style="info" %}
«Почему в Sentry нет данных?» — чаще всего это фильтр окружения в интерфейсе Sentry, а не сломанная настройка. Проверьте его раньше, чем конфигурацию.
{% endhint %}

## Карты исходников — `SENTRY_ORG` / `SENTRY_PROJECT_FRONTEND` / `SENTRY_AUTH_TOKEN`

Без карт исходников стеки вызовов фронтенда указывают на смещения в минифицированном бандле. Сборка может загрузить их в Sentry, чтобы трассировки разрешались в реальные исходные файлы.

{% code title=".env" %}

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

{% endcode %}

Загрузка выполняется только когда **оба** выполняются условия:

1. `SENTRY_AUTH_TOKEN` задана, и
2. `SENTRY_ENVIRONMENT` является `production` (или не задана, что означает production).

Поэтому dev- и test-сборки ни не генерируют, ни не загружают карты.

{% hint style="danger" %}
`SENTRY_AUTH_TOKEN` — это настоящий секрет и только для этапа сборки. Он никогда не встраивается в бандл и никогда не попадает в браузер. Держите его вне образа, вне репозитория и ограничьте его областью использования только для загрузки карт исходников.
{% endhint %}

Карты генерируются как скрытые карты исходников, загружаются, а затем удаляются из `dist/` — посетители не смогут их скачать.

## Docker

Мониторинг бэкенда прост; мониторинг фронтенда — нет, и стоит понять почему.

{% tabs %}
{% tab title="Только бэкенд (рекомендуется)" %}

```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
```

Читается во время выполнения. Работает с официальным готовым образом, без пересборки.
{% endtab %}

{% tab title="Фронтенд (требует собственной сборки)" %}
`VITE_SENTRY_DSN_FRONTEND` используется `pnpm run build` **внутри** сборки образа. Передача его через `docker run -e` поэтому не может встроить Sentry в уже собранный бандл.

Официальный образ собирается без какого-либо DSN, поэтому его фронтенд навсегда остаётся без Sentry. Чтобы включить мониторинг фронтенда, вы должны собрать свой собственный образ и сделать значение видимым для стадии сборки — например, добавив `ARG` / `ENV` пару в `Dockerfile` до `RUN pnpm run build`.

Затем передайте тот же DSN и во время выполнения, чтобы маршрут туннеля смонтировался:

```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` исключён из контекста сборки Docker, поэтому обычный `docker build` никогда не подхватывает из него DSN случайно.
{% endhint %}

## Проверка вашей настройки

* **Backend**: ищите `🛰️ Мониторинг backend в Sentry включён` в журнале запуска.
* **Туннель**: `POST /api/monitoring` не должен возвращать `404`. A `404` означает, что во время выполнения не видно `VITE_SENTRY_DSN_FRONTEND`.
* **Сборка фронтенда**: если вы собрали без DSN, в `dist/assets/` какого-либо.
* **Ничего не приходит**: проверьте фильтр окружения, селектор проекта и диапазон времени в интерфейсе Sentry, именно в таком порядке.

## Связанные страницы

* [Логирование](/developer/ru/configuration/logging.md) — уровни pino, которые питают Sentry Logs и Issues
* [Параметры безопасности](/developer/ru/configuration/security-options.md) — почему туннель освобождён от глобального ограничителя
* [Переменные окружения](/developer/ru/reference/environment-variables.md) — полный список
* [Развертывание с Docker](/developer/ru/getting-started/deploy-with-docker.md) — основы сборки и времени выполнения


---

# 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/ru/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.
