Документация Запись трафика

Рекордер трафика

Рекордер трафика перехватывает HTTP/HTTPS-трафик, проходящий через Mockarty, и преобразует его в моки, тестовые коллекции и скрипты нагрузочного тестирования. Он работает как перехватывающий прокси между вашим приложением и реальным upstream-сервисом, записывая каждую пару запрос/ответ в реальном времени.

Рекордер — сессия с захваченным трафиком
Рекордер — модалка «Создать моки из трафика»

Совет: Примеры кода доступны для cURL, CLI и SDK-клиентов (Go, Python, Java). Смотрите Руководство по SDK для установки и настройки. Смотрите Руководство по CLI для командной утилиты.

Что такое запись трафика?

Запись трафика означает размещение прокси между вашим приложением и вызываемыми им сервисами, чтобы каждый проходящий HTTP-запрос и ответ был захвачен и сохранён для последующего анализа. В отличие от обычного логирования приложения, которое записывает только то, что ваш код явно выводит в файлы логов (сообщения, стек-трейсы), запись трафика захватывает полные сырые данные: URL запросов, заголовки, тела, коды статусов ответов, тела ответов и точную детализацию тайминга (DNS-запрос, TLS-рукопожатие, время до первого байта).

Представьте это как камеру наблюдения для ваших API-вызовов – каждый разговор между приложением и его зависимостями сохраняется в полной детализации, а не только те моменты, которые разработчики решили залогировать.

Чем отличается от Charles Proxy / Fiddler?

Charles Proxy и Fiddler — это десктопные GUI-инструменты для ручной отладки: вы устанавливаете их на свою машину, направляете на них браузер и визуально инспектируете отдельные запросы. Рекордер Mockarty создан для другого рабочего процесса:

  • Интегрированная генерация моков. После записи вы можете конвертировать захваченный трафик в моки Mockarty одним кликом — без шагов экспорта/импорта. Charles и Fiddler не умеют генерировать моки.
  • Серверное развёртывание. Рекордер работает как часть вашего экземпляра Mockarty, поэтому может использоваться в CI-пайплайнах, staging-окружениях и Docker-сетапах — не только на ноутбуке разработчика.
  • Экспорт тестовых артефактов. Записанные сессии можно экспортировать как коллекции API Tester, скрипты нагрузочного тестирования или наборы регрессионных тестов. Десктопные прокси экспортируют только HAR-файлы.
  • Симуляция токсичности. Вы можете внедрять задержки, ошибки и ограничение пропускной способности в проксируемый трафик во время записи. У Charles есть аналогичные функции “throttle”, но Mockarty интегрирует их непосредственно в сессию записи.
  • Совместимость с HAR. Mockarty по-прежнему экспортирует стандартные HAR-файлы, поэтому вы можете открывать записи в Chrome DevTools или Charles при необходимости.

Зачем записывать трафик?

  • Автогенерация моков из продакшн-трафика. Направьте staging-окружение на рекордер, запустите тестовый набор и экспортируйте записанный трафик в виде моков Mockarty. Никакого ручного написания JSON.
  • Отладка проблем интеграции с API. Просматривайте точные байты, которые ваше приложение отправляет и получает, включая заголовки, детализацию тайминга (DNS, TLS-хендшейк, TTFB) и сжатые/распакованные тела запросов.
  • Регрессионное тестирование. Запишите эталонную сессию, экспортируйте её как тестовую коллекцию и запускайте при каждой сборке в CI для обнаружения изменений контрактов.
  • Аудит соответствия. Храните журнал с временными метками всех API-вызовов между вашими сервисами в течение периода аудита.
  • Хаос-инженерия. Внедряйте задержки, джиттер, ошибки и ограничение пропускной способности, чтобы проверить поведение приложения в условиях деградации сети — без изменения upstream-сервиса.

Как работает рекордер (серверная сторона)

Рекордер работает полностью на сервере Mockarty, а не в вашем браузере. Когда вы запускаете сессию записи, Mockarty открывает прокси-порт (например, 8085) на машине, где он развёрнут. Ваше приложение должно быть настроено на отправку трафика именно на адрес и порт этой машины.

Это важное различие: UI рекордера — это то, что вы видите в браузере, а реальный прокси работает на сервере. Понимание этого критично для правильной настройки приложения.

Сетевая настройка в зависимости от развёртывания

Развёртывание UI Mockarty Адрес прокси (для вашего приложения)
Локальный (бинарник) http://localhost:5770/ui/recorder http://localhost:8085
Docker (та же машина) http://localhost:5770/ui/recorder http://localhost:8085 (нужен -p 8085:8085)
Удалённый сервер (192.168.1.50) http://192.168.1.50:5770/ui/recorder http://192.168.1.50:8085
Корпоративный / DNS https://mockarty.company.com/ui/recorder http://mockarty.company.com:8085
Kubernetes https://mockarty.k8s.company.com/ui/recorder Зависит от конфигурации Service/Ingress

Пользователям Docker: Прокси-порт (например, 8085) — отдельный от основного порта Mockarty (5770). Его нужно пробросить явно: docker run -p 5770:5770 -p 8081-8999:8081-8999 .... Если порт не проброшен, ваше приложение не сможет достучаться до прокси.

Пользователям Kubernetes: Прокси-порты (8081–8999) должны быть доступны через Service или NodePort. Обратитесь к настройкам сети вашего кластера.

Удалённое развёртывание (Remote Deployment)

Когда Mockarty работает на удалённом хосте (staging-сервер, CI-агент, кластер Kubernetes), а ваше приложение — в другом месте, нужно учесть три момента:

  1. UI открывается по одному URL (например, https://mockarty.company.com/ui/recorder).
  2. Прокси-порт открывается напрямую (например, http://mockarty.company.com:8085). HTTP-reverse-proxy вроде Nginx обычно пробрасывает только путь UI — они не пробрасывают диапазон 8081–8999, пока вы явно не настроите stream-блок.
  3. Диапазон 8081–8999 должен быть открыт сквозь все слои — host firewall, Docker -p, Kubernetes Service/Ingress, корпоративные прокси.

Пример Docker Compose. Все compose-файлы в deploy/compose/ уже публикуют диапазон рекордера. Если у вас свой compose, добавьте:

services:
  mockarty:
    ports:
      - "5770:5770"              # Web UI / REST API
      - "8081-8999:8081-8999"    # Порты прокси-рекордера

Пример Kubernetes. Опубликуйте диапазон через отдельный Service (NodePort или LoadBalancer). Ingress-контроллеры обычно не умеют проксировать не-HTTP порты; лучше использовать Service:

apiVersion: v1
kind: Service
metadata:
  name: mockarty-recorder
spec:
  type: LoadBalancer
  selector:
    app: mockarty
  ports:
    - name: ui
      port: 5770
      targetPort: 5770
    - name: recorder
      port: 8085          # добавьте по одному порту на активную сессию, либо используйте диапазон портов через L4-балансировщик
      targetPort: 8085

Для эластичного распределения по 8081–8999 используйте облачный балансировщик с поддержкой диапазонов (AWS NLB, GCP TCP LB) или поставьте перед кластером L4-прокси (HAProxy, Envoy), который пробрасывает весь диапазон.

Чек-лист проверки. С машины, где запускается приложение под тестом:

# 1. Доступен ли UI Mockarty?
curl -I https://mockarty.company.com/ui/recorder

# 2. Запустите сессию в UI, запомните порт (например, 8085).
# 3. Доступен ли этот порт напрямую?
curl -v http://mockarty.company.com:8085/

# Если шаг 3 висит или даёт refuse — диапазон портов недоступен, нужно править firewall/Service.

Режимы записи

Страница рекордера

Обратный прокси (Reverse Proxy)

Ваше приложение обращается к прокси-порту Mockarty (например, :8085), а Mockarty перенаправляет каждый запрос на реальный upstream-сервер (например, https://api.stripe.com).

App  ──►  Mockarty :8085  ──►  api.stripe.com
                 │
          (записывает трафик)

Как настроить приложение: Направьте его на прокси-адрес Mockarty вместо реального API. Если Mockarty работает локально — это http://localhost:8085. Если на удалённом сервере 192.168.1.50 — это http://192.168.1.50:8085.

Лучше всего подходит для: работы с одним upstream-сервисом, локальной разработки, CI-пайплайнов.

Прямой прокси (Forward Proxy)

Mockarty работает как классический HTTP-прокси. Настройте ваше приложение (или ОС), указав переменную окружения HTTP_PROXY на прокси-порт Mockarty:

App  ──HTTP_PROXY──►  Mockarty :8085  ──►  любой upstream
                            │
                     (записывает трафик)

Как настроить приложение:

# Если Mockarty работает локально:
export HTTP_PROXY=http://localhost:8085

# Если Mockarty на удалённом сервере:
export HTTP_PROXY=http://192.168.1.50:8085
# или
export HTTP_PROXY=http://mockarty.company.com:8085

HTTP-запросы записываются полностью. HTTPS-трафик туннелируется через метод CONNECT. Для расшифровки HTTPS включите MITM-перехват.


Запуск сессии записи

Через UI

  1. Перейдите в раздел Рекордер в боковой панели (/ui/recorder).
  2. Нажмите Новая сессия.
  3. Выберите режим (Обратный прокси или Прямой прокси).
  4. Для обратного прокси введите URL назначения (например, https://api.example.com).
  5. При необходимости укажите Порт прослушивания (автоматически назначается из диапазона 8081–8999, если не указан).
  6. Настройте фильтры, токсики, модификации, MITM и Map Local по необходимости.
  7. Нажмите Старт.

Сессия начинает запись немедленно. Новые записи поступают в UI через WebSocket в реальном времени.

Через API

cURL

curl -X POST http://localhost:5770/api/v1/recorder/start \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "name": "Stripe Integration Test",
    "mode": "reverse",
    "targetUrl": "https://api.stripe.com",
    "listenPort": 8085,
    "namespace": "default",
    "filters": {
      "includePaths": ["/v1/*"],
      "excludePaths": ["/v1/health"]
    },
    "toxics": {
      "delayMs": 100,
      "delayJitter": 50
    }
  }'

CLI

# Запуск сессии записи трафика
mockarty-cli recorder start --name "Stripe Integration Test" \
  --target https://api.stripe.com \
  --port 8085 --session-namespace default

Примечание: Фильтры, токсики и расширенные опции доступны через REST API и веб-интерфейс. Команда mockarty-cli recorder start создаёт базовую сессию reverse-proxy; для полной конфигурации используйте API напрямую.

Go

// Запуск сессии записи
session, err := client.StartRecorderSession(&mockarty.RecorderSessionRequest{
    Name:      "Stripe Integration Test",
    TargetURL: "https://api.stripe.com",
    Port:      8085,
    Namespace: "default",
})

Python

# Запуск сессии записи
session = client.recorder.start_recording(
    name="Stripe Integration Test",
    mode="reverse",
    target_url="https://api.stripe.com",
    listen_port=8085,
    namespace="default",
    filters={"includePaths": ["/v1/*"], "excludePaths": ["/v1/health"]},
    toxics={"delayMs": 100, "delayJitter": 50},
)

Java

// Запуск сессии записи
var session = client.recorder().startRecording(RecorderStartRequest.builder()
    .name("Stripe Integration Test")
    .mode("reverse")
    .targetUrl("https://api.stripe.com")
    .listenPort(8085)
    .namespace("default")
    .build());

Ответ:

{
  "session": {
    "id": "a1b2c3d4-...",
    "name": "Stripe Integration Test",
    "mode": "reverse",
    "targetUrl": "https://api.stripe.com",
    "listenPort": 8085,
    "status": "running",
    "entryCount": 0,
    "createdAt": "2026-03-14T10:00:00Z",
    "expiresAt": "2026-03-14T14:00:00Z"
  }
}

Параметры конфигурации сессии

Поле Тип Описание
name string Читаемое название. Генерируется автоматически, если не указано.
mode "reverse" или "forward" Режим прокси. По умолчанию: "reverse".
targetUrl string URL upstream-сервера. Обязателен для обратного прокси.
listenPort int Порт прослушивания прокси. Назначается автоматически (8081–8999), если 0.
namespace string Пространство имён Mockarty. По умолчанию: "default".
toxics object Правила токсичности (задержка, джиттер, ошибки, пропускная способность).
filters object Фильтры области (хосты, пути, методы, коды статусов).
modifications object Правила модификации запросов/ответов.
mitm object Конфигурация MITM TLS-перехвата.
mapLocal object Авто-ответчик с использованием моков Mockarty.

Фильтры области

Фильтры управляют тем, какие запросы записываются. Пустое измерение фильтра означает «разрешить все». Все строки шаблонов поддерживают glob-синтаксис.

{
  "filters": {
    "includeHosts": ["api.example.com", "*.internal.corp"],
    "excludeHosts": ["telemetry.example.com"],
    "includePaths": ["/api/*", "/v2/*"],
    "excludePaths": ["/api/healthcheck", "/api/metrics"],
    "includeMethods": ["GET", "POST", "PUT"],
    "excludeStatus": [304, 204]
  }
}

Как вычисляются фильтры

  1. Если includeHosts не пуст, хост запроса должен соответствовать хотя бы одному шаблону.
  2. Если хост совпадает с любым шаблоном из excludeHosts, запрос пропускается.
  3. Аналогичная логика для includePaths / excludePaths.
  4. Если includeMethods не пуст, HTTP-метод должен быть в списке.
  5. Если код статуса ответа входит в excludeStatus, запись отбрасывается.

Примеры glob-шаблонов

Шаблон Совпадает с
*.example.com api.example.com, auth.example.com
/api/v1/* /api/v1/users, /api/v1/orders
/api/*/details /api/users/details, /api/orders/details

Симуляция токсичности

Внедряйте искусственную деградацию в проксируемый трафик, чтобы проверить поведение приложения в реальных сетевых условиях.

Токсики настраиваются для каждого протокола — правила вкладываются под ключ протокола (http, websocket, sse, grpc):

{
  "toxics": {
    "http": {
      "delayMs": 200,
      "delayJitter": 100,
      "errorRate": 0.05,
      "errorStatus": 503,
      "bandwidthKBps": 50,
      "slowReadKBps": 10
    }
  }
}

HTTP-токсики

Поле Тип Описание
delayMs int Фиксированная задержка (мс), добавляемая перед каждым ответом.
delayJitter int Случайный джиттер в диапазоне ±jitter мс, добавляется поверх delayMs.
errorRate float Доля запросов, завершающихся с указанным errorStatus (от 0.0 до 1.0).
errorStatus int HTTP-код для инжектируемых ошибок. По умолчанию: 503.
bandwidthKBps int Ограничение пропускной способности ответа в КБ/с. 0 = без ограничений.
slowReadKBps int Ограничение скорости чтения тела запроса в КБ/с. 0 = без ограничений.

Примеры сценариев:

  • Симуляция медленного стороннего API: delayMs: 500, delayJitter: 200
  • Тестирование срабатывания circuit breaker: errorRate: 0.3
  • Симуляция мобильной сети: bandwidthKBps: 25, delayMs: 150
  • Инжекция пользовательских кодов ошибок: errorRate: 0.1, errorStatus: 504

Правила модификации

Модифицируйте запросы и ответы при прохождении через прокси. Правила применяются по порядку. Изменения влияют на то, что отправляется на upstream и что получает ваше приложение, но оригинальный запрос по-прежнему сохраняется в записи.

Модификация заголовков

{
  "modifications": {
    "requestHeaders": [
      { "action": "add", "name": "X-Debug", "value": "recorder" },
      { "action": "replace", "name": "Authorization", "value": "Bearer test-token" },
      { "action": "remove", "name": "X-Internal-ID" }
    ],
    "responseHeaders": [
      { "action": "add", "name": "X-Recorded", "value": "true" }
    ]
  }
}

Действия для правил заголовков: add, replace, remove.

Перезапись URL

Перезапись URL на основе регулярных выражений с поддержкой групп захвата:

{
  "modifications": {
    "urlRewrites": [
      {
        "match": "/api/v1/(.*)",
        "replace": "/api/v2/$1"
      }
    ]
  }
}

Замена в теле ответа

Замена текста в телах ответов с помощью строк или регулярных выражений:

{
  "modifications": {
    "bodyReplacements": [
      {
        "match": "production-db.internal",
        "replace": "localhost:5432",
        "isRegex": false
      },
      {
        "match": "\"apiKey\":\\s*\"[^\"]+\"",
        "replace": "\"apiKey\": \"REDACTED\"",
        "isRegex": true
      }
    ]
  }
}

Обновление модификаций в работающей сессии

Вы можете обновить правила модификации без перезапуска сессии:

curl -X PUT http://localhost:5770/api/v1/recorder/<session-id>/modifications \
  -H "Content-Type: application/json" \
  -d '{
    "modifications": {
      "requestHeaders": [
        { "action": "add", "name": "X-Trace", "value": "123" }
      ]
    }
  }'

Map Local (авто-ответчик)

Когда Map Local включён, прокси проверяет наличие подходящего мока Mockarty перед перенаправлением на upstream. Если мок найден, его ответ отдаётся локально без сетевого вызова. Запись помечается флагом "mapLocal": true.

{
  "mapLocal": {
    "enabled": true,
    "namespace": "staging"
  }
}

Если namespace не указан, используется пространство имён сессии по умолчанию.

Примеры использования:

  • Заглушка для нестабильного upstream-эндпоинта во время записи.
  • Внедрение определённых ответов об ошибках для тестирования граничных случаев.
  • Комбинирование реального трафика с замоканными эндпоинтами в одной сессии.

Как работает сопоставление: Рекордер ищет моки по паттерну маршрута (regex) и HTTP-методу в указанном пространстве имён. Условия мока (тело запроса, заголовки, query-параметры) не проверяются при Map Local — возвращается первый мок, совпавший по маршруту и методу.


Перехват SSL/TLS (MITM)

Примечание: Если вам нужно записывать только HTTP-трафик (незашифрованный), настройка MITM не требуется. Просто используйте режим обратного прокси, направленный на upstream-сервис, или режим прямого прокси без включения MITM. Приведённая ниже настройка необходима только для расшифровки и инспекции HTTPS-трафика в режиме прямого прокси.

В режиме прямого прокси HTTPS-трафик туннелируется через CONNECT и по умолчанию зашифрован сквозным шифрованием. Для расшифровки и записи тел HTTPS-запросов/ответов включите MITM-перехват.

Как это работает

  1. Mockarty генерирует самоподписанный CA-сертификат (ECDSA P-256, срок действия 10 лет).
  2. При установке CONNECT-туннеля Mockarty генерирует листовой сертификат для целевого хоста, подписанный CA.
  3. Ваше приложение (или браузер) выполняет TLS-хендшейк с листовым сертификатом Mockarty.
  4. Mockarty открывает отдельное TLS-соединение к реальному серверу.
  5. Расшифрованный HTTP-трафик записывается, затем повторно шифруется и пересылается.

Настройка

Шаг 1: Генерация CA

curl -X POST http://localhost:5770/api/v1/recorder/ca/generate

Шаг 2: Скачивание и установка доверия к CA-сертификату

curl -o mockarty-ca.pem http://localhost:5770/api/v1/recorder/ca/download

Установите сертификат в хранилище доверия вашей ОС или браузера:

  • macOS: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain mockarty-ca.pem
  • Linux (Ubuntu/Debian): Скопируйте в /usr/local/share/ca-certificates/mockarty-ca.crt и выполните sudo update-ca-certificates
  • Windows: Дважды щёлкните по .pem-файлу и установите в «Доверенные корневые центры сертификации»
  • Node.js: Установите NODE_EXTRA_CA_CERTS=mockarty-ca.pem
  • Go: Установите SSL_CERT_FILE=mockarty-ca.pem

Шаг 3: Включение MITM при запуске сессии

curl -X POST http://localhost:5770/api/v1/recorder/start \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "forward",
    "mitm": { "enabled": true },
    "listenPort": 8085
  }'

Шаг 4: Настройка вашего приложения

export HTTP_PROXY=http://localhost:8085
export HTTPS_PROXY=http://localhost:8085

Весь HTTPS-трафик теперь будет расшифровываться, записываться и повторно шифроваться прозрачно.


Экспорт записанного трафика

HAR-файл

Экспортируйте сессию (или выбранные записи) в формате HAR, совместимом с Chrome DevTools, Charles Proxy и другими инструментами.

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/export \
  -H "Content-Type: application/json" \
  -d '{ "entryIds": [] }' \
  -o recording.har

Передайте конкретные entryIds для экспорта подмножества или пустой массив для экспорта всех записей.

Генерация моков

Конвертируйте записанные запросы напрямую в моки Mockarty:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "entryIds": [],
    "namespace": "default",
    "prefix": "rec-",
    "tags": ["recorded", "payment-api"],
    "priority": 5
  }'

Параметры:

Поле Описание
entryIds Записи для конвертации. Пустой массив = все.
namespace Целевое пространство имён для созданных моков.
prefix Префикс ID для сгенерированных моков (например, rec-).
tags Теги, применяемые к каждому сгенерированному моку.
chainId Необязательный ID цепочки для связывания моков в рабочий процесс.
forceUpdate Перезаписать существующие моки с тем же ID.
priority Приоритет по умолчанию для сгенерированных моков.

Тестовая коллекция

Экспортируйте записи как коллекцию API Tester для повторного тестирования:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/export-collection \
  -H "Content-Type: application/json" \
  -d '{
    "collectionName": "Payment Flow Regression",
    "namespace": "default",
    "protocol": "http"
  }'

Установите protocol в "tests" для генерации тестового скрипта с ассертами или "performance" для генерации скрипта нагрузочного тестирования.

Скрипт нагрузочного тестирования

Экспортируйте как автономный JavaScript-скрипт нагрузочного тестирования:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/export-perf \
  -H "Content-Type: application/json" \
  -d '{ "entryIds": [] }' \
  -o perf-script.js

Тестовый скрипт

Экспортируйте как JavaScript-скрипт тестирования с ассертами:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/export-test \
  -H "Content-Type: application/json" \
  -d '{ "entryIds": [] }' \
  -o test-script.js

Управление сессиями

Лимиты

Ограничение Значение
Макс. параллельных сессий (глобально) 30
Макс. сессий на пользователя 2
Макс. записей на сессию 1 000 (FIFO-вытеснение)
Автоистечение сессии 4 часа
Хранение записей после остановки 5 дней
Диапазон портов (автоназначение) 8081–8999
Сохранённых конфигураций на пользователя 10
Макс. размер захваченного тела 1 МиБ (тела, превышающие этот лимит, обрезаются)

При достижении 1 000 записей в сессии самая старая запись вытесняется автоматически. Подписчики WebSocket получают уведомление о вытеснении, чтобы UI оставался синхронизированным.

Жизненный цикл сессии

  1. Запущена (Running) — прокси активен, записи захватываются.
  2. Остановлена (Stopped) — прокси выключен, записи доступны для экспорта. Сессии, достигшие лимита автоистечения в 4 часа, автоматически переходят в этот статус.

Сохранённые конфигурации

Сохраняйте часто используемые конфигурации сессий для быстрого повторного использования:

# Сохранение конфигурации
curl -X POST http://localhost:5770/api/v1/recorder/configs \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Stripe Dev",
    "mode": "reverse",
    "targetUrl": "https://api.stripe.com",
    "filters": { "includePaths": ["/v1/*"] }
  }'

# Список сохранённых конфигураций
curl http://localhost:5770/api/v1/recorder/configs

# Экспорт конфигурации в JSON
curl http://localhost:5770/api/v1/recorder/configs/<config-id>/export -o config.json

# Импорт конфигурации из JSON
curl -X POST http://localhost:5770/api/v1/recorder/configs/import \
  -H "Content-Type: application/json" \
  -d @config.json

Потоковая передача в реальном времени

Захват трафика с запросами и ответами в реальном времени

Подключитесь по WebSocket для получения записей по мере их захвата:

ws://localhost:5770/api/v1/recorder/<session-id>/ws

Каждое сообщение — JSON-объект:

{
  "type": "entry",
  "entry": {
    "id": "...",
    "entryType": "http",
    "request": { "method": "GET", "url": "..." },
    "response": { "statusCode": 200 },
    "durationMs": 42,
    "timings": { "dnsMs": 2, "connectMs": 5, "tlsMs": 12, "sendMs": 1.2, "recvMs": 8.5, "waitMs": 20, "totalMs": 42 }
  }
}

Уведомление о вытеснении выглядит так:

{ "type": "entry", "entry": { "id": "__evict__", "notes": "<evicted-entry-id>" } }

Аннотации записей

Помечайте и аннотируйте отдельные записи для последующего анализа:

curl -X PATCH http://localhost:5770/api/v1/recorder/<session-id>/entries/<entry-id> \
  -H "Content-Type: application/json" \
  -d '{
    "tags": ["bug", "timeout"],
    "notes": "This request took 8 seconds — investigate upstream latency"
  }'

Повтор записи

Повторите захваченный запрос к оригинальному (или другому) серверу:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/entries/<entry-id>/replay \
  -H "Content-Type: application/json" \
  -d '{
    "url": "http://api.staging.example.com/api/users/123",
    "headers": { "Authorization": "Bearer new-token" }
  }'

Переопределите любое поле (method, url, headers, body) или оставьте тело пустым для повтора как есть.

Повтор сессии целиком

Перезапустите все захваченные записи против оригинального URL или другого таргета. Полезно для проверки соответствия staging и production, smoke-тестирования нового деплоя реалистичным трафиком и регрессионных проверок после рефакторинга бэкенда. Эндпоинт возвращает сводку с количеством matched, mismatched, failed, skipped и пер-запросные результаты.

cURL
curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/replay \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MOCKARTY_API_TOKEN" \
  -d '{
    "targetUrl": "https://staging.example.com",
    "concurrency": 5,
    "timeoutSeconds": 5,
    "followRedirects": true
  }'
CLI
mockarty-cli recorder replay <session-id> \
  --target https://staging.example.com \
  --concurrency 5 \
  --timeout-ms 5000 \
  --follow-redirects

# Или повторить только выбранные записи:
mockarty-cli recorder replay <session-id> --entries entry-1,entry-2
Go SDK
summary, err := client.Recorder().ReplaySession(ctx, sessionID, &mockarty.ReplayOptions{
    TargetURL:       "https://staging.example.com",
    Concurrency:     5,
    TimeoutMs:       5000,
    FollowRedirects: true,
})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("matched=%d failed=%d\n", summary.Matched, summary.Failed)
Python SDK
summary = client.recorder.replay_session(
    session_id,
    options={
        "targetUrl": "https://staging.example.com",
        "concurrency": 5,
        "timeoutSeconds": 5,
        "followRedirects": True,
    },
)
print(f"matched={summary['matched']} failed={summary['failed']}")
Java SDK
Map<String, Object> summary = client.recorder().replaySession(sessionId, Map.of(
        "targetUrl", "https://staging.example.com",
        "concurrency", 5,
        "timeoutSeconds", 5000,
        "followRedirects", true
));
System.out.println("matched=" + summary.get("matched") +
                   " failed=" + summary.get("failed"));

Движок корреляций

Обнаруживает динамические значения, которые перетекают между записями. Детерминированный движок сопоставления значений сканирует ответы каждой записи (JSON, заголовки, Set-Cookie) и ищет значения, которые затем используются в запросе более поздней записи (URL, заголовок, тело, форма, cookie). Результат подсвечивает токены, идентификаторы и CSRF-значения, которые нужно извлекать на лету вместо того, чтобы хардкодить их из исходного захвата — ровно то, что нужно перед превращением записи в автоматизированный тест-сценарий.

cURL
curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/correlate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MOCKARTY_API_TOKEN" \
  -d '{
    "minValueLength": 6,
    "excludeNumeric": false,
    "maxCorrelationsPerSource": 50
  }'
CLI
mockarty-cli recorder correlate <session-id> \
  --min-len 6 \
  --max-per-source 50

# Пропустить чисто числовые значения вроде целочисленных ID:
mockarty-cli recorder correlate <session-id> --exclude-numeric
Go SDK
report, err := client.Recorder().CorrelateSession(ctx, sessionID, &mockarty.CorrelationOptions{
    MinValueLength: 6,
    ExcludeNumeric: false,
})
if err != nil {
    log.Fatal(err)
}
for _, c := range report.Correlations {
    fmt.Printf("[%s] %s = %q (confidence %.2f, %d targets)\n",
        c.ValueType, c.Source.Section, c.Value, c.Confidence, len(c.Targets))
}
Python SDK
report = client.recorder.correlate_session(
    session_id,
    options={"minValueLength": 6, "excludeNumeric": False},
)
for c in report["correlations"][:5]:
    print(f"[{c['valueType']}] {c['source']['section']}={c['value']!r}"
          f" (confidence {c['confidence']:.2f}, {len(c['targets'])} targets)")
Java SDK
Map<String, Object> report = client.recorder().correlateSession(sessionId, Map.of(
        "minValueLength", 6,
        "excludeNumeric", false
));
@SuppressWarnings("unchecked")
List<Map<String, Object>> corrs =
        (List<Map<String, Object>>) report.getOrDefault("correlations", List.of());
for (Map<String, Object> c : corrs) {
    System.out.println(c.get("valueType") + " = " + c.get("value")
            + " (confidence " + c.get("confidence") + ")");
}

Справочник API

Все эндпоинты находятся по пути /api/v1/recorder. Требуется аутентификация.

Сессии

Метод Путь Описание
POST /start Запуск новой сессии записи
GET /sessions Список сессий текущего пользователя
GET /:id Получение одной сессии
POST /:id/stop Остановка запущенной сессии
POST /:id/restart Перезапуск остановленной сессии (та же конфигурация, новый порт при необходимости)
DELETE /:id Удаление сессии и её записей

Записи

Метод Путь Описание
GET /:id/entries?offset=0&limit=100 Список записей (с пагинацией)
PATCH /:id/entries/:entryId Аннотирование записи (теги, заметки)
POST /:id/entries/:entryId/replay Повтор одной захваченной записи
POST /:id/replay Повтор всех (или выбранных) записей против таргета — возвращает сводку match/fail
POST /:id/correlate Запуск детерминированного движка корреляций — обнаружение перетекания динамических значений
GET /:id/ws WebSocket-поток новых записей

Экспорт

Метод Путь Описание
POST /:id/export Экспорт в HAR-файл
POST /:id/export-perf Экспорт как скрипт нагрузочного тестирования
POST /:id/export-test Экспорт как тестовый скрипт
POST /:id/export-collection Экспорт как коллекция API Tester
POST /:id/mocks Генерация моков Mockarty из записей

Модификации

Метод Путь Описание
GET /:id/modifications Получение текущих правил модификации
PUT /:id/modifications Обновление правил модификации (на лету)

CA-сертификат (MITM)

Метод Путь Описание
GET /ca/status Проверка наличия CA
POST /ca/generate Генерация (или возврат существующего) CA
GET /ca/download Скачивание CA-сертификата в формате PEM

Сохранённые конфигурации

Метод Путь Описание
GET /configs Список сохранённых конфигураций
POST /configs Сохранение новой конфигурации (макс. 10 на пользователя)
DELETE /configs/:id Удаление сохранённой конфигурации
GET /configs/:id/export Экспорт конфигурации в JSON-файл
POST /configs/import Импорт конфигурации из JSON

AI-анализ

Метод Путь Описание
POST /:id/ai-analyze AI-анализ записанного трафика (принимает analysisType: traffic, security, correlate)
POST /:id/ai-scenarios Генерация тестовых сценариев из записанного трафика

Утилиты

Метод Путь Описание
GET /ports Статус пула портов (используемые/максимум/детали)
GET /port-check?port=8085 Проверка доступности порта

Практические примеры

Пример 1: Запись интеграции с платёжным API

Запишите весь трафик между вашим сервисом оформления заказа и Stripe во время тестовой покупки:

# 1. Запуск сессии записи
curl -X POST http://localhost:5770/api/v1/recorder/start \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Checkout Flow",
    "mode": "reverse",
    "targetUrl": "https://api.stripe.com",
    "filters": {
      "includePaths": ["/v1/charges", "/v1/payment_intents", "/v1/customers"],
      "includeMethods": ["POST", "GET"]
    }
  }'

# Возвращает ID сессии и порт прослушивания (например, 8081)

# 2. Направьте ваш сервис оформления заказа на рекордер
export STRIPE_API_BASE=http://localhost:8081

# 3. Запустите тестовый процесс покупки
./run-checkout-tests.sh

# 4. Остановите сессию
curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/stop

Пример 2: Генерация моков из записи

После записи преобразуйте захваченный трафик в моки, воспроизводящие те же ответы:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/mocks \
  -H "Content-Type: application/json" \
  -d '{
    "namespace": "checkout-tests",
    "prefix": "stripe-",
    "tags": ["stripe", "recorded"]
  }'

Теперь ваши тесты оформления заказа могут работать с моками Mockarty без сетевых зависимостей.

Пример 3: Создание регрессионных тестов

Экспортируйте запись как тестовую коллекцию, проверяющую коды статусов и структуру ответов:

curl -X POST http://localhost:5770/api/v1/recorder/<session-id>/export-collection \
  -H "Content-Type: application/json" \
  -d '{
    "collectionName": "Stripe Regression Suite",
    "protocol": "tests"
  }'

Коллекция появится в API Tester и может запускаться при каждой сборке в CI.

Пример 4: Хаос-тестирование с токсиками

Симулируйте деградацию API Stripe для тестирования логики повторных попыток и таймаутов:

curl -X POST http://localhost:5770/api/v1/recorder/start \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Stripe Chaos Test",
    "mode": "reverse",
    "targetUrl": "https://api.stripe.com",
    "toxics": {
      "delayMs": 3000,
      "delayJitter": 1000,
      "errorRate": 0.2
    }
  }'

20% запросов вернут HTTP 503, а оставшиеся 80% получат дополнительную задержку 2-4 секунды.


Поддерживаемые типы записей

Рекордер захватывает шесть типов протоколов:

Тип Описание
http Стандартные пары HTTP-запрос/ответ
websocket WebSocket-соединения с захватом отдельных фреймов
sse Потоки Server-Sent Events с захватом отдельных событий
grpc gRPC унарные и стриминговые вызовы
soap SOAP/XML конверты запроса/ответа
mcp Взаимодействия Model Context Protocol

GraphQL-запросы автоматически определяются и аннотируются именем операции и типом в поле graphqlInfo.


См. также