Аудит событий

В STOMP-клиентах поверх WebSocket ключевым источником наблюдаемости становится поток событий: соединение, переподключение, подписки, входящие сообщения, ошибки протокола и жизненный цикл ACK. В экосистеме STOMP.js аудит событий формирует основу диагностики и эксплуатационного контроля, поскольку сам протокол STOMP минималистичен и не предоставляет встроенной телеметрии.


Событийная модель STOMP-клиента строится вокруг нескольких слоёв:

  • транспортный слой WebSocket
  • протокольный слой STOMP frame processing
  • прикладной слой подписок (subscriptions)
  • слой управления состоянием соединения

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

Типовой набор событий:

  • установление соединения (CONNECT / CONNECTED)
  • разрыв соединения (DISCONNECT / socket close)
  • ошибки протокола (ERROR frame)
  • входящие сообщения (MESSAGE frames)
  • подтверждение доставки (ACK / NACK)
  • события подписки (SUBSCRIBE / UNSUBSCRIBE)
  • heartbeat события (ping/pong или idle timeout)

Аудит жизненного цикла соединения

Жизненный цикл соединения является базовой осью аудита. Каждое состояние фиксируется с метаданными:

  • timestamp
  • sessionId
  • endpoint URL
  • причина изменения состояния
  • код ошибки (если есть)

Пример структуры аудиторской записи:

{
  "type": "connection_state",
  "state": "CONNECTED",
  "sessionId": "c7a12f3",
  "endpoint": "wss://api.example/ws",
  "ts": 1710001122334
}

Для отслеживания нестабильности важны переходы:

  • CONNECTING → CONNECTED
  • CONNECTED → DISCONNECTED
  • CONNECTED → RECONNECTING
  • RECONNECTING → FAILED

Особое значение имеет фиксация причины разрыва: сетевой таймаут, серверное закрытие, протокольная ошибка.


Аудит входящих сообщений

Сообщения STOMP представляют основной поток данных системы. Аудит сообщений включает:

  • маршрут (destination)
  • headers
  • payload
  • subscription id
  • delivery timestamp
  • correlation id (если используется)

Формируется единая запись:

{
  "type": "message",
  "destination": "/topic/orders",
  "subscription": "sub-1",
  "headers": {
    "message-id": "m-99121",
    "content-type": "application/json"
  },
  "payload": "{\"id\":42,\"status\":\"paid\"}",
  "ts": 1710001122999
}

Критическим аспектом является контроль полноты доставки: отсутствие сообщений при активной подписке трактуется как нарушение потока данных, а не как «тишина».


Аудит подписок

Подписки формируют динамическую карту интересов клиента. Каждая подписка должна фиксироваться:

  • момент создания
  • destination
  • id подписки
  • режим ACK (auto/client/client-individual)
  • момент отмены

Важной частью является сопоставление подписок с соединением: при реконнекте подписки часто пересоздаются, что приводит к дублированию потоков, если аудит отсутствует.

{
  "type": "subscription",
  "action": "SUBSCRIBE",
  "destination": "/queue/payments",
  "subscriptionId": "sub-77",
  "ack": "client",
  "ts": 1710001130001
}

При переподключении фиксируется стратегия восстановления:

  • полная ресубскрипция
  • частичная (по whitelist)
  • ленивое восстановление по требованию

Аудит ошибок и STOMP ERROR frames

STOMP ERROR frame содержит серверную диагностику, но без системного аудита она теряется или не связывается с контекстом.

Аудиторская запись ошибки включает:

  • тип ошибки (protocol / application / transport)
  • raw frame
  • parsed message
  • stack context клиента
  • correlation с текущей сессией
{
  "type": "error",
  "category": "protocol",
  "message": "Invalid destination",
  "frame": "ERROR\nmessage:Invalid destination\n\n",
  "sessionId": "c7a12f3",
  "ts": 1710001140000
}

Особое значение имеет разделение ошибок:

  • транспортные (WebSocket close codes)
  • протокольные (STOMP ERROR)
  • прикладные (ошибки payload processing)

Heartbeat и контроль живости соединения

Heartbeat механизм используется для обнаружения «тихих обрывов». Аудит фиксирует:

  • входящие heartbeat frames
  • исходящие heartbeat frames
  • интервалы между ними
  • отклонения от нормы

Типовой анализ:

  • задержка heartbeat > threshold → деградация сети
  • отсутствие heartbeat → подозрение на silent disconnect

Запись аудита:

{
  "type": "heartbeat",
  "direction": "in",
  "latency_ms": 1200,
  "sessionId": "c7a12f3",
  "ts": 1710001150000
}

Корреляция событий

Без корреляции событий аудит превращается в поток несвязанных записей. Основной механизм — correlationId.

Он связывает:

  • исходящий запрос (SEND)
  • входящее сообщение (MESSAGE)
  • ACK подтверждение
  • серверные ошибки

Пример цепочки:

  1. SEND order.create
  2. MESSAGE order.created
  3. ACK delivery

Каждое событие получает одинаковый correlationId, что позволяет строить полную трассировку взаимодействия.


Логирование уровня протокола

STOMP frame logging включает:

  • raw frames (SEND, SUBSCRIBE, MESSAGE)
  • headers normalization
  • escaping/unescaping payload
  • size metrics

Пример протокольного аудита:

SEND
destination:/app/order
content-length:34

{"id":42}

Фиксируются также:

  • размер frame
  • время сериализации
  • время отправки в WebSocket

Метрики аудита

На основе событий формируются метрики:

  • количество сообщений в секунду
  • средняя задержка доставки
  • количество реконнектов
  • процент ошибок
  • активные подписки

Пример агрегированных данных:

  • messages_in: 1200/min
  • messages_out: 1100/min
  • reconnect_count: 3/hour
  • error_rate: 0.12%

Эти метрики строятся исключительно из событийного потока.


Аудит реконнектов и деградации

Реконнект — критическая зона нестабильности. Каждый цикл включает:

  • причина разрыва
  • задержка до восстановления
  • количество попыток
  • восстановленные подписки
{
  "type": "reconnect",
  "attempt": 2,
  "reason": "network_timeout",
  "downtime_ms": 4500,
  "restored_subscriptions": 5
}

Особое внимание уделяется эффекту «штормового реконнекта», когда множественные клиенты одновременно восстанавливают соединения.


Безопасность и аудит payload

Аудит событий часто пересекается с безопасностью:

  • контроль чувствительных данных в payload
  • маскирование токенов в headers
  • проверка размера сообщений (anti-abuse)

Применяются правила:

  • ограничение payload size
  • логирование только метаданных при sensitive destinations
  • исключение секретов из трассировки

Трассировка end-to-end

Полный аудит событий позволяет строить цепочку:

WebSocket open → CONNECT → SUBSCRIBE → MESSAGE → ACK → DISCONNECT

Каждое звено содержит временные метки, что позволяет вычислять:

  • latency доставки
  • server processing time
  • network jitter

При наличии correlationId строится полноценная трассировка запрос-ответ.


Архитектура централизованного аудита

Типовая архитектура включает:

  • Event Collector (перехват STOMP frames)
  • Normalizer (приведение к единому формату)
  • Buffer (локальная очередь)
  • Exporter (отправка в лог-систему)
  • Storage (аналитическая база)

Поток событий:

STOMP client → interceptor → audit bus → exporter → monitoring system


Перехват событий в клиенте

Аудит реализуется через обёртки над основными операциями:

  • connect()
  • subscribe()
  • send()
  • onMessage()
  • onError()

Каждая функция генерирует событие аудита до и после выполнения операции, формируя двойную фиксацию состояния:

  • intent event
  • result event

Поведение при потере событий

Потеря событий рассматривается как отдельный класс ошибок:

  • переполнение буфера аудита
  • сбой логирования
  • отключение exporter

В таких случаях фиксируются мета-события:

{
  "type": "audit_failure",
  "reason": "buffer_overflow",
  "dropped_events": 120
}

Практическая модель наблюдаемости

Полноценный аудит событий в STOMP-клиенте строится на принципах:

  • неизменяемость событий
  • детерминированная сериализация
  • обязательная корреляция
  • временная синхронизация
  • разделение транспортных и прикладных событий

Такой подход превращает поток STOMP-сообщений в трассируемую систему взаимодействий, пригодную для диагностики, мониторинга и анализа поведения распределённых WebSocket-систем.