@webex/internal-plugin-metrics 3.12.0-next.6 → 3.12.0-next.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.repo-context.json +466 -0
- package/.sdd/manifest.json +626 -0
- package/AGENTS.md +208 -0
- package/README.md +274 -0
- package/dist/automated-user.js +19 -0
- package/dist/automated-user.js.map +1 -0
- package/dist/batcher.js +3 -0
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +613 -53
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +240 -103
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +19 -4
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +118 -5
- package/dist/metrics.js.map +1 -1
- package/dist/metrics.types.js +4 -0
- package/dist/metrics.types.js.map +1 -1
- package/dist/network-telemetry.js +610 -0
- package/dist/network-telemetry.js.map +1 -0
- package/dist/new-metrics.js +63 -17
- package/dist/new-metrics.js.map +1 -1
- package/dist/privacy-and-security-permission-enricher/constants.js +18 -0
- package/dist/privacy-and-security-permission-enricher/constants.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/index.js +143 -0
- package/dist/privacy-and-security-permission-enricher/index.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/types.js +7 -0
- package/dist/privacy-and-security-permission-enricher/types.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/utils.js +71 -0
- package/dist/privacy-and-security-permission-enricher/utils.js.map +1 -0
- package/dist/types/automated-user.d.ts +2 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +200 -5
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +77 -17
- package/dist/types/call-diagnostic/config.d.ts +6 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/metrics.types.d.ts +11 -5
- package/dist/types/network-telemetry.d.ts +108 -0
- package/dist/types/new-metrics.d.ts +17 -1
- package/dist/types/privacy-and-security-permission-enricher/constants.d.ts +6 -0
- package/dist/types/privacy-and-security-permission-enricher/index.d.ts +40 -0
- package/dist/types/privacy-and-security-permission-enricher/types.d.ts +14 -0
- package/dist/types/privacy-and-security-permission-enricher/utils.d.ts +5 -0
- package/dist/types/unhandled-exception-telemetry/index.d.ts +60 -0
- package/dist/types/unhandled-exception-telemetry/utils.d.ts +6 -0
- package/dist/unhandled-exception-telemetry/index.js +331 -0
- package/dist/unhandled-exception-telemetry/index.js.map +1 -0
- package/dist/unhandled-exception-telemetry/utils.js +105 -0
- package/dist/unhandled-exception-telemetry/utils.js.map +1 -0
- package/docs/adr/index.md +27 -0
- package/docs/architecture.md +437 -0
- package/docs/getting-started.md +131 -0
- package/docs/index.md +52 -0
- package/docs/specs/README.md +88 -0
- package/package.json +12 -11
- package/schemas/repo-context.schema.json +796 -0
- package/src/automated-user.ts +16 -0
- package/src/batcher.js +4 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +737 -60
- package/src/call-diagnostic/call-diagnostic-metrics.ts +184 -42
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
- package/src/call-diagnostic/config.ts +16 -0
- package/src/call-diagnostic/docs/README.md +535 -0
- package/src/config.js +8 -0
- package/src/docs/README.md +703 -0
- package/src/index.ts +16 -0
- package/src/metrics.js +123 -5
- package/src/metrics.types.ts +29 -6
- package/src/network-telemetry.ts +757 -0
- package/src/new-metrics.ts +56 -6
- package/src/privacy-and-security-permission-enricher/constants.ts +33 -0
- package/src/privacy-and-security-permission-enricher/docs/README.md +356 -0
- package/src/privacy-and-security-permission-enricher/index.ts +142 -0
- package/src/privacy-and-security-permission-enricher/types.ts +21 -0
- package/src/privacy-and-security-permission-enricher/utils.ts +82 -0
- package/src/rtcMetrics/docs/README.md +447 -0
- package/src/unhandled-exception-telemetry/docs/README.md +536 -0
- package/src/unhandled-exception-telemetry/index.ts +404 -0
- package/src/unhandled-exception-telemetry/utils.ts +101 -0
- package/test/unit/spec/automated-user.ts +43 -0
- package/test/unit/spec/batcher.js +43 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +10 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1336 -131
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +1265 -207
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
- package/test/unit/spec/metrics.js +14 -5
- package/test/unit/spec/network-telemetry.ts +610 -0
- package/test/unit/spec/new-metrics.ts +203 -50
- package/test/unit/spec/prelogin-metrics-batcher.ts +71 -36
- package/test/unit/spec/privacy-and-security-permission-enricher.ts +318 -0
- package/test/unit/spec/unhandled-exception-telemetry/utils.ts +109 -0
- package/test/unit/spec/unhandled-exception-telemetry.ts +689 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Architecture
|
|
3
|
+
title: '@webex/internal-plugin-metrics architecture'
|
|
4
|
+
description: Repository-wide boundaries, resources, interactions, dependencies, and cross-cutting architecture.
|
|
5
|
+
tags: [architecture]
|
|
6
|
+
---
|
|
7
|
+
<!-- sdd-generated-metadata
|
|
8
|
+
doc_kind: standing-doc
|
|
9
|
+
generated_from: architecture@0.3.0
|
|
10
|
+
generated_by: claude-code
|
|
11
|
+
approved_by: rarajes2@cisco.com
|
|
12
|
+
updated_at: 2026-10-07T04:50:31Z
|
|
13
|
+
validation_status: pass
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
# @webex/internal-plugin-metrics architecture
|
|
17
|
+
|
|
18
|
+
Canonical repository-wide architecture. This document owns facts that span
|
|
19
|
+
multiple modules and the package's external boundaries. Link to
|
|
20
|
+
the owning module, ADR, or native contract instead of duplicating owner-local
|
|
21
|
+
detail.
|
|
22
|
+
|
|
23
|
+
Related context: [specification registry](specs/README.md) ·
|
|
24
|
+
[repository agent instructions](../AGENTS.md)
|
|
25
|
+
|
|
26
|
+
## Applicability
|
|
27
|
+
|
|
28
|
+
Sections preceded by an `Include if` comment are conditional. Retain a
|
|
29
|
+
conditional section only when repository evidence satisfies its condition.
|
|
30
|
+
|
|
31
|
+
| Condition ID | Status | Evidence or reason | Owned section |
|
|
32
|
+
| ------------------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
33
|
+
| `repo.owns_datastore` | N/A | No schema, migration, ORM or connection configuration exists; every aggregate is in-memory and discarded at the submission boundary | Repository data and schema |
|
|
34
|
+
| `repo.holds_client_state` | Applicable | `src/network-telemetry.ts`, `src/call-diagnostic/call-diagnostic-metrics-latencies.ts`, `src/unhandled-exception-telemetry/index.ts` | Client state model |
|
|
35
|
+
| `repo.components_interact` | Applicable | `src/new-metrics.ts` composes the four child modules; `src/metrics.js` subscribes to SDK request events | Dependency and interaction topology |
|
|
36
|
+
| `repo.domain_data_across_components` | Applicable | The event envelope declared in `src/metrics.types.ts` is written by `src/call-diagnostic/call-diagnostic-metrics.ts` and `src/privacy-and-security-permission-enricher/index.ts` and transported by `src/prelogin-metrics-batcher.ts` | Object and data ownership |
|
|
37
|
+
| `repo.caches_data` | Applicable | `src/call-diagnostic/call-diagnostic-metrics.ts` error `WeakMap`, memoized device id in `src/generic-metrics.ts`, memoized verdict in `src/automated-user.ts` | Caching catalog |
|
|
38
|
+
| `repo.observability_convention` | Applicable | Log-identifier prefixes in `src/call-diagnostic/config.ts`, `src/prelogin-metrics-batcher.ts`, `src/unhandled-exception-telemetry/index.ts` | Observability patterns |
|
|
39
|
+
| `repo.deploys_to_infra` | N/A | No Dockerfile, deployment manifest, process entry point or runtime configuration; the package runs inside a host SDK instance | Runtime and infrastructure |
|
|
40
|
+
| `repo.shared_base_libs` | Applicable | `src/metrics.js` and `src/batcher.js` extend base classes from `@webex/webex-core`; shared babel, eslint and jest presets in `package.json` | Shared and base libraries |
|
|
41
|
+
| `repo.is_monorepo` | N/A | The SDD root is one workspace package with one build and one published artifact; the surrounding monorepo is out of scope | Package map and dependencies |
|
|
42
|
+
| `repo.multi_platform` | Applicable | `src/config.js` selects `appType` from the browser check; `src/metrics.js`, `src/automated-user.ts` and `src/unhandled-exception-telemetry/index.ts` guard on `window` | Platform matrix |
|
|
43
|
+
| `repo.published_package` | Applicable | `package.json` declares `main`, `types` and `deploy:npm`; seven sibling workspace packages depend on it | Release and versioning |
|
|
44
|
+
| `repo.embedded_in_host` | Applicable | `src/index.ts` mounts two plugins into a host SDK instance and registers an `onBeforeLogout` lifecycle hook | Host integration and theming |
|
|
45
|
+
| `repo.exposes_commands_or_artifacts` | Applicable | `package.json` defines `build`, `build:src`, `test:unit` and `test:style`, producing the `dist/` artifact | Commands and generated artifacts |
|
|
46
|
+
| `repo.cross_repo_deps_material` | Applicable | The Call Analyzer event schema is owned externally by `@webex/event-dictionary-ts`, pinned in `package.json` | Cross-repository topology |
|
|
47
|
+
| `repo.security_arch_warranted` | Applicable | IP anonymization in `src/call-diagnostic/call-diagnostic-metrics.util.ts`, URL credential stripping in `src/unhandled-exception-telemetry/utils.ts`, unauthenticated pre-login transport in `src/prelogin-metrics-batcher.ts` | Security architecture |
|
|
48
|
+
|
|
49
|
+
## Design overview
|
|
50
|
+
|
|
51
|
+
This package is the Webex JS SDK's single telemetry boundary. Every other SDK plugin and every first
|
|
52
|
+
party client that needs to report something — a diagnostic event, a behavioural counter, a WebRTC
|
|
53
|
+
stats sample, an uncaught browser error, a request-failure summary — reaches it through one of two
|
|
54
|
+
registered internal plugins rather than talking to an ingestion service directly.
|
|
55
|
+
|
|
56
|
+
The package is shaped by three decisions visible in the code.
|
|
57
|
+
|
|
58
|
+
**Two façades, one transport layer.** `src/index.ts` registers `metrics` (`src/metrics.js`) and
|
|
59
|
+
`newMetrics` (`src/new-metrics.ts`). `metrics` is the older surface: a thin `WebexPlugin` that owns
|
|
60
|
+
the three `Batcher` children and the raw `submitClientMetrics` path. `newMetrics` is the current
|
|
61
|
+
surface and owns no transport of its own; it composes `src/call-diagnostic/`,
|
|
62
|
+
`src/privacy-and-security-permission-enricher/`, the tagged-event classes and
|
|
63
|
+
`src/unhandled-exception-telemetry/`, and each of those reaches the network through a `Batcher`
|
|
64
|
+
descendant of `src/batcher.js`. New callers use `newMetrics`; `metrics` remains because
|
|
65
|
+
`submitClientMetrics` is the only path that accepts a pre-login identifier and is the transport that
|
|
66
|
+
network and unhandled-exception telemetry reuse.
|
|
67
|
+
|
|
68
|
+
**Collection is decoupled from submission by an accumulate-then-flush window.** The two
|
|
69
|
+
self-driven collectors — `src/network-telemetry.ts` and `src/unhandled-exception-telemetry/` — do not
|
|
70
|
+
submit per event. They accumulate into an in-memory window keyed by an identity (host plus endpoint;
|
|
71
|
+
error fingerprint), then submit one aggregate on a timer. Both reset the window before the
|
|
72
|
+
asynchronous submission starts, so an event observed while a submission is in flight belongs to the
|
|
73
|
+
next window and cannot mutate a payload already being sent.
|
|
74
|
+
|
|
75
|
+
**Telemetry must never degrade what it observes.** No failure in this package propagates to a
|
|
76
|
+
caller's request path. `src/network-telemetry.ts` excludes the `metrics` and `unifiedTelemetry`
|
|
77
|
+
services centrally so an upload cannot appear in its own summary; every submission failure is caught
|
|
78
|
+
and logged; `src/batcher.js` re-enqueues with exponential backoff on network errors instead of
|
|
79
|
+
rejecting; and `src/privacy-and-security-permission-enricher/index.ts` returns the original payload
|
|
80
|
+
on any internal error. The same constraint drives the redaction rules: anonymized IP addresses,
|
|
81
|
+
stripped URL credentials and query data, and endpoint path segments replaced with a placeholder.
|
|
82
|
+
|
|
83
|
+
The package owns no HTTP surface and no datastore. Its boundaries are the SDK plugin registration
|
|
84
|
+
contract on one side and two upstream ingestion APIs on the other.
|
|
85
|
+
|
|
86
|
+
## Resource inventory and responsibilities
|
|
87
|
+
|
|
88
|
+
| Resource | Kind | Responsibility | Owner | Source | Detailed specification |
|
|
89
|
+
| ------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------- |
|
|
90
|
+
| Metrics plugin root | Module | Plugin registration, both façades, the batcher family, tagged-event metrics and SDK network telemetry | Cisco Webex JS SDK — telemetry | `src/index.ts` | `src/docs/README.md` |
|
|
91
|
+
| Call Analyzer diagnostics | Module | Client, feature and media-quality events, the latency ledger and error-code mapping | Cisco Webex JS SDK — telemetry | `src/call-diagnostic/call-diagnostic-metrics.ts` | `src/call-diagnostic/docs/README.md` |
|
|
92
|
+
| Privacy and security permission enrichment | Module | Deciding which browser permission changes are attached to which client events | Cisco Webex JS SDK — telemetry | `src/privacy-and-security-permission-enricher/index.ts` | `src/privacy-and-security-permission-enricher/docs/README.md` |
|
|
93
|
+
| WebRTC stats telemetry | Module | Queueing and submitting WCME stats batches with anonymized candidate addresses | Cisco Webex JS SDK — telemetry | `src/rtcMetrics/index.ts` | `src/rtcMetrics/docs/README.md` |
|
|
94
|
+
| Unhandled exception telemetry | Module | Capturing, deduplicating, sanitizing and submitting browser uncaught errors and rejections | Cisco Webex JS SDK — telemetry | `src/unhandled-exception-telemetry/index.ts` | `src/unhandled-exception-telemetry/docs/README.md` |
|
|
95
|
+
| Published npm package | Package | The `@webex/internal-plugin-metrics` artifact consumed by sibling plugins and first party clients | Cisco Webex JS SDK — telemetry | `package.json` | `src/docs/README.md` |
|
|
96
|
+
|
|
97
|
+
## Interaction and execution flows
|
|
98
|
+
|
|
99
|
+
The representative end-to-end flow is a Call Analyzer client event, because it crosses the most
|
|
100
|
+
boundaries: façade, latency ledger, permission enrichment, event construction, batching, transport.
|
|
101
|
+
|
|
102
|
+
```mermaid
|
|
103
|
+
flowchart LR
|
|
104
|
+
Caller[SDK plugin or first party client] --> NewMetrics[newMetrics facade]
|
|
105
|
+
NewMetrics --> Latencies[Latency ledger]
|
|
106
|
+
NewMetrics --> Enricher[Permission enricher]
|
|
107
|
+
Enricher --> CallDiag[Call Analyzer event builder]
|
|
108
|
+
CallDiag --> Batcher[Metrics batcher]
|
|
109
|
+
Batcher --> MetricsSvc[(Webex metrics service)]
|
|
110
|
+
Core[WebexCore request pipeline] -->|request:start / success / failure| NetTel[Network telemetry collector]
|
|
111
|
+
NetTel -->|every interval| LegacyMetrics[metrics facade]
|
|
112
|
+
LegacyMetrics --> Batcher
|
|
113
|
+
Window[Browser window] -->|error / unhandledrejection| ExcTel[Unhandled exception reporter]
|
|
114
|
+
ExcTel --> LegacyMetrics
|
|
115
|
+
Rtc[Media connection] --> RtcMetrics[WebRTC stats reporter]
|
|
116
|
+
RtcMetrics --> TelemetrySvc[(Webex unified telemetry service)]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| From | To | Interaction or transport | Purpose | Failure or compatibility behavior |
|
|
120
|
+
| -------------------------------------- | -------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
121
|
+
| SDK plugin or first party client | `newMetrics` façade | In-process method call on the registered plugin | Submit a diagnostic, behavioural, operational or business event | Submissions before the SDK `ready` event are logged and resolve without submitting |
|
|
122
|
+
| `newMetrics` façade | Permission enricher | In-process call | Attach changed browser permission state to eligible client events | Any internal error is handed to the injected handler and the original payload is returned unchanged |
|
|
123
|
+
| Call Analyzer event builder | Metrics batcher | Queued HTTP POST to the `metrics` service | Deliver diagnostic and feature events | Network errors re-enqueue with doubling delay up to the configured plateau; other errors reject the item |
|
|
124
|
+
| `WebexCore` request pipeline | Network telemetry collector | SDK-wide events `request:start`, `request:success`, `request:failure` | Aggregate request outcomes without wrapping `webex.request()` | Requests to the `metrics` and `unifiedTelemetry` services are excluded so telemetry cannot report on itself |
|
|
125
|
+
| Network telemetry collector | `metrics` façade | In-process callback at the window boundary | Submit one summary metric per interval | The window resets before submission; a failed submission is logged and that window's data is dropped |
|
|
126
|
+
| Browser window | Unhandled exception reporter | Capture-phase `error` and `unhandledrejection` listeners | Report uncaught errors and rejections | Matching errors within the one-second window merge into one event with an occurrence count |
|
|
127
|
+
| Media connection | WebRTC stats reporter | Direct HTTP POST to the `unifiedTelemetry` service | Deliver WCME stats batches | A failed media connection flushes the queue and starts a new connection identifier |
|
|
128
|
+
|
|
129
|
+
## Dependency topology
|
|
130
|
+
|
|
131
|
+
| Dependency | Type | Used by | Purpose | Version, failure, or fallback policy |
|
|
132
|
+
| ------------------------------- | -------- | -------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
133
|
+
| `@webex/webex-core` | Internal | `src/metrics.js`, `src/batcher.js`, `src/new-metrics.ts`, `src/generic-metrics.ts` | Plugin base classes, the batcher queue and retry machinery, HTTP error types, plugin registration | `workspace:*` in `package.json`; a breaking base-class change breaks registration at import time |
|
|
134
|
+
| `@webex/common` | Internal | `src/metrics.js`, `src/config.js`, `src/generic-metrics.ts` | Browser and OS detection, the browser-environment flag | `workspace:*`; detection values degrade to `unknown` rather than throwing |
|
|
135
|
+
| `@webex/common-timers` | Internal | `src/batcher.js`, `src/network-telemetry.ts`, `src/unhandled-exception-telemetry/index.ts` | Timers that survive the SDK's own clock handling | `workspace:*` |
|
|
136
|
+
| `@webex/event-dictionary-ts` | External | `src/metrics.types.ts` | The authoritative Call Analyzer event schema | Pinned `^1.0.2220` in `package.json`; a schema change surfaces as a TypeScript error at build time |
|
|
137
|
+
| `ip-anonymize` | External | `src/call-diagnostic/call-diagnostic-metrics.util.ts` | Truncating IPv4 and IPv6 addresses before submission | Pinned in `package.json`; a failure yields `undefined`, which drops the field |
|
|
138
|
+
| `isbot` | External | `src/automated-user.ts` | Classifying the user agent as automated | Pinned `5.2.1`; the verdict is memoized once per process |
|
|
139
|
+
| `lodash` | External | `src/new-metrics.ts`, `src/generic-metrics.ts`, `src/privacy-and-security-permission-enricher/utils.ts`, `src/prelogin-metrics-batcher.ts` | Deep merge, deep equality, clamping and unique identifiers | Pinned in `package.json` |
|
|
140
|
+
| `uuid` | External | `src/call-diagnostic/call-diagnostic-metrics.ts`, `src/rtcMetrics/index.ts`, `src/unhandled-exception-telemetry/index.ts` | Event, connection and pre-login identifiers | Pinned in `package.json` |
|
|
141
|
+
|
|
142
|
+
Ordering constraints and single points of failure:
|
|
143
|
+
|
|
144
|
+
- The package must be imported before a host SDK instance is constructed, or neither plugin is
|
|
145
|
+
registered. `src/index.ts` performs the registration as an import side effect.
|
|
146
|
+
- `src/generic-metrics.ts` resolves the device identifier from the device registration URL and
|
|
147
|
+
memoizes it. Until a device is registered, `isReadyToSubmitEvents` is false and the tagged-event
|
|
148
|
+
façades report not-ready rather than submitting an event with an empty device identifier.
|
|
149
|
+
- `src/metrics.js` and `src/generic-metrics.ts` form a deliberate one-way import: `generic-metrics`
|
|
150
|
+
imports the OS-name helper from `metrics`. Do not add the reverse edge.
|
|
151
|
+
- A circular dependency between this package and the device plugin is avoided by injection:
|
|
152
|
+
`setDeviceInfo` in `src/call-diagnostic/call-diagnostic-metrics.ts` is called by the device plugin
|
|
153
|
+
rather than this package importing it.
|
|
154
|
+
|
|
155
|
+
## Public and consumer surfaces
|
|
156
|
+
|
|
157
|
+
This is the repository contract index. Exact definitions remain in their native source.
|
|
158
|
+
|
|
159
|
+
| Surface | Type | Owner | Consumers | Compatibility policy | Source |
|
|
160
|
+
| ---------------------------------- | ----- | ------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------ |
|
|
161
|
+
| `metrics-package-entry` | SDK | Metrics plugin root | Any package importing `@webex/internal-plugin-metrics` | Internal plugin; additive. Removing a named export is breaking for workspace siblings | `src/index.ts` |
|
|
162
|
+
| `metrics-internal-plugin-sdk` | SDK | Metrics plugin root | `plugin-meetings`, `internal-plugin-device`, `internal-plugin-mercury`, this package's own telemetry collectors | Internal; retained for the pre-login transport path | `src/metrics.js` |
|
|
163
|
+
| `new-metrics-internal-plugin-sdk` | SDK | Metrics plugin root | `plugin-meetings`, `internal-plugin-scheduler`, `contact-center`, first party clients | Internal; the preferred surface for new callers | `src/new-metrics.ts` |
|
|
164
|
+
| `metrics-event-types` | SDK | Metrics plugin root | Consumers typing their own event payloads | Internal; derived from the external event dictionary rather than hand-declared | `src/metrics.types.ts` |
|
|
165
|
+
| `network-request-summary-metric` | Event | Metrics plugin root | Webex metrics ingestion and its dashboards | Internal wire contract; field removal or rename breaks ingestion | `src/network-telemetry.ts` |
|
|
166
|
+
| `call-diagnostic-event` | Event | Call Analyzer diagnostics | Webex Call Analyzer ingestion | Internal wire contract; the payload schema is owned externally | `src/call-diagnostic/call-diagnostic-metrics.ts` |
|
|
167
|
+
| `privacy-permission-enricher-sdk` | SDK | Privacy and security permission enrichment | `src/new-metrics.ts` only | Module-internal; not re-exported from `src/index.ts` | `src/privacy-and-security-permission-enricher/index.ts` |
|
|
168
|
+
| `rtc-metrics-payload` | Event | WebRTC stats telemetry | Webex unified telemetry ingestion | Internal wire contract; the payload declares its own `version` field | `src/rtcMetrics/index.ts` |
|
|
169
|
+
| `unhandled-exception-metric` | Event | Unhandled exception telemetry | Webex metrics ingestion | Internal wire contract; the payload declares `schemaVersion` | `src/unhandled-exception-telemetry/index.ts` |
|
|
170
|
+
| `webex-metrics-http` | API | Webex metrics service (external) | Every batcher in this package | Consumed, not owned; resources `metrics`, `clientmetrics`, `clientmetrics-prelogin` | `src/config.js` |
|
|
171
|
+
| `webex-unified-telemetry-http` | API | Webex unified telemetry service (external) | WebRTC stats telemetry | Consumed, not owned; resource `metric/v2` | `src/rtcMetrics/index.ts` |
|
|
172
|
+
| `webex-core-request-events` | Event | `@webex/webex-core` request pipeline (external) | Network telemetry | Consumed, not owned; no shared TypeScript contract, so telemetry declares a local structural type | `src/network-telemetry.ts` |
|
|
173
|
+
| `call-analyzer-event-schema` | File | Webex Call Analyzer (external) | `src/metrics.types.ts` | Consumed, not owned; pinned by version in `package.json` | `package.json` |
|
|
174
|
+
|
|
175
|
+
<!-- Include if: the repository holds client-side or in-memory session state. [condition-id: repo.holds_client_state] -->
|
|
176
|
+
|
|
177
|
+
## Client state model
|
|
178
|
+
|
|
179
|
+
Every slice below is in-memory and process-local. Nothing in this package is persisted, and no slice
|
|
180
|
+
survives a page reload.
|
|
181
|
+
|
|
182
|
+
| State or slice | Owner | Transition triggers | Persistence or reset boundary |
|
|
183
|
+
| -------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
184
|
+
| Network telemetry window | Metrics plugin root | `request:start`, `request:success`, `request:failure` | Replaced with an empty window at every interval boundary, manual flush and shutdown |
|
|
185
|
+
| In-flight submission set | Metrics plugin root | A window submission starts or settles | Awaited and drained by the shutdown path |
|
|
186
|
+
| Batcher queues and backoff state | Metrics plugin root | An item is enqueued, accepted, or re-enqueued after a network error | Per-item delay doubles up to the configured plateau; cleared on acceptance |
|
|
187
|
+
| Latency timestamp ledger | Call Analyzer diagnostics | Any client, feature or internal event name recorded through the façade | Cleared by the internal reset event; Locus sync records are pruned by age and capped per meeting |
|
|
188
|
+
| Delayed event queues | Call Analyzer diagnostics | Delay mode enabled, then disabled | Emptied when the delayed events are submitted |
|
|
189
|
+
| Event-limit counters | Call Analyzer diagnostics | A limited event name is submitted for a correlation identifier | Cleared wholesale, or per correlation identifier, by the public clear operations |
|
|
190
|
+
| Error payload cache | Call Analyzer diagnostics | A raw error is converted into an event error payload | A `WeakMap` keyed by the error object; also cleared explicitly |
|
|
191
|
+
| Per-scope permission history | Privacy and security permission enrichment | A client event is enriched | Deleted for that scope when a terminal call event is enriched |
|
|
192
|
+
| WebRTC metrics queue | WebRTC stats telemetry | A stats item is added | Emptied on submission, on connection failure and on close |
|
|
193
|
+
| Pending exception events | Unhandled exception telemetry | An uncaught error or rejection is captured | Submitted and removed when its one-second window expires; cleared on teardown |
|
|
194
|
+
|
|
195
|
+
## Cross-cutting architecture
|
|
196
|
+
|
|
197
|
+
### Security
|
|
198
|
+
|
|
199
|
+
- Trust boundaries and identity flow: the package sits entirely inside the host SDK's trust
|
|
200
|
+
boundary and holds no credentials of its own. Authenticated submissions inherit the host's
|
|
201
|
+
credentials through `webex.request`. One path is deliberately unauthenticated:
|
|
202
|
+
`src/prelogin-metrics-batcher.ts` posts to the pre-login resource with `authorization: false` and
|
|
203
|
+
an `x-prelogin-userid` header, and refuses to submit at all when no pre-login identifier is set.
|
|
204
|
+
- Sensitive surfaces and data classes: telemetry payloads are the only sensitive surface. Three
|
|
205
|
+
redaction controls are enforced in code — IP anonymization in
|
|
206
|
+
`src/call-diagnostic/call-diagnostic-metrics.util.ts`, URL credential, query and fragment removal
|
|
207
|
+
plus non-HTTP scheme redaction in `src/unhandled-exception-telemetry/utils.ts`, and endpoint path
|
|
208
|
+
segment replacement in `src/network-telemetry.ts`.
|
|
209
|
+
- Encryption and secret boundaries: transport-level only. The package performs no cryptography and
|
|
210
|
+
reads no secret; its sole environment input is the optional pre-discovery service URL override in
|
|
211
|
+
`src/config.js`.
|
|
212
|
+
|
|
213
|
+
### Observability and operations
|
|
214
|
+
|
|
215
|
+
- Logging and correlation: every module logs through the host SDK logger with a module-specific
|
|
216
|
+
prefix constant, so telemetry lines can be filtered by family. Call Analyzer additionally emits a
|
|
217
|
+
milestone line per event name from `src/call-diagnostic/call-diagnostic-metrics.util.ts`.
|
|
218
|
+
- Metrics, traces, and audit signals: this package is the SDK's metrics producer rather than a
|
|
219
|
+
consumer of one. Its own health is observable through the batch-submission success and failure
|
|
220
|
+
log lines in `src/call-diagnostic/call-diagnostic-metrics-batcher.ts` and
|
|
221
|
+
`src/prelogin-metrics-batcher.ts`, and through the two SDK-emitted summary metrics it owns.
|
|
222
|
+
Correlation across a call uses the Call Analyzer correlation identifier; WebRTC batches carry
|
|
223
|
+
their own connection identifier.
|
|
224
|
+
- Ownership and operational entry points: ingestion, dashboards and alerting belong to the Webex
|
|
225
|
+
metrics and Call Analyzer services, not to this repository. There is no runbook here because the
|
|
226
|
+
package has no runtime of its own.
|
|
227
|
+
|
|
228
|
+
### Quality attributes
|
|
229
|
+
|
|
230
|
+
Stated as SDK footprint and compatibility boundaries, which is the form that fits a library plugin:
|
|
231
|
+
|
|
232
|
+
- Bounded memory per window. Tracking identifiers per error aggregate are capped at ten in
|
|
233
|
+
`src/network-telemetry.ts`; Locus sync records are capped per meeting and dataset and pruned by a
|
|
234
|
+
time-to-live in `src/call-diagnostic/call-diagnostic-metrics-latencies.ts`; the deduplication map
|
|
235
|
+
in `src/unhandled-exception-telemetry/index.ts` holds at most one event per distinct fingerprint
|
|
236
|
+
per window.
|
|
237
|
+
- Bounded cardinality. Endpoint normalization in `src/network-telemetry.ts` replaces
|
|
238
|
+
dynamic-looking path segments so the per-endpoint aggregate cannot grow with the number of
|
|
239
|
+
resource identifiers observed.
|
|
240
|
+
- Non-blocking by construction. No collection path awaits a submission; no submission failure
|
|
241
|
+
reaches a caller.
|
|
242
|
+
- Additive public surface. Both plugin façades are consumed by sibling workspace packages, so an
|
|
243
|
+
export or payload-field removal is a breaking change for the monorepo.
|
|
244
|
+
|
|
245
|
+
<!-- Include if: repository resources call, import, or exchange events with one another. [condition-id: repo.components_interact] -->
|
|
246
|
+
|
|
247
|
+
## Dependency and interaction topology
|
|
248
|
+
|
|
249
|
+
```mermaid
|
|
250
|
+
flowchart LR
|
|
251
|
+
Index[src/index.ts] -->|registers| Legacy[src/metrics.js]
|
|
252
|
+
Index -->|registers| New[src/new-metrics.ts]
|
|
253
|
+
New -->|composes| CallDiag[src/call-diagnostic/]
|
|
254
|
+
New -->|composes| Enricher[src/privacy-and-security-permission-enricher/]
|
|
255
|
+
New -->|starts on ready| ExcTel[src/unhandled-exception-telemetry/]
|
|
256
|
+
New -->|composes| Tagged[Tagged event classes]
|
|
257
|
+
Legacy -->|owns| Batchers[Batcher family]
|
|
258
|
+
Legacy -->|creates| NetTel[src/network-telemetry.ts]
|
|
259
|
+
CallDiag -->|uses| Batchers
|
|
260
|
+
Tagged -->|uses| Batchers
|
|
261
|
+
ExcTel -->|calls submitClientMetrics| Legacy
|
|
262
|
+
NetTel -->|callback| Legacy
|
|
263
|
+
RtcMetrics[src/rtcMetrics/] -->|uses anonymizeIPAddress| CallDiag
|
|
264
|
+
Tagged -->|imports OS helper| Legacy
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
| From | To | Kind | Purpose | Ordering or failure boundary |
|
|
268
|
+
| ------------------------------------------ | ------------------------------------------ | ------ | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
269
|
+
| `src/index.ts` | Metrics plugin root | Import | Register both plugins and define the export surface | Must run before the host SDK instance is constructed |
|
|
270
|
+
| `src/new-metrics.ts` | Call Analyzer diagnostics | Call | Build and submit client, feature and media-quality events | Constructed eagerly in the façade constructor |
|
|
271
|
+
| `src/new-metrics.ts` | Privacy and security permission enrichment | Call | Enrich eligible client events before they are built | Synchronous; enrichment-body errors go to the injected handler, while a throwing policy resolver or handler propagates |
|
|
272
|
+
| `src/new-metrics.ts` | Unhandled exception telemetry | Call | Start the browser reporter | Deferred until the SDK emits `ready`; a later start supersedes and flushes the previous reporter |
|
|
273
|
+
| `src/new-metrics.ts` | Tagged event classes | Call | Submit behavioural, operational and business events | Built lazily on first use, and only after the SDK is ready |
|
|
274
|
+
| Unhandled exception telemetry | Metrics plugin root | Call | Reuse `submitClientMetrics` as the transport | Missing transport is logged and the event is dropped |
|
|
275
|
+
| Network telemetry | Metrics plugin root | Call | Submit the completed window | Window reset precedes submission so the two cannot interleave |
|
|
276
|
+
| WebRTC stats telemetry | Call Analyzer diagnostics | Import | Reuse the IP anonymization helper | Pure utility import; no instance dependency |
|
|
277
|
+
| Tagged event classes | Metrics plugin root | Import | Reuse the OS-name helper | One-way only; the reverse edge would be circular |
|
|
278
|
+
|
|
279
|
+
<!-- Include if: repository-owned domain data spans multiple resources. [condition-id: repo.domain_data_across_components] -->
|
|
280
|
+
|
|
281
|
+
## Object and data ownership
|
|
282
|
+
|
|
283
|
+
| Object or state | System of record | May write | May read | Movement or lifecycle |
|
|
284
|
+
| ------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
285
|
+
| Call Analyzer event envelope | Call Analyzer diagnostics | Call Analyzer diagnostics; the permission enricher adds one payload field | The batchers, which stamp origin and send time | Built per submission, enriched, batched, posted, then discarded |
|
|
286
|
+
| Client metric payload | Metrics plugin root | Metrics plugin root | The client-metrics batchers | Built per submission from host configuration and browser detection, then posted |
|
|
287
|
+
| Latency timestamp ledger | Call Analyzer diagnostics | Call Analyzer diagnostics only | The batcher preparation step, which derives join times | Accumulated across a call, read at submission time, reset by the internal reset event |
|
|
288
|
+
| Browser permission snapshot | Privacy and security permission enrichment | The façade, through the public setter | The enricher only | Supplied by the client, projected to the three known resources, diffed per scope, cleared on call end |
|
|
289
|
+
| Device identifier | `@webex/webex-core` device registration | Not writable here | Tagged event classes, via a memoized read | Read once from the device registration URL and cached for the process lifetime |
|
|
290
|
+
| Pre-login identifier | The caller | The pre-login batchers, through their save operation | The pre-login batchers | Set before the first pre-login submission; a submission with none set is rejected |
|
|
291
|
+
|
|
292
|
+
<!-- Include if: the repository caches data. [condition-id: repo.caches_data] -->
|
|
293
|
+
|
|
294
|
+
## Caching catalog
|
|
295
|
+
|
|
296
|
+
| Cache | Owner | Backend | Contents | TTL or bound | Invalidation trigger | Failure behavior |
|
|
297
|
+
| ---------------------------- | ------------------------- | ----------------------- | ------------------------------------------------------ | ------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------- |
|
|
298
|
+
| Event error payload cache | Call Analyzer diagnostics | `WeakMap` keyed by error | The generated error payload for a raw error object | Bounded by garbage collection of the key | The explicit clear operation | A miss regenerates the payload; the cached flag is reported |
|
|
299
|
+
| Device identifier memo | Tagged event classes | Instance field | The identifier parsed from the device registration URL | Process lifetime of the instance | None; recomputed only while still empty | An empty value keeps the readiness probe false |
|
|
300
|
+
| Automated-user verdict memo | Metrics plugin root | Module-level variable | Whether the current user agent is automated | Process lifetime | None | Absent browser globals resolve the verdict to false |
|
|
301
|
+
| Browser-serial log guard | Call Analyzer diagnostics | Instance flag | Whether browser data has already been logged | Instance lifetime | None | None; the guard only suppresses repeat logging |
|
|
302
|
+
|
|
303
|
+
<!-- Include if: the repository has logging, metrics, tracing, or audit conventions worth standardizing. [condition-id: repo.observability_convention] -->
|
|
304
|
+
|
|
305
|
+
## Observability patterns
|
|
306
|
+
|
|
307
|
+
| Signal | Convention or required fields | Propagation or naming rule | Primary evidence |
|
|
308
|
+
| ------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
309
|
+
| Logs | Host SDK logger only. Every family prefixes its lines with a module constant, and errors are serialized through one shared helper | Prefix constants are declared once per module and reused; error objects are stringified to message, name and stack | `src/call-diagnostic/config.ts` |
|
|
310
|
+
| Metrics | Submitted metrics carry a metric name, a type tag list, a timestamp and a context block with application, locale and OS details | Metric names are screaming-snake-case constants declared beside their producer; tagged events compose a dotted name | `src/generic-metrics.ts` |
|
|
311
|
+
| Traces | No tracing instrumentation. Correlation is carried by event identifiers instead | Call Analyzer uses the correlation identifier; WebRTC batches carry a connection identifier; requests carry a tracking identifier | `src/network-telemetry.ts` |
|
|
312
|
+
| Audit | No audit log. Submission attempts are observable through per-batch success and failure log lines carrying a generated batch identifier | Each batch logs once on success and once on failure, with the batch identifier in both lines | `src/prelogin-metrics-batcher.ts` |
|
|
313
|
+
|
|
314
|
+
<!-- Include if: modules inherit a shared or base library stack. [condition-id: repo.shared_base_libs] -->
|
|
315
|
+
|
|
316
|
+
## Shared and base libraries
|
|
317
|
+
|
|
318
|
+
| Library | Inherited responsibility | Consumers | Version floor | Compatibility rule |
|
|
319
|
+
| ---------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------- |
|
|
320
|
+
| `@webex/webex-core` | `WebexPlugin`, `StatelessWebexPlugin`, `Batcher`, `WebexHttpError`, plugin registration | `src/metrics.js`, `src/batcher.js`, `src/new-metrics.ts`, `src/generic-metrics.ts` | `workspace:*` | Base-class and registration changes are breaking at import time |
|
|
321
|
+
| `@webex/common` | Browser and OS detection, the browser-environment flag | `src/metrics.js`, `src/config.js`, `src/generic-metrics.ts` | `workspace:*` | Detection results degrade to `unknown` rather than throwing |
|
|
322
|
+
| `@webex/common-timers` | Timers resilient to the SDK's clock handling | `src/batcher.js`, `src/network-telemetry.ts`, `src/unhandled-exception-telemetry/index.ts` | `workspace:*` | Used wherever a timer must outlive throttling |
|
|
323
|
+
| `@webex/eslint-config-legacy` | The repository lint and style ruleset | All of `src/`, via `.eslintrc.js` | `workspace:*` | Markdown is not linted, so generated docs do not affect `test:style` |
|
|
324
|
+
| `@webex/babel-config-legacy` | Transpilation preset | The build, via `babel.config.js` | `workspace:*` | Shared monorepo preset; not overridden here |
|
|
325
|
+
| `@webex/legacy-tools` | The build and unit-test runners invoked by `package.json` scripts | `build:src` and `test:unit` | `workspace:*` | Runner flags such as `--targets` come from this package |
|
|
326
|
+
|
|
327
|
+
<!-- Include if: the repository targets multiple runtime or host platforms. [condition-id: repo.multi_platform] -->
|
|
328
|
+
|
|
329
|
+
## Platform matrix
|
|
330
|
+
|
|
331
|
+
| Platform | Shared versus platform-specific boundary | Entry or build | Support and compatibility constraints |
|
|
332
|
+
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
333
|
+
| Browser | All collection and submission paths are available. `src/config.js` reports the browser application type, and the browser-only reporter and WebRTC collector run here | `dist/index.js` from `src/index.ts` | Browser globals are read defensively; the package must not assume a document is present at import time |
|
|
334
|
+
| Node.js | Submission paths are available; browser-only collection is not. The unhandled-exception reporter does not install listeners and browser-derived payload fields fall back to non-browser placeholders | `dist/index.js` from `src/index.ts` | `engines` requires `>=18`; WebRTC stats telemetry uses a browser interval and is not a Node.js surface |
|
|
335
|
+
|
|
336
|
+
<!-- Include if: the repository publishes a package or consumer artifact. [condition-id: repo.published_package] -->
|
|
337
|
+
|
|
338
|
+
## Release and versioning
|
|
339
|
+
|
|
340
|
+
| Artifact | Publish target | Versioning rule | Deprecation window | Changelog or migration obligation |
|
|
341
|
+
| ----------------------------------- | -------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
342
|
+
| `@webex/internal-plugin-metrics` | npm | Released with the monorepo; as an internal plugin it does not strictly follow semantic versioning | None promised. Removing an export or payload field requires coordinating the seven dependent workspace packages first | Changelogs are produced centrally by the monorepo release tooling; this package owns none |
|
|
343
|
+
| `dist/` and `dist/types/` | npm tarball | Regenerated by `build:src` from `src/`; never edited by hand | Not applicable | `main` and `types` in `package.json` are the contract for consumers |
|
|
344
|
+
|
|
345
|
+
<!-- Include if: the repository is embedded in a host application. [condition-id: repo.embedded_in_host] -->
|
|
346
|
+
|
|
347
|
+
## Host integration and theming
|
|
348
|
+
|
|
349
|
+
| Host or integration | Mount or entry contract | Required providers or peers | Theming and accessibility constraints |
|
|
350
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
351
|
+
| `WebexCore` SDK | `src/index.ts` registers `metrics` and `newMetrics` as internal plugins, each with the shared config, and attaches an `onBeforeLogout` hook that stops network telemetry | `@webex/webex-core`; a registered device for tagged events; host configuration under the `metrics` namespace | Not applicable — the package renders nothing and owns no user interface |
|
|
352
|
+
|
|
353
|
+
<!-- Include if: the repository exposes commands, generators, or stable file outputs. [condition-id: repo.exposes_commands_or_artifacts] -->
|
|
354
|
+
|
|
355
|
+
## Commands and generated artifacts
|
|
356
|
+
|
|
357
|
+
| Command or artifact | Owner | Inputs | Output or side effect | Compatibility boundary |
|
|
358
|
+
| ------------------- | -------------------- | -------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
|
|
359
|
+
| `build:src` | `package.json` | `src/`, `tsconfig.json`, `babel.config.js` | `dist/` JavaScript with source maps, then `dist/types` declarations | Produces the published artifact; `main` and `types` must keep resolving |
|
|
360
|
+
| `build` | `package.json` | `src/`, `tsconfig.json` | `dist/types` declarations only | Declaration output is the typed consumer contract |
|
|
361
|
+
| `test:unit` | `package.json` | `test/unit/spec/` | Mocha results; accepts `--targets` relative to the spec directory | No coverage threshold is enforced |
|
|
362
|
+
| `test:style` | `package.json` | `src/`, `.eslintrc.js` | ESLint findings over `src/` only | Does not lint `test/` or Markdown |
|
|
363
|
+
| `deploy:npm` | `package.json` | `dist/` | Publishes the package to npm | Release is coordinated by the monorepo, not invoked per package by contributors |
|
|
364
|
+
| `dist/` | The build | `src/` | The published build output; git-ignored | Never edit by hand; regenerate with `build:src` |
|
|
365
|
+
|
|
366
|
+
<!-- Include if: cross-repository dependencies materially affect behavior or delivery. [condition-id: repo.cross_repo_deps_material] -->
|
|
367
|
+
|
|
368
|
+
## Cross-repository topology
|
|
369
|
+
|
|
370
|
+
| Repository or external system | Relationship | Exchanged contract or artifact | Owner | Sequencing constraint |
|
|
371
|
+
| --------------------------------- | ------------ | ---------------------------------------------------------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------- |
|
|
372
|
+
| Webex Call Analyzer event schema | Consumes | `@webex/event-dictionary-ts`, the authoritative event-name and payload definition | Webex Call Analyzer | A new event name is usable here only after the dictionary version in `package.json` is bumped |
|
|
373
|
+
| Webex metrics service | Consumes | HTTP ingestion for the `metrics`, `clientmetrics` and `clientmetrics-prelogin` resources | Webex metrics service | Ingestion must accept a payload field before this package emits it |
|
|
374
|
+
| Webex unified telemetry service | Consumes | HTTP ingestion for the `metric/v2` resource with the `webrtcMedia` type | Webex unified telemetry service | The application identifier header is a fixed registered value in `src/rtcMetrics/constants.ts` |
|
|
375
|
+
| Webex JS SDK sibling packages | Provides | Both plugin façades, consumed in-process after registration | Cisco Webex JS SDK | A breaking surface change must land with its consumers in the same monorepo change |
|
|
376
|
+
|
|
377
|
+
<!-- Include if: trust boundaries or identity flows warrant a dedicated architectural view. [condition-id: repo.security_arch_warranted] -->
|
|
378
|
+
|
|
379
|
+
## Security architecture
|
|
380
|
+
|
|
381
|
+
The package has one inbound trust boundary and two outbound ones. Inbound, it accepts payloads from
|
|
382
|
+
in-process SDK callers inside the host's trust boundary; it does not validate them as untrusted
|
|
383
|
+
input, but it does sanitize everything derived from the environment — error text, resource paths,
|
|
384
|
+
URLs and IP addresses — before those values leave the process. Outbound, authenticated submissions
|
|
385
|
+
inherit the host's credentials, and one path is intentionally unauthenticated so that telemetry can
|
|
386
|
+
be attributed to a user before sign-in.
|
|
387
|
+
|
|
388
|
+
```mermaid
|
|
389
|
+
flowchart LR
|
|
390
|
+
Caller[In-process SDK caller] -->|event payload| Plugin[Metrics plugin]
|
|
391
|
+
Env[Browser environment] -->|error text, URLs, IP addresses| Redact[Redaction helpers]
|
|
392
|
+
Redact --> Plugin
|
|
393
|
+
Plugin -->|host credentials| MetricsSvc[Webex metrics service]
|
|
394
|
+
Plugin -->|authorization false plus x-prelogin-userid| PreLogin[Pre-login metrics resource]
|
|
395
|
+
Plugin -->|host credentials| TelemetrySvc[Webex unified telemetry service]
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Architectural controls, each enforced in code rather than by convention:
|
|
399
|
+
|
|
400
|
+
- Pre-login submission refuses to send when no pre-login identifier has been set, so an
|
|
401
|
+
unauthenticated request is never made without its attribution header.
|
|
402
|
+
- Non-HTTP and HTTP(S) URLs are treated differently on purpose: non-HTTP schemes, which can embed
|
|
403
|
+
inline payloads, are replaced wholesale, while HTTP(S) URLs keep only scheme, host and path.
|
|
404
|
+
- Endpoint normalization is heuristic, which is a deliberate accepted limitation: requests do not
|
|
405
|
+
supply route templates, so a short lowercase segment can survive as if it were a static route.
|
|
406
|
+
Callers must therefore not place sensitive values in resource paths or thrown error messages.
|
|
407
|
+
- The telemetry self-exclusion rule is centralized in the collector rather than delegated to call
|
|
408
|
+
sites, so a new telemetry transport cannot forget to opt out.
|
|
409
|
+
|
|
410
|
+
The authoritative Webex security policy lives at the `webex-js-sdk` repository root rather than in
|
|
411
|
+
this package.
|
|
412
|
+
|
|
413
|
+
## Domain language
|
|
414
|
+
|
|
415
|
+
| Term | Repository-specific meaning | Authoritative source |
|
|
416
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
|
|
417
|
+
| Client event | A Call Analyzer diagnostic event describing a client-side milestone or failure in a call | `src/metrics.types.ts` |
|
|
418
|
+
| Feature event | A Call Analyzer event describing feature usage, submitted as a business-typed envelope rather than a diagnostic one | `src/call-diagnostic/call-diagnostic-metrics.ts` |
|
|
419
|
+
| Media quality event | A periodic Call Analyzer event carrying media interval statistics, exempt from the empty-key sanitization applied to other events | `src/call-diagnostic/call-diagnostic-metrics.ts` |
|
|
420
|
+
| Tagged event | A behavioural, operational or business metric built as a metric name plus tag map, rather than as a Call Analyzer envelope | `src/generic-metrics.ts` |
|
|
421
|
+
| Client metric | The lower-level payload posted to the client-metrics resource, carrying tags, fields, context and an optional event payload | `src/metrics.js` |
|
|
422
|
+
| Pre-login identifier | A caller-supplied identifier that lets telemetry be attributed before sign-in, sent as a header on the unauthenticated resource | `src/prelogin-metrics-batcher.ts` |
|
|
423
|
+
| Correlation identifier | The Call Analyzer identity for one call, used to scope latency records, event limits and permission history | `src/call-diagnostic/call-diagnostic-metrics.ts` |
|
|
424
|
+
| Reporting window | The accumulation period after which a collector submits one aggregate and starts a fresh accumulator | `src/network-telemetry.ts` |
|
|
425
|
+
| Fingerprint | The stable hash of an error's identifying fields, used only to deduplicate exception reports within a window | `src/unhandled-exception-telemetry/utils.ts` |
|
|
426
|
+
| Endpoint | A request's resource path after query data removal and identifier-segment replacement, used as an aggregation key | `src/network-telemetry.ts` |
|
|
427
|
+
| Delayed submission | Holding built client or feature events in memory until the caller disables delay mode, preserving each event's original trigger time | `src/new-metrics.ts` |
|
|
428
|
+
|
|
429
|
+
## References and maintenance
|
|
430
|
+
|
|
431
|
+
- Decisions: [adr/](adr/)
|
|
432
|
+
- Instantiated specifications and routing: [specs/README.md](specs/README.md)
|
|
433
|
+
- Repository rules and patterns: [repository agent instructions](../AGENTS.md); lint rules in
|
|
434
|
+
`.eslintrc.js`; the published package overview in [README.md](../README.md)
|
|
435
|
+
- Update this document in the same change that alters repository boundaries,
|
|
436
|
+
resource ownership, cross-resource interaction, or cross-cutting
|
|
437
|
+
architecture.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Getting Started
|
|
3
|
+
title: Getting started
|
|
4
|
+
description: Local setup, build, run, and test routing for @webex/internal-plugin-metrics.
|
|
5
|
+
tags: [onboarding]
|
|
6
|
+
---
|
|
7
|
+
<!-- sdd-generated-metadata
|
|
8
|
+
doc_kind: standing-doc
|
|
9
|
+
generated_from: getting-started@0.3.0
|
|
10
|
+
generated_by: claude-code
|
|
11
|
+
approved_by: rarajes2@cisco.com
|
|
12
|
+
updated_at: 2026-10-07T04:50:31Z
|
|
13
|
+
validation_status: pass
|
|
14
|
+
-->
|
|
15
|
+
|
|
16
|
+
# Getting started
|
|
17
|
+
|
|
18
|
+
Onboarding for **@webex/internal-plugin-metrics**, a workspace package of the `webex-js-sdk`
|
|
19
|
+
monorepo. Every command below is run from the monorepo root.
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
| Tool or access | Version or requirement |
|
|
24
|
+
| -------------------------------------- | ----------------------------------------------------------------------------- |
|
|
25
|
+
| Node.js | `22.14` for building and testing, as declared by the repository owner in `.sdd/manifest.json` `toolchain`; `>=18` from `engines` in `package.json` is the consumer runtime floor |
|
|
26
|
+
| Yarn | The monorepo's Yarn workspaces; dependencies use the `workspace:*` protocol |
|
|
27
|
+
| Registry or VPN access | Public npm only. The package declares no `.npmrc` and no authenticated registry |
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/webex/webex-js-sdk.git
|
|
33
|
+
yarn install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Consumers outside the monorepo install the published package with:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install --save @webex/internal-plugin-metrics
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Build
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
yarn workspace @webex/internal-plugin-metrics build:src
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`build:src` transpiles `src/` to `dist/` and then runs `build`, which emits type declarations to
|
|
49
|
+
`dist/types`. Run `yarn workspace @webex/internal-plugin-metrics build` alone for declarations only.
|
|
50
|
+
|
|
51
|
+
## Run
|
|
52
|
+
|
|
53
|
+
Not applicable. This package is a library plugin with no runnable entry point. It becomes active by
|
|
54
|
+
being imported before a `WebexCore` instance is constructed, which registers
|
|
55
|
+
`webex.internal.metrics` and `webex.internal.newMetrics`:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
import '@webex/internal-plugin-metrics';
|
|
59
|
+
|
|
60
|
+
import WebexCore from '@webex/webex-core';
|
|
61
|
+
|
|
62
|
+
const webex = new WebexCore();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Tests
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
yarn workspace @webex/internal-plugin-metrics test:unit
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Use the table as the repository-level test router. List only tiers that
|
|
72
|
+
actually exist; behavioral intent belongs in the owning module specifications and exact
|
|
73
|
+
cases remain in the repository's native test sources.
|
|
74
|
+
|
|
75
|
+
| Tier | Command | Test location | Framework | External dependencies |
|
|
76
|
+
| ------------ | ------------------------------------------------------------------ | ----------------- | --------- | --------------------- |
|
|
77
|
+
| Unit | `yarn workspace @webex/internal-plugin-metrics test:unit` | `test/unit/spec` | Mocha | None |
|
|
78
|
+
| Integration | Not applicable — the package defines no `test:integration` script and has no `test/integration` directory | — | — | — |
|
|
79
|
+
| System / E2E | Not applicable — the package defines no `test:browser` script | — | — | — |
|
|
80
|
+
|
|
81
|
+
Run one spec with `--targets`, relative to `test/unit/spec/`. Run the focused unit tests with
|
|
82
|
+
Node.js 22.14, the declared toolchain version; with nvm, switch first using `nvm use 22.14`:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
yarn workspace @webex/internal-plugin-metrics test:unit --targets network-telemetry.ts
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- Coverage or quality gate: none. The package's Mocha run enforces no threshold and defines no
|
|
89
|
+
`test:coverage` script, so the monorepo CI coverage job never reaches this workspace.
|
|
90
|
+
`.sdd/manifest.json` records this as `quality_gates.code_coverage.origin: none`.
|
|
91
|
+
- Enforcement source: lint only, through `test:style` (`eslint ./src/**/*.*`) configured by
|
|
92
|
+
`.eslintrc.js`.
|
|
93
|
+
- Test environment or QA dependencies: none. Every spec runs in-process against
|
|
94
|
+
`@webex/test-helper-mock-webex`.
|
|
95
|
+
|
|
96
|
+
The `test` script in `package.json` is not a working gate: it chains `test:integration` and
|
|
97
|
+
`test:browser`, which this package does not define. `.sdd/manifest.json` records `commands.build`
|
|
98
|
+
as an unresolved owner decision for that reason.
|
|
99
|
+
|
|
100
|
+
## Configuration and secrets
|
|
101
|
+
|
|
102
|
+
- Required configuration: none to build or test. At runtime the plugin reads its own defaults from
|
|
103
|
+
`src/config.js`; both telemetry features it gates (`metrics.unhandledExceptionTelemetry.enabled`
|
|
104
|
+
and `metrics.networkTelemetry.enabled`) default to `false`.
|
|
105
|
+
- Secret source: none. The package holds no credentials and reads only
|
|
106
|
+
`process.env.METRICS_SERVICE_URL`, an optional pre-discovery service override in `src/config.js`.
|
|
107
|
+
- Package or artifact access: public npm. `@webex/event-dictionary-ts` is the one external runtime
|
|
108
|
+
dependency pinned in `package.json`.
|
|
109
|
+
- Required neighboring repositories or workspace layout: none beyond the monorepo itself. The
|
|
110
|
+
package depends on the `@webex/webex-core`, `@webex/common` and `@webex/common-timers` workspace
|
|
111
|
+
siblings, which `yarn install` links.
|
|
112
|
+
- Platform, simulator, device, or SDK setup: none. Browser-only behavior is guarded at runtime, so
|
|
113
|
+
the unit suite runs under Node.js.
|
|
114
|
+
- Never commit credentials or copy production secrets into a local config.
|
|
115
|
+
|
|
116
|
+
## First-run verification
|
|
117
|
+
|
|
118
|
+
1. Run `yarn workspace @webex/internal-plugin-metrics build:src`.
|
|
119
|
+
2. Check that `dist/index.js` and `dist/types/index.d.ts` exist, matching the `main` and `types`
|
|
120
|
+
fields in `package.json`.
|
|
121
|
+
3. Run `yarn workspace @webex/internal-plugin-metrics test:unit --targets network-telemetry.ts`.
|
|
122
|
+
|
|
123
|
+
Expected result: the build emits `dist/` without errors and the focused spec passes, exercising the
|
|
124
|
+
request-outcome collector end to end against the mocked SDK.
|
|
125
|
+
|
|
126
|
+
## Next steps
|
|
127
|
+
|
|
128
|
+
- [Repository architecture](architecture.md)
|
|
129
|
+
- Service specification — not applicable for this package
|
|
130
|
+
- [Specification registry](specs/README.md)
|
|
131
|
+
- [Documentation index](index.md)
|