/** * Wire-level transport counters for the SDK's reconnect + replay path. * * Three counters expose the contract `task.resubscribe` flow has with * QAR's per-session replay buffer: how many resubscribes the SDK has * sent, how many replayed envelopes have come back, and how often the * anchor `since_message_id` rotated out before the SDK could * re-anchor. * * The counters are wire-agnostic — they live next to the spans the SDK * already emits (`src/observability/spans.ts`) rather than inside the * connection itself so consumers can read them off `client.transportMetrics` * without holding a reference to the WS layer. * * Backing storage is in-memory. The SDK does NOT shovel these into an OTel * meter — consumers wanting Prometheus/StatsD scrape paths read the values * via {@link TransportMetrics.snapshot} and forward them through their own * exporter. (OTel's metrics API is a heavier surface than the SDK's tracing * peer-dependency posture wants to pull in for three counters.) */ /** * Snapshot of every counter at a point in time. Counter names are * wire-aligned with QAR's runtime documentation: `*_total` suffix per the * OpenMetrics convention, even though the SDK doesn't ship them through an * OTel meter — the suffix is part of the published name so consumers * forwarding to Prometheus get the canonical metric name without renames. */ export interface TransportMetricsSnapshot { /** Envelopes received via `task.resubscribe` replay (descendants of an anchor). */ readonly replay_envelopes_received_total: number; /** `task.resubscribe` envelopes emitted by the SDK (auto-replay + manual). */ readonly resubscribes_sent_total: number; /** * Inbound `error { code: "replay_anchor_missing" }` envelopes from QAR. * * Defensive wiring — no released QAR emits that code, so this stays at * zero. Don't alert on it, and don't read zero as "no anchor misses." * See `docs/sdk2/reconnect-replay.md` §When the replay anchor is stale. */ readonly replay_anchor_missing_total: number; } /** * In-memory counter store. One instance per `QodoClient` — survives * reconnects so the counters accumulate across the client's lifetime. * * The store is intentionally minimal: three monotonic counters + a * `snapshot()` reader. No reset, no labels, no histograms. Consumers * wanting label dimensionality (per-session, per-task) read the per-event * span attributes instead — the counters are the aggregate roll-up. */ export declare class TransportMetrics { private replayEnvelopesReceived; private resubscribesSent; private replayAnchorMissing; /** Increment per inbound envelope that arrived via a `task.resubscribe` replay window. */ recordReplayEnvelopeReceived(): void; /** Increment per outbound `task.resubscribe` envelope written to the wire. */ recordResubscribeSent(): void; /** * Increment per inbound `error { code: 'replay_anchor_missing' }` envelope. * Defensive — no released QAR emits that code. See * {@link TransportMetricsSnapshot.replay_anchor_missing_total}. */ recordReplayAnchorMissing(): void; /** Read every counter atomically — single-threaded JS, so this is a copy. */ snapshot(): TransportMetricsSnapshot; } //# sourceMappingURL=transportMetrics.d.ts.map