Traffic Inspector
Описание
Общее описание функционала
Инспектор HTTP-трафика сохраняет события HTTP/HTTPS-запросов, прошедших через туннель: метод, путь, код ответа, длительность и доступные по правилам захвата заголовки и тело. Владелец туннеля просматривает журнал в дашборде, открывает отдельное событие и при необходимости повторяет запрос с безопасными ограничениями на путь и заголовки.
Для события также определяется IP клиента. Заголовки переадресации учитываются только тогда, когда запрос пришёл через настроенный доверенный промежуточный сервер. В остальных случаях Инспектор показывает адрес прямого соединения. Чтобы адрес не повторялся на каждом небольшом экране, мобильные карточки и компактный список его не показывают. На широком экране он доступен в подробном списке, а у выбранного события — отдельной строкой IP клиента.
Как пользователь может использовать
- Разработчик отлаживает API: находит неудачный запрос в списке, открывает детали и сравнивает его с ответом бэкенда.
- Специалист поддержки открывает выбранное событие и сверяет IP клиента с ожидаемым источником запроса.
- Разработчик включает подробный вид на широком экране и сравнивает IP нескольких событий в одном списке.
- Пользователь работает с журналом на телефоне или в компактном режиме без повторения IP в каждой карточке или строке.
- Пользователь фильтрует события по туннелю, времени и пагинации, чтобы не загружать весь журнал.
- Пользователь подписывается на поток событий (SSE) для живого просмотра во время ручного теста.
- Пользователь запускает повтор запроса события в режиме «через облако» или «локально» с допустимыми правками тела/метода в рамках ограничений сервера.
- Администратор при поддержке просматривает те же события в рамках полномочий.
Как это реализовано в сервисе
Когда запрос проходит через публичный адрес туннеля, сервис определяет адрес клиента, проверяет правила доверия к промежуточному серверу и сохраняет событие Инспектора. Если адрес клиента передал доверенный посредник, порт соединения посредника не приписывается клиенту. Если доверенного посредника нет или заголовок содержит некорректный адрес, используется адрес прямого соединения.
Список и карточки получают те же данные события, но показывают их с разной плотностью. Подробный вид подходит для сравнения, а выбранное событие содержит одну основную строку IP клиента. Сохранённые заголовки переадресации остаются в разделе заголовков запроса и не подменяют эту строку. Доступ к списку и деталям проверяется по учётной записи и туннелю. Перед повтором запроса сервис отдельно проверяет допустимые изменения пути, заголовков и тела.
Справочник API
Список событий
GET /api/v1/inspector/events
Параметры (имена уточняйте по ответу сервера): tunnel_id, фильтры времени, пагинация limit / offset или курсор.
Ответ: JSON со списком событий и метаданными пагинации.
IP клиента
source_ip— определённый сервисом IP клиента. Имя поля сохраняется для новых и ранее записанных событий.source_port— порт прямого соединения, если он был корректно определён. Для адреса, полученного от доверенного промежуточного сервера, поле отсутствует или равноnull: порт такого соединения принадлежит посреднику, а не клиенту.- Заголовки
X-Forwarded-ForиX-Real-IP, если они попали в захват, остаются отдельными элементами списка заголовков запроса. Они не заменяютsource_ipи сами по себе не означают, что сервис им доверял.
Фильтр по IP клиента в дополнении «Расширенный журнал инспектора» продолжает передавать параметр source_ip.
Одно событие
GET /api/v1/inspector/events/{id}
id должен быть URL-encoded в клиенте.
Поток SSE
GET /api/v1/inspector/events/stream?tunnel_id=...
Подписка на новые события; tunnel_id в query также передавать в закодированном виде при необходимости.
Повтор запроса
POST /api/v1/inspector/events/{eventId}/replay
Тело JSON: { "mode": "cloud" | "local", "overrides": { ... опционально } }.
cloud— повтор выполняется на сервере Fortunnels и уходит через публичный edge туннеля (как внешний клиент). Подходит для проверки маршрута end-to-end наfortunnels.ru.local— повтор отправляется непосредственно в настроенную цель туннеля без нового внешнего обращения к публичному адресу.
Поля overrides (правки метода, пути, заголовков и тела) ограничены сервером: нельзя подставить абсолютный URL в path, запрещённые заголовки и слишком большое тело (лимит порядка десятков килобайт).
Ошибки
401 Unauthorized
Нет сессии или токена для инспектора (в боевом режиме).
403 Forbidden
Нет доступа к туннелю события.
400 Bad Request
Некорректные параметры списка или недопустимые правки запроса при повторе (путь, заголовки, размер тела).
404 Not Found
Событие не найдено или недоступно.
503 Service Unavailable
Инспектор отключён или хранилище недоступно.
Ограничения
- Захват может не включать полное тело запроса/ответа или маскировать чувствительные поля по политике сервера.
- Повтор запроса не гарантирует идентичный побочный эффект на бэкенде; использовать только на тестовых стендах с осторожностью.
- Большие журналы требуют фильтрации по времени и туннелю.
- В dev-режиме сервера правила аутентификации к инспектору могут быть слабее, чем в продакшене.
Дополнения
Inspector export and retention
Общее описание функционала
Дополнение «Экспорт и хранение инспектора» расширяет инспектор HTTP-трафика: пользователь на подходящем тарифе задаёт срок хранения событий (от нескольких дней до года), видит ориентировочную дату автоудаления и экспортирует записи в JSON, как сырую HTTP-транскрипцию или как команду cURL. Без дополнения журнал событий хранится 3 дня; экспорт и настройка срока недоступны. Очистка журнала или удаление одного события убирает только данные инспектора — публичный URL туннеля и приём нового трафика не затрагиваются. Настройки полного захвата тел и лимита размера тела связаны с дополнением «Захват тел запросов» и отображаются в той же панели на странице инспектора.
Как пользователь может использовать
- Разработчик на тарифе с дополнением открывает инспектор туннеля (
/dashboard/tunnels/{tunnelId}/inspector), в панели Хранение и экспорт видит текущий срок хранения, лимит тарифа (до 365 дней) и строку Ориентировочная дата автоудаления, задаёт новый срок (например, 30 дней) и нажимает Сохранить. - Пользователь сравнивает значения в панели — срок в днях, лимит тарифа и Ориентировочную дату автоудаления — с полями
retention_days,plan_retention_days_maxиnext_auto_deletion_atизGET /api/v1/inspector/settingsперед аудитом или отчётом. - После Очистить все пользователь убеждается, что публичный URL туннеля остаётся прежним и новый трафик снова появляется в журнале.
- Интегратор выгружает одно событие через Export JSON в деталях или запросом
GET …/export?format=jsonдля архива или тикета. - Пользователь копирует Copy cURL (или скачивает
format=curl) и вставляет команду в терминал: публичныйhttpsURL, заголовки и тело подставляются автоматически; аргументы с символами оболочки (;,|,$()и т.п.) экранируются одинарными кавычками для безопасной вставки. - Специалист поддержки получает raw HTTP транскрипт одного события (
format=raw) для обмена с внешней системой. - Аналитик отправляет POST массовый экспорт JSON с массивом
event_ids(от 1 до 50 id): ответ всегда JSON-массив объектов событий, даже если передан один id. - Пользователь без дополнения видит фиксированные 3 дня хранения; поле срока в панели недоступно, кнопки копирования и экспорта в деталях скрыты или недоступны по тарифу.
- Владелец туннеля нажимает Очистить все, в диалоге подтверждения читает, что публичный URL туннеля останется активным, подтверждает удаление только записей инспектора и проверяет, что новый трафик снова появляется в журнале.
- При удалении одного события пользователь подтверждает, что URL туннеля не изменится.
- В списке событий пользователь видит значки truncated (обрезано) и no body (тело не сохранено) и в деталях — пояснение Тело не захвачено (только метаданные) для режима только метаданных.
- Пользователь с низким лимитом тела проверяет частичное сохранение и значок Обрезано в деталях запроса.
- Администратор с правами экспорта обращается к тем же endpoint'ам API, что и обычный пользователь с дополнением на тарифе.
Как это реализовано в сервисе
Настройки инспектора (срок хранения, лимит тела, полный захват) сохраняются на аккаунт и при чтении сопоставляются с возможностями тарифа: без дополнения «Экспорт и хранение» действует короткий срок по умолчанию, запрошенный больший срок не применяется. Сервис периодически удаляет события старше эффективного срока каждого владельца; оценка следующего автоудаления в интерфейсе соответствует полуночи UTC плюс выбранное число дней. Экспорт и копирование читают те же детали события, что и экран детализации: JSON — полная структура, raw — текстовая HTTP-транскрипция, cURL — команда с публичным https адресом и экранированием аргументов для оболочки. Массовый экспорт доступен только в JSON (до 50 id); ответ всегда JSON-массив, в том числе при одном id. Формат HAR не поддерживается — при запросе сервис отвечает ошибкой с подсказкой использовать JSON, raw или cURL. Удаление и очистка затрагивают только журнал инспектора; записи туннеля и его публичный endpoint остаются.
Настройки инспектора — срок хранения и entitlements
GET /api/v1/inspector/settings
PUT /api/v1/inspector/settings
Требуется авторизация. Базовые поля захвата тел описаны в документации «Захват тел запросов». Дополнение «Экспорт и хранение» добавляет и изменяет следующие поля.
Ответ GET (и эффективные значения после PUT)
| Поле | Описание |
| --- | --- |
| retention_days | Эффективный срок хранения событий инспектора в днях. Без дополнения на тарифе всегда 3. С дополнением — сохранённое значение в пределах тарифного лимита. |
| plan_retention_days_max | Максимальный срок, разрешённый тарифом: 3 без дополнения, 365 с дополнением «Экспорт и хранение». |
| next_auto_deletion_at | Оценка момента автоудаления событий, зафиксированных «сегодня»: RFC3339, 00:00:00 UTC на дату через retention_days календарных дней от текущего UTC-дня. |
| export_retention_entitled | true, если на тарифе есть дополнение «Экспорт и хранение» (настройка срока выше 3 дней и экспорт API/UI). |
| body_capture_entitled | true, если на тарифе есть дополнение «Захват тел запросов» (см. связанную документацию). |
Поле PUT
| Поле | Описание |
| --- | --- |
| retention_days | Запрошенный срок в днях. Без export_retention_entitled сервер сохраняет 3 независимо от запроса. С дополнением значение ограничивается диапазоном 1 … plan_retention_days_max; значение выше лимита урезается до лимита (не ошибка). |
При PUT без права на захват тел full_capture_enabled сбрасывается в false (см. документацию захвата тел).
Успешный PUT возвращает JSON с status: "updated" и объектом settings с сохранёнными полями.
Максимальный размер тела запроса для PUT — 32 КиБ; больший объём отклоняется с 400 (см. ошибки).
Экспорт одного события
GET /api/v1/inspector/events/{id}/export
Параметр query format (необязательный):
| format | Ответ |
| --- | --- |
| json или пусто | application/json — полная детализация события (как в GET /api/v1/inspector/events/{id}). |
| raw | text/plain — текстовая HTTP-транскрипция запроса и ответа. |
| curl | text/plain — команда curl с публичным https URL, заголовками и --data-raw при сохранённом теле. Значения аргументов с символами оболочки (;, |, $(), кавычки и т.п.) оборачиваются в одинарные кавычки для безопасной вставки в терминал. |
Успех: 200. В заголовке Content-Disposition — вложение с префиксом имени inspector-event-{id} и суффиксом .json, .http или .sh в зависимости от формата.
Требуется дополнение «Экспорт и хранение» на тарифе (или права администратора).
Контроль доступа: экспорт разрешён только для событий туннелей, к которым у пользователя есть доступ. Отсутствующее событие, уже удалённое или принадлежащее чужому туннелю — ответ 404 Not Found с сообщением «event not found» (тот же вид ответа, что и для несуществующего id; не 403).
Лимит частоты: на каждый успешный запрос экспорта действует пер-пользовательский лимит; при превышении — 429 Too Many Requests («rate limit exceeded»).
Массовый экспорт JSON
POST /api/v1/inspector/events/export?format=json
Тело JSON:
{
"event_ids": ["<uuid>", "<uuid>"]
}
| Поле | Описание |
| --- | --- |
| event_ids | Обязательный массив id событий. Минимум 1, максимум 50 id. |
Максимальный размер тела запроса — 16 КиБ (включая длинные uuid в массиве). Больший объём — 400 без обработки экспорта.
Успех: 200, application/json — всегда JSON-массив объектов детализации событий (никогда одиночный объект), в том числе при одном элементе в event_ids. Content-Disposition с префиксом inspector-events и суффиксом .json.
Те же правила контроля доступа (чужой id → 404) и лимита частоты (429), что и для экспорта одного события.
Параметр format для bulk:
- json — поддерживается (можно опустить query: по умолчанию JSON).
- raw и curl — не поддерживаются для нескольких событий (см. ошибки).
Форматы har, yaml и другие неизвестные значения format — 400.
Интерфейс дашборда
Страница инспектора туннеля: /dashboard/tunnels/{tunnelId}/inspector.
| Элемент | Описание |
| --- | --- |
| Панель Хранение и экспорт (data-testid="inspector-retention-panel") | Текущий срок хранения, лимит тарифа (plan_retention_days_max), строка Ориентировочная дата автоудаления (из next_auto_deletion_at), поле Срок хранения (дней) (id="retention-days") и Сохранить (при export_retention_entitled; поле отключено без дополнения). |
| Панель Захват тел запросов | Лимит тела, переключатель полного захвата (при body_capture_entitled). |
| Детали события | Copy cURL, Copy headers, Copy body, Export JSON — при дополнении на тарифе. |
| Очистить все | Удаление всех событий туннеля в инспекторе; диалог подтверждения сообщает, что публичный URL туннеля останется активным и удаляются только записи инспектора. |
| Удалить (в деталях) | Удаление одного события; диалог подтверждения сообщает, что публичный URL туннеля не изменится. |
401 Unauthorized
Нет сессии или токена для API инспектора.
403 Forbidden
- Нет дополнения «Экспорт и хранение» на тарифе — экспорт (
GET …/export,POST …/events/export) недоступен. - Нет доступа к настройкам инспектора другого аккаунта (для не-администратора).
400 Bad Request
event_idsотсутствует или пустой массив приPOST /api/v1/inspector/events/export.- Более 50 элементов в
event_ids— сообщение о лимите 50 событий. - Тело
POST /api/v1/inspector/events/exportбольше 16 КиБ — запрос отклоняется до обработки экспорта. - Тело
PUT /api/v1/inspector/settingsбольше 32 КиБ — запрос отклоняется до сохранения настроек. - Некорректный uuid в
event_ids— «invalid event id in event_ids». retention_daysвне диапазона 1 …plan_retention_days_maxпри PUT настроек (после учёта тарифа).body_limit_bytesвне диапазона 1024–1048576 (см. захват тел).- Неподдерживаемый
formatпри экспорте (напримерhar,yaml) — текст с указанием поддерживаемых форматов: json, raw, curl. POST …/events/exportсformat=rawилиformat=curlи более чем одним id — raw/curl только для одного события.- Некорректное JSON-тело запроса.
404 Not Found
- Событие для экспорта или удаления не найдено или уже удалено.
- Запрос экспорта по id события чужого туннеля (другой аккаунт) — тот же ответ 404 и то же сообщение «event not found», что и для несуществующего id (не 403, чтобы не раскрывать наличие чужих событий).
429 Too Many Requests
- Превышен лимит частоты экспорта для пользователя на
GET …/events/{id}/exportилиPOST …/events/export. - Текст ответа: rate limit exceeded.
- Подождите и повторите запрос; при частых выгрузках разбейте работу на несколько сессий.
405 Method Not Allowed
Неверный HTTP-метод для endpoint настроек или экспорта (например POST на GET …/events/{id}/export).
503 Service Unavailable
Инспектор или хранилище событий временно недоступны. Повторите запрос позже.
500 Internal Server Error
Внутренняя ошибка при чтении настроек, сохранении или построении экспорта. Если ошибка повторяется — обратитесь в поддержку.
Известные ограничения
- Без дополнения «Экспорт и хранение» срок хранения фиксирован на 3 дня;
plan_retention_days_maxравен 3; настройка срока и экспорт недоступны. - С дополнением максимальный срок хранения — 365 дней; запрос выше лимита урезается до лимита тарифа, а не отклоняется.
next_auto_deletion_at— только ориентировочная оценка по правилу «полночь UTC + retention_days» для событий, зафиксированных в текущий UTC-день; фактическое удаление выполняется фоновой задачей сервиса и может наступить позже в тот же календарный день или после него — не используйте это поле как точный дедлайн для compliance.- Массовый экспорт JSON принимает не более 50 id в одном запросе; для большего числа событий нужны несколько запросов. Ответ всегда JSON-массив, даже если в
event_idsпередан один id (не одиночный объект). - Форматы raw и cURL доступны только для одного события (
GET …/events/{id}/export); bulk endpoint поддерживает только JSON. - Формат HAR (HTTP Archive) не поддерживается и не планируется в текущей версии; запрос
format=harвозвращает 400 с подсказкой использовать JSON, raw HTTP или cURL. - Файлы экспорта (JSON, raw, cURL) содержат захваченные заголовки и тела запросов/ответов — в них могут оказаться токены, cookie, ключи API и другие секреты; храните выгрузки в защищённом месте, не публикуйте и не пересылайте без необходимости.
- Экспорт и кнопки копирования в дашборде требуют дополнение на тарифе; без него доступны только метаданные в списке и деталях по правилам базового инспектора.
- Содержимое экспорта совпадает с детализацией события: без полного захвата тел в экспорте не будет сохранённых тел (см. захват тел).
- Команда cURL и копирование из UI используют публичный
httpshost события; локальные или внутренние адреса не подставляются. Аргументы с символами оболочки экранируются одинарными кавычками — команда рассчитана на вставку в типичный Unix-shell, но не гарантирует корректность во всех оболочках и ОС. - Очистка журнала и удаление события необратимы и не отменяют работу туннеля; публичный URL остаётся прежним.
- Значки truncated и no body в списке событий отражают политику захвата и лимит тела, а не ошибку экспорта.
- Администратор может экспортировать без отдельного дополнения на тарифе, но остаются ограничения форматов и лимита bulk.
Inspector advanced log UX
Общее описание функционала
Дополнение «Расширенный журнал инспектора» добавляет к инспектору HTTP-трафика поиск, точные фильтры, сортировку, закрепление событий и массовое удаление. Оно также открывает подробный вид списка с данными о доставке webhook-inbox. Без дополнения базовый Инспектор остаётся доступен: фильтры по методу, пути, статусу, времени и режиму захвата работают как раньше.
Поиск по сохранённым телам и переключатель Включая тела требуют дополнение «Захват тел запросов». Закрепления общие для всех пользователей с доступом к туннелю. Массовое удаление убирает только записи Инспектора и не меняет публичный адрес туннеля. Коды ошибок и ограничения описаны в справочнике ошибок и известных ограничениях.
Как пользователь может использовать
- Разработчик с дополнением открывает
/dashboard/tunnels/{tunnelId}/inspector, вводит текст в Поиск и находит событие по пути, фрагменту id, заметкам или значению заголовка без открытия каждой записи. - Интегратор включает Включая тела и ищет строку, которая есть только в сохранённом JSON или тексте POST — после включения захвата тел.
- Специалист поддержки задаёт Статус от / Статус до (например 400–499) и Только ошибки, чтобы отфильтровать неуспешные ответы и ошибки доставки webhook-inbox.
- Аналитик сортирует список по Длительность ↓ или Статус ↑ и сравнивает медленные или проблемные запросы в одном экране.
- Пользователь указывает IP клиента, Заголовок и Значение заголовка, чтобы найти трафик конкретного клиента или запросы с определённым
Authorization/X-Request-Id. - Тестировщик фильтрует по Query param и Подстрока в теле, чтобы изолировать один сценарий API среди потока запросов.
- Аналитик задаёт Длительность от/до (мс) и отбирает запросы с аномально долгим или быстрым ответом.
- Интегратор задаёт границы размера запроса, чтобы найти крупные POST или пустые запросы прямо в панели фильтров.
- Пользователь оставляет в верхней строке путь, метод, точный статус, поиск и сортировку, а по кнопке Фильтры открывает боковую панель с периодом захвата и подробными критериями. Число рядом с кнопкой показывает, сколько критериев уже применяется.
- Пользователь нажимает Очистить всё и одновременно сбрасывает базовые и расширенные критерии, не меняя выбранный вид списка и отмеченные события.
- Владелец туннеля закрепляет (Закрепить) ключевые события, включает Только закреплённые и собирает «короткий список» для демо или эскалации.
- Пользователь в другой сессии или браузере видит те же закрепления без повторного действия — состояние общее для туннеля.
- Оператор webhook-inbox переключает Подробный вид и читает delivery_status (
delivered,failed,pending) и destination_label для inbox-трафика без открытия каждой карточки. - Пользователь выбирает несколько строк чекбоксами, подтверждает Удалить выбранные и очищает журнал от шума, оставляя туннель активным.
- Пользователь без дополнения продолжает работать с базовыми фильтрами инспектора; поиск, сортировка и расширенные критерии скрыты, а период и режим захвата по-прежнему доступны в панели фильтров.
- Администратор с правами доступа к туннелю использует те же API и элементы интерфейса, что пользователь с дополнением на тарифе.
- Пользователь сохраняет Компактный или Подробный вид списка — выбор сохраняется в браузере и восстанавливается после перезагрузки страницы.
- Разработчик включает Подробный вид на широком экране и сравнивает события по колонке IP клиента.
- Пользователь открывает событие и видит один основной адрес в строке IP клиента, а исходные заголовки переадресации — отдельно среди заголовков запроса.
- Пользователь просматривает журнал на телефоне без повторения IP в компактных и подробных карточках.
Как это реализовано в сервисе
Инспектор оставляет основные критерии в короткой строке, а подробные помещает в боковую панель. Список событий остаётся видимым, пока пользователь настраивает отбор. На узком экране поля прокручиваются внутри панели, а её заголовок и действия остаются доступными.
Расширенные элементы показываются только пользователям, которым дополнение доступно по тарифу. Фильтр IP клиента использует то же поле source_ip, что и API, поэтому сохранённые ссылки и интеграции продолжают работать. Сам адрес не повторяется в мобильных карточках и компактном списке. Он появляется в подробном списке на широком экране и один раз в метаданных выбранного события. При активном поиске или фильтре список обновляется как единая выборка и сохраняет заданные условия.
Расширенный список событий
GET /api/v1/inspector/events
Требуется авторизация. Базовые параметры списка (tunnel_id, method, status, path_sub / path_contains, capture, from / to, limit, offset) описаны в документации инспектора. Дополнение «Расширенный журнал инспектора» добавляет следующие query-параметры. Без дополнения на тарифе любой запрос с хотя бы одним из них возвращает 403 Forbidden (параметры не применяются молча).
| Параметр | Описание |
| --- | --- |
| source_ip | Подстрока IP клиента (регистронезависимое совпадение). |
| status_min, status_max | Диапазон HTTP-статуса ответа (целые числа). Работает вместе с точным status, если он задан. |
| min_duration_ms, max_duration_ms | Диапазон длительности запроса в миллисекундах. |
| min_request_size, max_request_size | Диапазон сохранённого размера тела запроса в байтах (метаданные захвата). |
| has_error | true — только события с HTTP ≥ 400 или признаками ошибки доставки/захвата. |
| header_name | Имя заголовка для поиска в заголовках запроса или ответа. |
| header_value | Подстрока значения заголовка; требует header_name. |
| query_param_key | Ключ query-параметра в URL запроса. |
| query_param_value | Подстрока значения query-параметра (часто вместе с ключом). |
| body_substring | Подстрока в сохранённом теле запроса; требует tunnel_id и захват тел. |
| search | Глобальный поиск: путь, фрагмент id, заметки, значения заголовков; без join тел по умолчанию. |
| search_include_bodies | true — включить поиск в сохранённых телах при непустом search (медленнее; нужен захват тел). |
| sort_by | ts (по умолчанию), status или duration_ms. |
| sort_dir | asc или desc (по умолчанию desc для ts). |
| pinned_only | true — только закреплённые события на туннеле. |
Параметры search и body_substring обязательно сопоставляются с tunnel_id. Длина шаблона search и body_substring — не более 200 символов.
Дополнительные поля в ответе списка
При наличии дополнения на тарифе (или для администратора) каждый элемент списка может содержать:
| Поле | Описание |
| --- | --- |
| pinned | true, если событие закреплено на туннеле. |
| short_id | Первые 8 символов id события для компактного отображения. |
| request_size | Размер сохранённого тела запроса в байтах (0, если тело не сохранено). |
| delivery_status | Для webhook-inbox: delivered, failed, pending или пусто для обычного HTTP-трафика. |
| destination_label | Подпись назначения inbox (forward URL, local client, store only); учётные данные в URL скрыты. |
Успех: 200 с JSON списка и метаданными пагинации.
Закрепление события
POST /api/v1/inspector/events/{id}/pin
Требуется дополнение на тарифе (или права администратора). {id} — UUID события, URL-encoded.
Успех: 204 No Content. На туннеле действует лимит 50 закреплённых событий.
Снятие закрепления
DELETE /api/v1/inspector/events/{id}/pin
Требуется дополнение. Повторный вызов для уже незакреплённого события также успешен (204).
Массовое удаление
POST /api/v1/inspector/events/delete
Требуется дополнение. Тело JSON:
{
"tunnel_id": "<tunnel_id>",
"event_ids": ["<uuid>", "<uuid>"]
}
| Поле | Описание |
| --- | --- |
| tunnel_id | Обязательный id туннеля (можно также передать в query tunnel_id). |
| event_ids | Обязательный массив id событий: минимум 1, максимум 50 UUID. Все id должны принадлежать указанному туннелю. |
Успех: 200 с JSON {"deleted": <число удалённых записей>}. Удаляются события, сохранённые тела и закрепления для этих id; публичный URL туннеля не меняется.
Интерфейс дашборда
Страница: /dashboard/tunnels/{tunnelId}/inspector.
| Элемент | Описание |
| --- | --- |
| Поиск | Глобальный поиск; подсказка в поле: «Путь, ID, заголовки, заметки…». |
| Включая тела | Переключатель поиска в сохранённых телах; по умолчанию выключен (соответствует search_include_bodies=false). |
| Сортировка | Варианты: Время ↓/↑, Длительность ↓/↑, Статус ↓/↑. |
| Расширенные фильтры | IP клиента, Статус от/до, Длительность от/до (мс), Заголовок, Значение заголовка, Query param, Подстрока в теле, Только ошибки, Только закреплённые. Поле IP клиента передаёт прежний query-параметр source_ip. |
| Очистить фильтры | Сбрасывает базовые и расширенные фильтры, поиск и сортировку. |
| Компактный вид / Подробный вид | Переключение плотности журнала; настройка сохраняется в браузере. |
| IP клиента в журнале | В компактном списке и мобильных карточках IP не повторяется. В подробном списке на широком экране есть одна колонка IP клиента. У выбранного события адрес показан одной строкой в метаданных. |
| Закрепить / Открепить | Действие над записью журнала. |
| Чекбоксы строк | Множественный выбор; не более 50 — сообщение «Можно выбрать не более 50 событий». |
| Удалить выбранные (N) | Подтверждение «Удалить выбранные события (N)? Действие необратимо.» |
Панель поиска, расширенные фильтры и массовое удаление отображаются только при дополнении на тарифе.
401 Unauthorized
Нет сессии или токена для API инспектора.
403 Forbidden
- Нет дополнения «Расширенный журнал инспектора» на тарифе — расширенные query-параметры списка,
POST/DELETEзакрепления иPOST …/events/deleteнедоступны. - Нет доступа к указанному
tunnel_idпри массовом удалении. - В
event_idsуказаны id событий другого туннеля — запрос отклоняется целиком, без частичного удаления.
400 Bad Request
event_idsотсутствует или пустой массив приPOST /api/v1/inspector/events/delete.- Более 50 элементов в
event_ids— текст «event_ids exceeds limit of 50». - Некорректный UUID в
event_ids— «invalid event id in event_ids». tunnel_idне указан при массовом удалении — «tunnel_id required».searchилиbody_substringбезtunnel_id— «tunnel_id required for body/search filters».- Длина
searchилиbody_substringболее 200 символов — «search pattern too long». header_valueбезheader_name— «header_name required when header_value is set».- Недопустимый
sort_by— «invalid sort_by» (разрешены толькоts,status,duration_ms). - Недопустимый
sort_dir— «invalid sort_dir» (разрешеныascиdesc). - Некорректное целое в
status_min,status_max,min_duration_ms,max_duration_ms,min_request_size,max_request_size— соответствующие сообщенияinvalid …. - Некорректное булево в
has_error,pinned_onlyилиsearch_include_bodies—invalid has_error,invalid pinned_onlyилиinvalid search_include_bodies. - Некорректное JSON-тело при массовом удалении — «invalid request body».
404 Not Found
- Событие для закрепления не существует.
- Событие принадлежит туннелю, к которому у вызывающего нет доступа (ответ 404, а не 403, чтобы не раскрывать существование id).
409 Conflict
- Попытка закрепить событие, когда на туннеле уже 50 закреплённых записей — «pin quota exceeded». Старые закрепления не снимаются автоматически.
405 Method Not Allowed
Неверный HTTP-метод для endpoint закрепления или массового удаления.
503 Service Unavailable
Инспектор или хранилище событий временно недоступны («inspector service not available»). Повторите запрос позже.
500 Internal Server Error
Внутренняя ошибка при фильтрации, закреплении или удалении. Если ошибка повторяется — обратитесь в поддержку.
Известные ограничения
- Без дополнения «Расширенный журнал инспектора» расширенные параметры списка, закрепление и массовое удаление недоступны; базовые фильтры инспектора работают как до дополнения.
- На каждый туннель — не более 50 закреплённых событий; при превышении новое закрепление отклоняется (409), без автоматического снятия старых.
- Закрепления общие для всех пользователей с доступом к туннелю (endpoint-scoped), не персональные.
- Массовое удаление — не более 50 id в одном запросе; в интерфейсе выбор строк также ограничен 50.
- Шаблоны
searchиbody_substring— не длиннее 200 символов. - Поиск и фильтр Подстрока в теле находят только сохранённые тела; нужны дополнение «Захват тел запросов» и соответствующий режим захвата.
- Переключатель Включая тела по умолчанию выключен; поиск по умолчанию не читает большие payload'ы — запросы с телами могут выполняться медленнее.
- Колонки
delivery_statusиdestination_labelвычисляются при каждом отображении списка на основе данных события и актуальных настроек webhook-inbox; подпись назначения может измениться, если настройки inbox обновили после захвата события. Отдельная история попыток доставки и счётчик попыток пока не отображаются. - Фильтр по диапазону размера запроса (
min_request_size/max_request_size) доступен только через API — в панели расширенных фильтров дашборда его нет. - Сравнение событий и массовый replay для выбранных строк не реализованы — для множественного выбора доступно только удаление.
- При активном расширенном запросе (поиск, фильтры или сортировка не по времени ↓) новые события из потока в реальном времени не добавляются в начало списка — список перезагружается с сервера.
- Очистить фильтры сбрасывает и базовую строку, и расширенную панель (поиск, расширенные поля, сортировку).
- Компактный / подробный вид сохраняется только в браузере на этом устройстве — на другом устройстве или в другом браузере настройка не переносится.
- IP клиента не показывается в мобильных карточках и компактном списке. Для сравнения адресов используйте подробный вид на широком экране; у выбранного события адрес остаётся доступен в метаданных.
- Массовое удаление и удаление через API необратимы и не останавливают туннель; публичный URL остаётся прежним.
- Администратор может использовать расширенные API без отдельного дополнения на тарифе, но лимиты 50 на закрепления, удаление и длину поиска сохраняются.
Request body capture
Общее описание функционала
Дополнение «Захват тел запросов» сохраняет тела HTTP-запросов и ответов для событий инспектора трафика в пределах лимита размера и настроек пользователя. Метаданные события (метод, путь, код ответа, заголовки) доступны на всех тарифах с инспектором; полные тела — только при включённой функции на тарифе и при активированном полном захвате в настройках инспектора. Сохранённые тела отображаются в деталях события в дашборде и подгружаются по запросу к API; их можно использовать при повторе вебхука, если тело не было обрезано лимитом.
Как пользователь может использовать
- Разработчик на тарифе с захватом тел включает полный захват в настройках инспектора и просматривает JSON тела входящего вебхука в панели деталей события.
- Пользователь задаёт лимит размера тела (от 1 КиБ до 1 МиБ) и проверяет, что большие запросы сохраняются частично с пометкой об обрезке.
- Интегратор сравнивает тело ответа целевого сервиса с исходным запросом в одном экране инспектора.
- Пользователь без функции на тарифе продолжает видеть только метаданные событий; полные тела не сохраняются даже при попытке включить захват в настройках.
- Владелец туннеля удаляет одно событие или очищает весь журнал туннеля — вместе с сохранёнными телами.
- Пользователь повторяет вебхук с сохранённым телом запроса (см. повтор вебхуков), не вводя тело вручную, если оно сохранено целиком.
Как это реализовано в сервисе
При прохождении HTTP-запроса через туннель сервис фиксирует метаданные события для инспектора. Если тариф и настройки пользователя разрешают полный захват, сервис дополнительно сохраняет ограниченные фрагменты тел запроса и ответа отдельно от строки события в списке. Список и поток событий остаются лёгкими; полное содержимое тел загружается при открытии детали события или при обращении к API детали. При удалении события или очистке журнала туннеля связанные тела удаляются вместе с записью. Повтор запроса может подставить сохранённое тело автоматически, если оно не обрезано; иначе требуется явное тело в параметрах повтора.
Настройки инспектора
GET /api/v1/inspector/settings
PUT /api/v1/inspector/settings
Требуется авторизация. Поля, связанные с захватом тел:
| Поле | Описание |
| --- | --- |
| full_capture_enabled | true — сохранять тела запросов и ответов при наличии функции на тарифе; false — только метаданные. |
| body_limit_bytes | Максимум байт на одно тело (запрос или ответ), от 1024 до 1048576 (1 МиБ). Если не задано, применяется значение по умолчанию 65536 (64 КиБ). |
На тарифе без дополнения «Захват тел запросов» события остаются с capture_level: metadata; тела не сохраняются независимо от full_capture_enabled.
Детали события с телами
GET /api/v1/inspector/events/{id}
Помимо полей события из базового инспектора, при сохранённых телах в ответе могут быть:
| Поле | Описание |
| --- | --- |
| request_body / response_body | Метаданные: captured, bytes_saved, truncated, content_type, при обрезке — bytes_original. |
| request_body_content / response_body_content | Содержимое: encoding (utf-8 или base64), text для текстовых типов, raw_base64 для бинарных, для multipart/form-data — список multipart_files с именами и размерами частей. |
| capture_level | full при сохранённых телах, иначе metadata. |
| truncated | true, если хотя бы одно тело обрезано лимитом. |
Тела не включаются в список событий и в SSE-поток — только в ответ детали.
Удаление событий и тел
DELETE /api/v1/inspector/events/{id}
Удаляет одно событие и все связанные сохранённые тела. Успех: 204 No Content. Нет доступа к туннелю: 403. Событие не найдено: 404.
DELETE /api/v1/inspector/events?tunnel_id={tunnelId}
Удаляет все HTTP-события инспектора для указанного туннеля и их тела. Успех: JSON с полем deleted (число удалённых записей). Параметр tunnel_id обязателен.
Связь с повтором вебхука
POST /api/v1/inspector/events/{eventId}/replay — при полном сохранённом теле запроса поле overrides.body можно не указыать; сервис отправит сохранённые байты. Подробности — в документации повтора вебхуков.
401 Unauthorized
Нет сессии или токена для API инспектора.
403 Forbidden
Нет доступа к туннелю события или к настройкам чужого аккаунта. Удаление чужого события отклоняется без изменения данных.
400 Bad Request
body_limit_bytesвне диапазона 1024–1048576 при сохранении настроек.- Некорректные параметры запроса (например, отсутствует
tunnel_idпри массовом удалении).
404 Not Found
Событие не найдено или уже удалено.
503 Service Unavailable
Инспектор или хранилище событий временно недоступны. Повторите запрос позже.
Повтор с обрезанным телом
При вызове повтора вебхука без overrides.body для события с обрезанным сохранённым телом запроса — 400 с сообщением о том, что тело было обрезано и нужно указать тело в параметрах повтора. Подробнее — в ошибках повтора вебхуков.
Известные ограничения
- Полный захват тел доступен только на тарифах с дополнением «Захват тел запросов» и при
full_capture_enabled: trueв настройках инспектора. - Без функции на тарифе события всегда остаются на уровне метаданных, даже если полный захват включён в настройках.
- На каждое тело (запрос и ответ отдельно) действует лимит
body_limit_bytes; превышающая часть не сохраняется, в метаданных выставляетсяtruncated: true. - Значение по умолчанию лимита — 64 КиБ, если пользователь не задал другое в допустимом диапазоне.
- Бинарные и нетекстовые типы содержимого в API детали отдаются в кодировке base64, а не как читаемый текст.
- Для
multipart/form-dataв детали перечисляются метаданные частей (имя, имя файла, тип, размер); полное содержимое каждой части может быть недоступно при обрезке. - Сохранённые тела не попадают в список событий и поток SSE — только в запрос детали события.
- Автоматический повтор вебхука с сохранённым телом невозможен, если тело запроса было обрезано; нужно передать
overrides.bodyвручную (до 32 КиБ). - Удаление события или очистка журнала туннеля необратимо удаляет и сохранённые тела.