Initial Commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# `telemetry`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
The telemetry module owns every OpenTelemetry instrument published by
|
||||
`@suaveplan/react-audio-stream`. Concentrating the OTel surface in one
|
||||
file means the session class never touches `@opentelemetry/api` and
|
||||
tests can verify call counts by spying on a single verb-shaped object
|
||||
instead of low-level meter handles. The shape matches Requirement 7 of
|
||||
the parent spec — two counters, a gauge, two more counters, and a
|
||||
histogram — so the runtime instrument set can be cross-checked against
|
||||
the spec on every change.
|
||||
|
||||
Every emission is no-op until a host registers an OTel SDK provider
|
||||
via `@suaveplan/opentelemetry`. The module-scope meter handles are
|
||||
cheap (one map lookup) so we can keep them at file scope without
|
||||
inflating cold-start cost.
|
||||
|
||||
## Features
|
||||
|
||||
- Counter `react_audio_stream_peer_connect_total{transport}`.
|
||||
- Counter `react_audio_stream_peer_disconnect_total{reason}`, where
|
||||
`reason` covers every `InterruptionClass` plus `explicit`.
|
||||
- UpDown counter `react_audio_stream_active_sessions` (gauge-equivalent
|
||||
via OTel's synchronous up/down counter).
|
||||
- Counter `react_audio_stream_reconnect_attempt_total`.
|
||||
- Counter `react_audio_stream_reconnect_failed_total`.
|
||||
- Histogram `react_audio_stream_rtt_ms{participant}` for the
|
||||
transport's RTT probe.
|
||||
- Verbs (`peerConnect`, `peerDisconnect`, …) keep call sites tidy and
|
||||
give tests one knob per spec requirement.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { streamTelemetry } from "@suaveplan/react-audio-stream";
|
||||
|
||||
streamTelemetry.peerConnect("webrtc");
|
||||
streamTelemetry.recordRtt("alice", 42);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { streamTelemetry } from "@suaveplan/react-audio-stream";
|
||||
|
||||
class ReconnectLadder {
|
||||
async run(verdict: InterruptionVerdict): Promise<void> {
|
||||
for (let attempt = 1; attempt <= this.max; attempt++) {
|
||||
streamTelemetry.reconnectAttempt();
|
||||
try {
|
||||
await this.session.connect(this.roomId);
|
||||
return;
|
||||
} catch {
|
||||
await this.backoff(attempt);
|
||||
}
|
||||
}
|
||||
streamTelemetry.reconnectFailed();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `interface StreamTelemetry` — verb surface consumed by the session.
|
||||
- `const streamTelemetry: StreamTelemetry` — singleton implementation.
|
||||
- `type DisconnectReason` — `"network" | "media-permission" |
|
||||
"signalling" | "peer" | "unknown" | "explicit"`.
|
||||
- `type TransportLabel` — `"webrtc" | "websocket" | "trystero" |
|
||||
"local"`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
OTel's `Gauge` requires async observable callbacks which complicates
|
||||
the testable verb surface; the spec wording reads as "gauge tracks
|
||||
active sessions" and OTel's `UpDownCounter` is the synchronous
|
||||
equivalent that satisfies the same semantics — every monitoring backend
|
||||
renders it as a gauge. The reason labels are constrained to the
|
||||
`DisconnectReason` union so a typo in the call site is a compile
|
||||
error rather than a silent cardinality leak. Transport labels are
|
||||
constrained the same way — adding a new transport in chunk B requires
|
||||
extending the union (one line) so backend dashboards stay in sync with
|
||||
the code automatically. The participant id is used as a histogram
|
||||
attribute even though it is high-cardinality because RTT samples are
|
||||
per-peer by nature; consumers wiring a low-cardinality backend
|
||||
(Prometheus) should drop the attribute via a view in their SDK
|
||||
configuration rather than us removing it here.
|
||||
Reference in New Issue
Block a user