@webex/internal-plugin-metrics 3.12.0-auth-prejoin-fetch.1 → 3.12.0-llmrefactor.10

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.
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_commonTimers","require","_createForOfIteratorHelper","r","e","t","_Symbol","_Symbol$iterator","_Array$isArray","_unsupportedIterableToArray","length","_n","F","s","n","done","value","f","TypeError","o","a","u","call","next","return","_arrayLikeToArray","toString","slice","constructor","name","_Array$from","test","Array","ownKeys","_Object$keys","_Object$getOwnPropertySymbols","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","NETWORK_REQUEST_SUMMARY_METRIC","exports","NETWORK_TELEMETRY_INTERVAL_MS","SAFE_ROUTE_SEGMENT","MAX_TRACKING_IDS","UNKNOWN","String","undefined","getService","options","service","api","trim","toLowerCase","normalizeRouteSegment","segment","getOperation","resource","path","split","segments","Boolean","map","join","getDirectRequestIdentity","uri","url","requestUrl","URL","host","endPoint","pathname","_unused","getRequestIdentity","directRequestIdentity","getNetworkDuration","_options$$timings","_options$$timings2","start","$timings","networkStart","end","networkEnd","_isFinite","recordNetworkDuration","metric","duration","totalNetworkDurationMs","networkDurationsMs","getMethod","method","toUpperCase","getStatusCode","reason","_reason$statusCode","statusCode","status","_isInteger","getWrappedError","body","_typeof2","isTimeoutSignal","signal","includes","isTimeoutFailure","_options$$timings3","_options$$timings4","wrappedError","code","message","timeout","getErrorType","getErrorCode","errorCode","getErrorMessage","shouldTrackNetworkRequest","createNetworkErrorMetric","_options$headers","identity","trackingId","headers","trackingid","errorType","errorMessage","trackingIds","countError","createEmptyNetworkTelemetry","metricsSummary","totalSendRequest","totalFailedRequest","totalRecvdResponse","totalFailedResponse","metrics","errorMetrics","errorMetricsSummary","getRequestMetric","telemetry","_iterator","_step","err","countSendRequest","countFailedRequest","countRecvdResponse","countFailedResponse","isSameError","first","second","recordError","errorMetric","_iterator2","_step2","existingMetric","getDurationPercentile","durations","percentile","sortedDurations","_toConsumableArray2","sort","rank","Math","max","ceil","serializeRequestMetric","measuredRequestCount","averageNetworkDurationMs","maxNetworkDurationP90Ms","maxNetworkDurationP99Ms","serializeNetworkTelemetry","hasNetworkTelemetry","createNetworkTelemetryCollector","_ref","intervalMs","onSubmissionFailure","submitMetric","inFlightSubmissions","_set","trackSubmission","submission","add","then","delete","recordRequest","recordResponse","requestMetric","recordFailure","statusSummary","count","submitSummary","completedTelemetry","payload","_promise","resolve","type","tags","fields","eventPayload","_unused2","telemetryIntervalMs","telemetryInterval","safeSetInterval","flush","stop","clearInterval","all"],"sources":["network-telemetry.ts"],"sourcesContent":["// TypeScript signatures own the types; JSDoc contains descriptions only.\n/* eslint valid-jsdoc: [\"error\", {\"requireParamType\": false, \"requireReturnType\": false}] */\n\nimport {safeSetInterval} from '@webex/common-timers';\n\nexport const NETWORK_REQUEST_SUMMARY_METRIC = 'JS_SDK_NETWORK_REQUEST_SUMMARY';\nexport const NETWORK_TELEMETRY_INTERVAL_MS = 10 * 60 * 1_000;\n\n// Only segments that follow the SDK's static route naming convention are kept.\n// Numeric, mixed-case, encoded, and otherwise dynamic-looking values are redacted.\n// Lowercase alphabetic identifiers remain ambiguous because requests do not provide route templates.\n// Examples: `rooms/12345/messages` becomes `rooms/:id/messages`, and\n// `v1/rooms/65f81b6e-19dc-4a99-9175-59e9b34a5d42` becomes `v1/rooms/:id`.\n// `reports/a%2Fb/download` becomes `reports/:id/download`; `rooms`, `meeting-info`, and `v1` stay unchanged.\nconst SAFE_ROUTE_SEGMENT = /^(?:[a-z]+(?:-[a-z]+)*|v[1-9]\\d?)$/;\nconst MAX_TRACKING_IDS = 10;\nconst UNKNOWN = 'unknown';\n\ntype Headers = Record<string, unknown>;\n\ntype MetricsSummary = {\n totalSendRequest: number;\n totalFailedRequest: number;\n totalRecvdResponse: number;\n totalFailedResponse: number;\n};\n\ntype RequestMetric = {\n host: string;\n endPoint: string;\n countSendRequest: number;\n countFailedRequest: number;\n countRecvdResponse: number;\n countFailedResponse: number;\n averageNetworkDurationMs: number;\n maxNetworkDurationP90Ms: number;\n maxNetworkDurationP99Ms: number;\n};\n\ntype RequestIdentity = Pick<RequestMetric, 'host' | 'endPoint'>;\n\nexport type NetworkErrorMetric = {\n host: string;\n endPoint: string;\n statusCode: number;\n errorCode: string;\n method: string;\n errorType: string;\n errorMessage: string;\n trackingIds: string[];\n countError: number;\n};\n\nexport type NetworkTelemetry = {\n metricsSummary: MetricsSummary;\n metrics: RequestMetric[];\n errorMetrics: NetworkErrorMetric[];\n errorMetricsSummary: Record<string, {count: number}>;\n};\n\ntype RequestMetricState = Omit<\n RequestMetric,\n 'averageNetworkDurationMs' | 'maxNetworkDurationP90Ms' | 'maxNetworkDurationP99Ms'\n> & {\n totalNetworkDurationMs: number;\n networkDurationsMs: number[];\n};\n\ntype NetworkTelemetryState = Omit<NetworkTelemetry, 'metrics'> & {\n metrics: RequestMetricState[];\n};\n\ntype ErrorDetails = {\n code?: number | string;\n errorCode?: number | string;\n message?: string;\n name?: string;\n};\n\n// Request events come from JavaScript in webex-core and have no shared TypeScript\n// contract. This local type intentionally contains only fields used by telemetry.\ntype RequestOptions = {\n api?: string;\n headers?: Headers;\n method?: string;\n resource?: string;\n service?: string;\n timeout?: number;\n uri?: string;\n url?: string;\n // The network timing interceptor adds internal fields with a `$` prefix.\n $timings?: {\n networkEnd?: number;\n networkStart?: number;\n };\n};\n\ntype RequestFailure = ErrorDetails & {\n body?: ErrorDetails | string;\n status?: number;\n statusCode?: number;\n};\n\ntype NetworkMetricProperties = {\n type: 'operational';\n tags: Record<string, string>;\n fields: MetricsSummary;\n eventPayload: NetworkTelemetry;\n};\n\ntype NetworkTelemetryCollectorOptions = {\n intervalMs?: number;\n onSubmissionFailure: () => void;\n submitMetric: (name: string, properties: NetworkMetricProperties) => unknown;\n};\n\ntype NetworkTelemetryCollector = {\n recordRequest: (options?: RequestOptions) => void;\n recordResponse: (options?: RequestOptions) => void;\n recordFailure: (options?: RequestOptions, reason?: RequestFailure) => void;\n flush: () => Promise<void>;\n stop: () => Promise<void>;\n};\n\n/**\n * Converts a non-empty string or number to a string.\n * @param value Value to convert.\n * @returns The converted string, or undefined for unsupported values.\n */\nfunction toString(value: unknown): string | undefined {\n if (typeof value === 'number') {\n return String(value);\n }\n\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/**\n * Returns the normalized SDK service name.\n * @param options Request options containing the service or API name.\n * @returns The normalized service name.\n */\nfunction getService(options: RequestOptions): string {\n const service = options.service || options.api;\n\n return typeof service === 'string' ? service.trim().toLowerCase() : '';\n}\n\n/**\n * Replaces values that may be resource identifiers with a stable placeholder.\n * @param segment Endpoint path segment.\n * @returns The original static segment or the identifier placeholder.\n */\nfunction normalizeRouteSegment(segment: string): string {\n return SAFE_ROUTE_SEGMENT.test(segment) ? segment : ':id';\n}\n\n/**\n * Removes query data and redacts dynamic-looking endpoint segments.\n * @param resource SDK resource path.\n * @returns The normalized endpoint.\n */\nexport function getOperation(resource?: string): string {\n if (typeof resource !== 'string' || resource.length === 0) {\n return UNKNOWN;\n }\n\n const path = resource.split(/[?#]/, 1)[0];\n const segments = path.split('/').filter(Boolean).map(normalizeRouteSegment);\n\n return segments.length > 0 ? segments.join('/') : 'root';\n}\n\n/**\n * Extracts only the direct URL parts allowed in telemetry. URL credentials,\n * query parameters, and fragments are not returned, while the pathname is\n * converted to a sanitized endpoint.\n * @param options Request options containing a direct URL.\n * @returns The sanitized request identity, or undefined without a valid URL.\n */\nfunction getDirectRequestIdentity(options: RequestOptions): RequestIdentity | undefined {\n const value = options.uri || options.url;\n\n if (typeof value !== 'string') {\n return undefined;\n }\n\n try {\n const requestUrl = new URL(value);\n\n return {\n host: requestUrl.host.toLowerCase() || UNKNOWN,\n endPoint: getOperation(requestUrl.pathname),\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Uses the logical service as the host because request:start may run before the\n * service interceptor resolves a physical URL. Direct-URL requests use URL.host.\n * @param options Request options used to resolve the identity.\n * @returns The request host and endpoint.\n */\nfunction getRequestIdentity(options: RequestOptions): RequestIdentity {\n const directRequestIdentity = getDirectRequestIdentity(options);\n const service = getService(options);\n\n return {\n host: service || directRequestIdentity?.host || UNKNOWN,\n endPoint: options.resource\n ? getOperation(options.resource)\n : directRequestIdentity?.endPoint || UNKNOWN,\n };\n}\n\n/**\n * Returns the measured network duration when both timing points are valid.\n * @param options Request options containing network timing metadata.\n * @returns The duration in milliseconds, or undefined when timing is unavailable.\n */\nfunction getNetworkDuration(options: RequestOptions): number | undefined {\n const start = options.$timings?.networkStart;\n const end = options.$timings?.networkEnd;\n\n return typeof start === 'number' &&\n Number.isFinite(start) &&\n typeof end === 'number' &&\n Number.isFinite(end) &&\n end >= start\n ? end - start\n : undefined;\n}\n\n/**\n * Adds a completed request's network duration to its endpoint aggregate.\n * @param metric Endpoint aggregate to update.\n * @param options Request options containing network timing metadata.\n * @returns Nothing.\n */\nfunction recordNetworkDuration(metric: RequestMetricState, options: RequestOptions): void {\n const duration = getNetworkDuration(options);\n\n if (duration === undefined) {\n return;\n }\n\n metric.totalNetworkDurationMs += duration;\n metric.networkDurationsMs.push(duration);\n}\n\n/**\n * Returns a normalized uppercase HTTP method.\n * @param method HTTP method from the request options.\n * @returns The normalized method.\n */\nfunction getMethod(method?: string): string {\n return typeof method === 'string' && method.length > 0 ? method.toUpperCase() : 'UNKNOWN';\n}\n\n/**\n * Status zero represents a failure for which no valid HTTP response was received.\n * @param reason Request failure.\n * @returns A valid HTTP status code, or zero when no response was received.\n */\nfunction getStatusCode(reason: RequestFailure): number {\n const statusCode = reason.statusCode ?? reason.status;\n\n return typeof statusCode === 'number' &&\n Number.isInteger(statusCode) &&\n statusCode >= 100 &&\n statusCode <= 599\n ? statusCode\n : 0;\n}\n\n/**\n * Returns an error nested in a Webex HTTP error body.\n * @param reason Request failure.\n * @returns The wrapped error, when present.\n */\nfunction getWrappedError(reason: RequestFailure): ErrorDetails | undefined {\n return reason.body && typeof reason.body === 'object' ? reason.body : undefined;\n}\n\n/**\n * Checks the timeout forms emitted by browser and Node transports.\n * @param value Possible timeout signal.\n * @returns Whether the value represents a timeout.\n */\nfunction isTimeoutSignal(value: unknown): boolean {\n if (typeof value !== 'string') {\n return false;\n }\n\n const signal = value.toLowerCase();\n\n return signal.includes('timeout') || signal === 'etimedout' || signal === 'esockettimedout';\n}\n\n/**\n * Detects direct errors, transport errors wrapped in body, and requests whose\n * measured network duration reached the configured timeout.\n * @param reason Request failure.\n * @param options Request options containing timeout metadata.\n * @returns Whether the request timed out.\n */\nfunction isTimeoutFailure(reason: RequestFailure, options: RequestOptions): boolean {\n const wrappedError = getWrappedError(reason);\n\n if (\n isTimeoutSignal(reason.name) ||\n isTimeoutSignal(reason.code) ||\n isTimeoutSignal(reason.message) ||\n isTimeoutSignal(reason.body) ||\n isTimeoutSignal(wrappedError?.name) ||\n isTimeoutSignal(wrappedError?.code) ||\n isTimeoutSignal(wrappedError?.message)\n ) {\n return true;\n }\n\n const start = options.$timings?.networkStart;\n const end = options.$timings?.networkEnd;\n\n return (\n typeof options.timeout === 'number' &&\n options.timeout > 0 &&\n typeof start === 'number' &&\n typeof end === 'number' &&\n end >= start &&\n end - start >= options.timeout\n );\n}\n\n/**\n * Converts errors into a bounded set of categories for aggregation.\n * @param reason Request failure.\n * @param options Request options.\n * @param statusCode Normalized status code.\n * @returns The aggregate error category.\n */\nfunction getErrorType(reason: RequestFailure, options: RequestOptions, statusCode: number): string {\n const name = typeof reason.name === 'string' ? reason.name.toLowerCase() : '';\n\n if (name === 'aborterror') {\n return 'aborted';\n }\n\n if (statusCode === 408 || statusCode === 504 || isTimeoutFailure(reason, options)) {\n return 'timeout';\n }\n\n if (statusCode === 429) {\n return 'rate_limited';\n }\n\n if (statusCode >= 500) {\n return 'server_error';\n }\n\n if (statusCode >= 400) {\n return 'client_error';\n }\n\n return statusCode === 0 || name?.includes('network') ? 'network_error' : 'request_error';\n}\n\n/**\n * Returns the most specific available error code.\n * @param reason Request failure.\n * @returns The error code or the unknown fallback.\n */\nfunction getErrorCode(reason: RequestFailure): string {\n const wrappedError = getWrappedError(reason);\n\n return (\n toString(wrappedError?.errorCode) ||\n toString(wrappedError?.code) ||\n toString(reason.errorCode) ||\n toString(reason.code) ||\n UNKNOWN\n );\n}\n\n/**\n * Returns the most specific available error message.\n * @param reason Request failure.\n * @returns The error message or the unknown fallback.\n */\nfunction getErrorMessage(reason: RequestFailure): string {\n const wrappedError = getWrappedError(reason);\n\n return (\n toString(wrappedError?.message) || toString(reason.body) || toString(reason.message) || UNKNOWN\n );\n}\n\n/**\n * Excludes the transports used to submit telemetry, preventing self-reporting.\n * @param options Request options.\n * @returns Whether the request should be tracked.\n */\nexport function shouldTrackNetworkRequest(options: RequestOptions = {}): boolean {\n const service = getService(options);\n\n return service !== 'metrics' && service !== 'unifiedtelemetry';\n}\n\n/**\n * Creates the error entry produced by one failed request.\n * @param options Request options.\n * @param reason Request failure.\n * @returns The normalized error metric.\n */\nexport function createNetworkErrorMetric(\n options: RequestOptions = {},\n reason: RequestFailure = {}\n): NetworkErrorMetric {\n const identity = getRequestIdentity(options);\n const statusCode = getStatusCode(reason);\n // WebexTrackingIdInterceptor stores the request ID under this lowercase key.\n const trackingId = toString(options.headers?.trackingid);\n\n return {\n ...identity,\n statusCode,\n errorCode: getErrorCode(reason),\n method: getMethod(options.method),\n errorType: getErrorType(reason, options, statusCode),\n errorMessage: getErrorMessage(reason),\n trackingIds: trackingId ? [trackingId] : [],\n countError: 1,\n };\n}\n\n/**\n * Creates an empty ten-minute telemetry window.\n * @returns An empty telemetry aggregate.\n */\nfunction createEmptyNetworkTelemetry(): NetworkTelemetryState {\n return {\n metricsSummary: {\n totalSendRequest: 0,\n totalFailedRequest: 0,\n totalRecvdResponse: 0,\n totalFailedResponse: 0,\n },\n metrics: [],\n errorMetrics: [],\n errorMetricsSummary: {},\n };\n}\n\n/**\n * Finds or creates the request counters for one host and endpoint.\n * @param telemetry Current telemetry aggregate.\n * @param options Request options.\n * @returns The matching endpoint counters.\n */\nfunction getRequestMetric(\n telemetry: NetworkTelemetryState,\n options: RequestOptions\n): RequestMetricState {\n const identity = getRequestIdentity(options);\n\n for (const metric of telemetry.metrics) {\n if (metric.host === identity.host && metric.endPoint === identity.endPoint) {\n return metric;\n }\n }\n\n const metric = {\n ...identity,\n countSendRequest: 0,\n countFailedRequest: 0,\n countRecvdResponse: 0,\n countFailedResponse: 0,\n totalNetworkDurationMs: 0,\n networkDurationsMs: [],\n };\n\n telemetry.metrics.push(metric);\n\n return metric;\n}\n\n/**\n * Error entries aggregate only when every identifying field matches.\n * @param first First error metric.\n * @param second Second error metric.\n * @returns Whether both errors belong to the same aggregate.\n */\nfunction isSameError(first: NetworkErrorMetric, second: NetworkErrorMetric): boolean {\n return (\n first.host === second.host &&\n first.endPoint === second.endPoint &&\n first.statusCode === second.statusCode &&\n first.errorCode === second.errorCode &&\n first.method === second.method &&\n first.errorType === second.errorType &&\n first.errorMessage === second.errorMessage\n );\n}\n\n/**\n * Adds a failure to its error aggregate and retains at most ten unique IDs.\n * @param telemetry Current telemetry aggregate.\n * @param errorMetric Error metric to record.\n * @returns Nothing.\n */\nfunction recordError(telemetry: NetworkTelemetryState, errorMetric: NetworkErrorMetric): void {\n for (const existingMetric of telemetry.errorMetrics) {\n if (isSameError(existingMetric, errorMetric)) {\n existingMetric.countError += 1;\n\n const trackingId = errorMetric.trackingIds[0];\n\n if (\n trackingId &&\n existingMetric.trackingIds.length < MAX_TRACKING_IDS &&\n !existingMetric.trackingIds.includes(trackingId)\n ) {\n existingMetric.trackingIds.push(trackingId);\n }\n\n return;\n }\n }\n\n telemetry.errorMetrics.push(errorMetric);\n}\n\n/**\n * Returns a nearest-rank percentile from the measured durations.\n * @param durations Measured network durations in milliseconds.\n * @param percentile Percentile to calculate, between zero and one.\n * @returns The percentile duration, or zero when no durations were measured.\n */\nfunction getDurationPercentile(durations: number[], percentile: number): number {\n if (durations.length === 0) {\n return 0;\n }\n\n const sortedDurations = [...durations].sort((first, second) => first - second);\n const rank = Math.max(1, Math.ceil(sortedDurations.length * percentile));\n\n return sortedDurations[rank - 1];\n}\n\n/**\n * Converts internal duration samples into the public endpoint metric shape.\n * @param metric Internal endpoint aggregate.\n * @returns Endpoint aggregate with average and p90 duration statistics.\n */\nfunction serializeRequestMetric(metric: RequestMetricState): RequestMetric {\n const measuredRequestCount = metric.networkDurationsMs.length;\n\n return {\n host: metric.host,\n endPoint: metric.endPoint,\n countSendRequest: metric.countSendRequest,\n countFailedRequest: metric.countFailedRequest,\n countRecvdResponse: metric.countRecvdResponse,\n countFailedResponse: metric.countFailedResponse,\n averageNetworkDurationMs:\n measuredRequestCount > 0 ? metric.totalNetworkDurationMs / measuredRequestCount : 0,\n maxNetworkDurationP90Ms: getDurationPercentile(metric.networkDurationsMs, 0.9),\n maxNetworkDurationP99Ms: getDurationPercentile(metric.networkDurationsMs, 0.99),\n };\n}\n\n/**\n * Converts the internal telemetry state into the submitted payload shape.\n * @param telemetry Internal telemetry aggregate.\n * @returns Telemetry payload with no internal duration samples.\n */\nfunction serializeNetworkTelemetry(telemetry: NetworkTelemetryState): NetworkTelemetry {\n return {\n metricsSummary: telemetry.metricsSummary,\n metrics: telemetry.metrics.map(serializeRequestMetric),\n errorMetrics: telemetry.errorMetrics,\n errorMetricsSummary: telemetry.errorMetricsSummary,\n };\n}\n\n/**\n * Checks whether the current window contains anything worth flushing.\n * @param telemetry Current telemetry aggregate.\n * @returns Whether the aggregate contains request data.\n */\nfunction hasNetworkTelemetry(telemetry: NetworkTelemetryState): boolean {\n return telemetry.metrics.length > 0 || telemetry.errorMetrics.length > 0;\n}\n\n/**\n * Creates a network telemetry collector and starts its periodic timer.\n * @param options Submission callbacks.\n * @returns The network telemetry collector.\n */\nexport function createNetworkTelemetryCollector({\n intervalMs,\n onSubmissionFailure,\n submitMetric,\n}: NetworkTelemetryCollectorOptions): NetworkTelemetryCollector {\n let telemetry = createEmptyNetworkTelemetry();\n const inFlightSubmissions = new Set<Promise<void>>();\n\n /**\n * Tracks a submission until it settles so shutdown can wait for requests\n * whose telemetry window has already been reset.\n * @param submission Submission promise.\n * @returns The tracked submission promise.\n */\n function trackSubmission(submission: Promise<void>): Promise<void> {\n inFlightSubmissions.add(submission);\n submission.then(\n () => inFlightSubmissions.delete(submission),\n () => inFlightSubmissions.delete(submission)\n );\n\n return submission;\n }\n\n /**\n * Records a request being sent.\n * @param options Request options.\n * @returns Nothing.\n */\n function recordRequest(options: RequestOptions = {}): void {\n if (!shouldTrackNetworkRequest(options)) {\n return;\n }\n\n telemetry.metricsSummary.totalSendRequest += 1;\n getRequestMetric(telemetry, options).countSendRequest += 1;\n }\n\n /**\n * Records a successful response.\n * @param options Request options.\n * @returns Nothing.\n */\n function recordResponse(options: RequestOptions = {}): void {\n if (!shouldTrackNetworkRequest(options)) {\n return;\n }\n\n telemetry.metricsSummary.totalRecvdResponse += 1;\n const requestMetric = getRequestMetric(telemetry, options);\n requestMetric.countRecvdResponse += 1;\n recordNetworkDuration(requestMetric, options);\n }\n\n /**\n * A real HTTP status is a failed response. Status zero means the request\n * failed before the SDK received a valid HTTP response.\n * @param options Request options.\n * @param reason Request failure.\n * @returns Nothing.\n */\n function recordFailure(options: RequestOptions = {}, reason: RequestFailure = {}): void {\n if (!shouldTrackNetworkRequest(options)) {\n return;\n }\n\n const errorMetric = createNetworkErrorMetric(options, reason);\n const requestMetric = getRequestMetric(telemetry, options);\n recordNetworkDuration(requestMetric, options);\n\n if (errorMetric.statusCode === 0) {\n telemetry.metricsSummary.totalFailedRequest += 1;\n requestMetric.countFailedRequest += 1;\n } else {\n telemetry.metricsSummary.totalRecvdResponse += 1;\n telemetry.metricsSummary.totalFailedResponse += 1;\n requestMetric.countRecvdResponse += 1;\n requestMetric.countFailedResponse += 1;\n }\n\n recordError(telemetry, errorMetric);\n\n const statusCode = String(errorMetric.statusCode);\n const statusSummary = telemetry.errorMetricsSummary[statusCode];\n\n if (statusSummary) {\n statusSummary.count += 1;\n } else {\n telemetry.errorMetricsSummary[statusCode] = {count: 1};\n }\n }\n\n /**\n * Submits the completed window and starts collecting the next one.\n * @returns A promise that settles after submission succeeds or is reported as failed.\n */\n function submitSummary(): Promise<void> {\n const completedTelemetry = telemetry;\n const payload = serializeNetworkTelemetry(completedTelemetry);\n\n // Reset before submission so requests emitted by the telemetry transport,\n // or while it is pending, cannot mutate the completed window.\n telemetry = createEmptyNetworkTelemetry();\n\n try {\n const submission = Promise.resolve(\n submitMetric(NETWORK_REQUEST_SUMMARY_METRIC, {\n type: 'operational',\n tags: {},\n fields: completedTelemetry.metricsSummary,\n eventPayload: payload,\n })\n ).then(\n () => undefined,\n () => {\n onSubmissionFailure();\n }\n );\n\n return trackSubmission(submission);\n } catch {\n // submitMetric may throw before returning a promise.\n onSubmissionFailure();\n\n return Promise.resolve();\n }\n }\n\n const telemetryIntervalMs =\n typeof intervalMs === 'number' && Number.isFinite(intervalMs) && intervalMs > 0\n ? intervalMs\n : NETWORK_TELEMETRY_INTERVAL_MS;\n const telemetryInterval = safeSetInterval(submitSummary, telemetryIntervalMs);\n\n /**\n * Submits the current non-empty window immediately.\n * @returns A promise that settles after submission succeeds or is reported as failed.\n */\n function flush(): Promise<void> {\n return hasNetworkTelemetry(telemetry) ? submitSummary() : Promise.resolve();\n }\n\n /**\n * Stops periodic submission and releases data from the current window.\n * @returns A promise that settles after the final window is submitted or failure is reported.\n */\n function stop(): Promise<void> {\n clearInterval(telemetryInterval);\n\n flush();\n\n return Promise.all(inFlightSubmissions).then(() => undefined);\n }\n\n return {recordRequest, recordResponse, recordFailure, flush, stop};\n}\n"],"mappings":"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","ignoreList":[]}
@@ -205,6 +205,12 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
205
205
  serviceVersion?: string;
206
206
  additionalProperties?: never;
207
207
  };
208
+ /**
209
+ * Returns the signed-in user's CI ID derived from credentials tokens.
210
+ * Used as a fallback when no device is registered.
211
+ * @returns the userId, or undefined if it can't be determined
212
+ */
213
+ private getUserIdFromCredentials;
208
214
  /**
209
215
  * Gather identifier details for call diagnostic payload.
210
216
  * @throws Error if initialization fails.
@@ -541,16 +547,16 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
541
547
  * @param arg.clientErrorCode
542
548
  * @param arg.serviceErrorCode
543
549
  * @param arg.payloadOverrides
544
- * @param arg.httpStatusCode
550
+ * @param arg.httpCode
545
551
  * @returns
546
552
  */
547
- getErrorPayloadForClientErrorCode({ clientErrorCode, serviceErrorCode, serviceErrorName, rawErrorMessage, payloadOverrides, httpStatusCode, }: {
553
+ getErrorPayloadForClientErrorCode({ clientErrorCode, serviceErrorCode, serviceErrorName, rawErrorMessage, payloadOverrides, httpCode, }: {
548
554
  clientErrorCode: number;
549
555
  serviceErrorCode: any;
550
556
  serviceErrorName?: any;
551
557
  rawErrorMessage?: string;
552
558
  payloadOverrides?: any;
553
- httpStatusCode?: number;
559
+ httpCode?: number;
554
560
  }): ClientEventError;
555
561
  /**
556
562
  * Clear the error cache
@@ -2,6 +2,8 @@ import { ClientEventError, ClientSubServiceType } from '../metrics.types';
2
2
  export declare const CALL_DIAGNOSTIC_LOG_IDENTIFIER = "call-diagnostic-events -> ";
3
3
  export declare const CALL_FEATURE_LOG_IDENTIFIER = "call-diagnostic-events-feature -> ";
4
4
  export declare const AUTHENTICATION_FAILED_CODE = 1010;
5
+ export declare const LOCUS_RATE_LIMITED_OUTGOING_CLIENT_CODE = 1002;
6
+ export declare const LOCUS_UNAVAILABLE_CLIENT_CODE = 1003;
5
7
  export declare const NETWORK_ERROR = 1026;
6
8
  export declare const NEW_LOCUS_ERROR_CLIENT_CODE = 4008;
7
9
  export declare const MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE = 4100;
@@ -11,6 +11,11 @@ declare namespace _default {
11
11
  namespace unhandledExceptionTelemetry {
12
12
  const enabled: boolean;
13
13
  }
14
+ namespace networkTelemetry {
15
+ const enabled_1: boolean;
16
+ export { enabled_1 as enabled };
17
+ export const intervalMs: number;
18
+ }
14
19
  const batcherWait: number;
15
20
  const batcherMaxCalls: number;
16
21
  const batcherMaxWait: number;
@@ -0,0 +1,108 @@
1
+ export declare const NETWORK_REQUEST_SUMMARY_METRIC = "JS_SDK_NETWORK_REQUEST_SUMMARY";
2
+ export declare const NETWORK_TELEMETRY_INTERVAL_MS: number;
3
+ type Headers = Record<string, unknown>;
4
+ type MetricsSummary = {
5
+ totalSendRequest: number;
6
+ totalFailedRequest: number;
7
+ totalRecvdResponse: number;
8
+ totalFailedResponse: number;
9
+ };
10
+ type RequestMetric = {
11
+ host: string;
12
+ endPoint: string;
13
+ countSendRequest: number;
14
+ countFailedRequest: number;
15
+ countRecvdResponse: number;
16
+ countFailedResponse: number;
17
+ averageNetworkDurationMs: number;
18
+ maxNetworkDurationP90Ms: number;
19
+ maxNetworkDurationP99Ms: number;
20
+ };
21
+ export type NetworkErrorMetric = {
22
+ host: string;
23
+ endPoint: string;
24
+ statusCode: number;
25
+ errorCode: string;
26
+ method: string;
27
+ errorType: string;
28
+ errorMessage: string;
29
+ trackingIds: string[];
30
+ countError: number;
31
+ };
32
+ export type NetworkTelemetry = {
33
+ metricsSummary: MetricsSummary;
34
+ metrics: RequestMetric[];
35
+ errorMetrics: NetworkErrorMetric[];
36
+ errorMetricsSummary: Record<string, {
37
+ count: number;
38
+ }>;
39
+ };
40
+ type ErrorDetails = {
41
+ code?: number | string;
42
+ errorCode?: number | string;
43
+ message?: string;
44
+ name?: string;
45
+ };
46
+ type RequestOptions = {
47
+ api?: string;
48
+ headers?: Headers;
49
+ method?: string;
50
+ resource?: string;
51
+ service?: string;
52
+ timeout?: number;
53
+ uri?: string;
54
+ url?: string;
55
+ $timings?: {
56
+ networkEnd?: number;
57
+ networkStart?: number;
58
+ };
59
+ };
60
+ type RequestFailure = ErrorDetails & {
61
+ body?: ErrorDetails | string;
62
+ status?: number;
63
+ statusCode?: number;
64
+ };
65
+ type NetworkMetricProperties = {
66
+ type: 'operational';
67
+ tags: Record<string, string>;
68
+ fields: MetricsSummary;
69
+ eventPayload: NetworkTelemetry;
70
+ };
71
+ type NetworkTelemetryCollectorOptions = {
72
+ intervalMs?: number;
73
+ onSubmissionFailure: () => void;
74
+ submitMetric: (name: string, properties: NetworkMetricProperties) => unknown;
75
+ };
76
+ type NetworkTelemetryCollector = {
77
+ recordRequest: (options?: RequestOptions) => void;
78
+ recordResponse: (options?: RequestOptions) => void;
79
+ recordFailure: (options?: RequestOptions, reason?: RequestFailure) => void;
80
+ flush: () => Promise<void>;
81
+ stop: () => Promise<void>;
82
+ };
83
+ /**
84
+ * Removes query data and redacts dynamic-looking endpoint segments.
85
+ * @param resource SDK resource path.
86
+ * @returns The normalized endpoint.
87
+ */
88
+ export declare function getOperation(resource?: string): string;
89
+ /**
90
+ * Excludes the transports used to submit telemetry, preventing self-reporting.
91
+ * @param options Request options.
92
+ * @returns Whether the request should be tracked.
93
+ */
94
+ export declare function shouldTrackNetworkRequest(options?: RequestOptions): boolean;
95
+ /**
96
+ * Creates the error entry produced by one failed request.
97
+ * @param options Request options.
98
+ * @param reason Request failure.
99
+ * @returns The normalized error metric.
100
+ */
101
+ export declare function createNetworkErrorMetric(options?: RequestOptions, reason?: RequestFailure): NetworkErrorMetric;
102
+ /**
103
+ * Creates a network telemetry collector and starts its periodic timer.
104
+ * @param options Submission callbacks.
105
+ * @returns The network telemetry collector.
106
+ */
107
+ export declare function createNetworkTelemetryCollector({ intervalMs, onSubmissionFailure, submitMetric, }: NetworkTelemetryCollectorOptions): NetworkTelemetryCollector;
108
+ export {};
package/package.json CHANGED
@@ -26,21 +26,21 @@
26
26
  "@webex/eslint-config-legacy": "0.0.0",
27
27
  "@webex/jest-config-legacy": "0.0.0",
28
28
  "@webex/legacy-tools": "0.0.0",
29
- "@webex/test-helper-chai": "3.12.0-auth-prejoin-fetch.1",
30
- "@webex/test-helper-mocha": "3.12.0-auth-prejoin-fetch.1",
31
- "@webex/test-helper-mock-webex": "3.12.0-auth-prejoin-fetch.1",
32
- "@webex/test-helper-test-users": "3.12.0-auth-prejoin-fetch.1",
29
+ "@webex/test-helper-chai": "3.12.0-llmrefactor.4",
30
+ "@webex/test-helper-mocha": "3.12.0-llmrefactor.4",
31
+ "@webex/test-helper-mock-webex": "3.12.0-llmrefactor.3",
32
+ "@webex/test-helper-test-users": "3.12.0-llmrefactor.1",
33
33
  "eslint": "^8.24.0",
34
34
  "prettier": "^2.7.1",
35
35
  "sinon": "^9.2.4"
36
36
  },
37
37
  "dependencies": {
38
- "@webex/common": "3.12.0-auth-prejoin-fetch.1",
39
- "@webex/common-timers": "3.12.0-auth-prejoin-fetch.1",
38
+ "@webex/common": "3.12.0-llmrefactor.4",
39
+ "@webex/common-timers": "3.12.0-llmrefactor.4",
40
40
  "@webex/event-dictionary-ts": "^1.0.2220",
41
- "@webex/test-helper-chai": "3.12.0-auth-prejoin-fetch.1",
42
- "@webex/test-helper-mock-webex": "3.12.0-auth-prejoin-fetch.1",
43
- "@webex/webex-core": "3.12.0-auth-prejoin-fetch.1",
41
+ "@webex/test-helper-chai": "3.12.0-llmrefactor.4",
42
+ "@webex/test-helper-mock-webex": "3.12.0-llmrefactor.3",
43
+ "@webex/webex-core": "3.12.0-llmrefactor.10",
44
44
  "ip-anonymize": "^0.1.0",
45
45
  "isbot": "5.2.1",
46
46
  "lodash": "^4.17.21",
@@ -54,5 +54,5 @@
54
54
  "test:style": "eslint ./src/**/*.*",
55
55
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
56
56
  },
57
- "version": "3.12.0-auth-prejoin-fetch.1"
57
+ "version": "3.12.0-llmrefactor.10"
58
58
  }
@@ -64,10 +64,17 @@ import {
64
64
  SDP_OFFER_CREATION_ERROR_MAP,
65
65
  CALL_FEATURE_LOG_IDENTIFIER,
66
66
  CALL_FEATURE_EVENT_FAILED_TO_SEND,
67
+ LOCUS_RATE_LIMITED_OUTGOING_CLIENT_CODE,
68
+ LOCUS_UNAVAILABLE_CLIENT_CODE,
67
69
  } from './config';
68
70
 
69
71
  const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
70
72
 
73
+ const LOCUS_HTTP_STATUS_TO_CLIENT_ERROR_CODE: Partial<Record<number, number>> = {
74
+ 429: LOCUS_RATE_LIMITED_OUTGOING_CLIENT_CODE,
75
+ 503: LOCUS_UNAVAILABLE_CLIENT_CODE,
76
+ };
77
+
71
78
  type GetOriginOptions = {
72
79
  clientType: ClientType;
73
80
  subClientType: SubClientType;
@@ -385,6 +392,20 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
385
392
  throw new Error("ClientType and SubClientType can't be undefined");
386
393
  }
387
394
 
395
+ /**
396
+ * Returns the signed-in user's CI ID derived from credentials tokens.
397
+ * Used as a fallback when no device is registered.
398
+ * @returns the userId, or undefined if it can't be determined
399
+ */
400
+ private getUserIdFromCredentials(): string | undefined {
401
+ try {
402
+ // @ts-ignore
403
+ return this.webex.credentials.getUserId();
404
+ } catch {
405
+ return undefined;
406
+ }
407
+ }
408
+
388
409
  /**
389
410
  * Gather identifier details for call diagnostic payload.
390
411
  * @throws Error if initialization fails.
@@ -429,7 +450,6 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
429
450
  const {device} = this;
430
451
  const {installationId} = device?.config || {};
431
452
 
432
- identifiers.userId = device?.userId || preLoginId;
433
453
  identifiers.deviceId = device?.url;
434
454
  identifiers.orgId = device?.orgId;
435
455
  // @ts-ignore
@@ -440,6 +460,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
440
460
  }
441
461
  }
442
462
 
463
+ // Prefer the device's userId, but fall back to the signed-in user's ID from
464
+ // credentials when no device is registered, then to the pre-login ID.
465
+ identifiers.userId = this.device?.userId || this.getUserIdFromCredentials() || preLoginId;
466
+
443
467
  if (meeting?.locusInfo?.fullState) {
444
468
  identifiers.locusUrl = meeting.locusUrl;
445
469
  identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();
@@ -702,7 +726,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
702
726
  * @param arg.clientErrorCode
703
727
  * @param arg.serviceErrorCode
704
728
  * @param arg.payloadOverrides
705
- * @param arg.httpStatusCode
729
+ * @param arg.httpCode
706
730
  * @returns
707
731
  */
708
732
  public getErrorPayloadForClientErrorCode({
@@ -711,14 +735,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
711
735
  serviceErrorName,
712
736
  rawErrorMessage,
713
737
  payloadOverrides,
714
- httpStatusCode,
738
+ httpCode,
715
739
  }: {
716
740
  clientErrorCode: number;
717
741
  serviceErrorCode: any;
718
742
  serviceErrorName?: any;
719
743
  rawErrorMessage?: string;
720
744
  payloadOverrides?: any;
721
- httpStatusCode?: number;
745
+ httpCode?: number;
722
746
  }): ClientEventError {
723
747
  let error: ClientEventError;
724
748
 
@@ -732,7 +756,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
732
756
  serviceErrorName ? {errorData: {errorName: serviceErrorName}} : {},
733
757
  {serviceErrorCode},
734
758
  {rawErrorMessage},
735
- httpStatusCode === undefined ? {} : {httpStatusCode},
759
+ httpCode === undefined ? {} : {httpCode},
736
760
  partialParsedError,
737
761
  payloadOverrides || {}
738
762
  );
@@ -901,7 +925,12 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
901
925
  }
902
926
 
903
927
  const rawErrorMessage = rawError.message;
904
- const httpStatusCode = rawError.statusCode;
928
+ const httpCode = rawError.statusCode;
929
+ const serviceErrorCode =
930
+ rawError?.error?.body?.errorCode ||
931
+ rawError?.body?.errorCode ||
932
+ rawError?.body?.code ||
933
+ rawError?.body?.reason?.reasonCode;
905
934
  let payload;
906
935
 
907
936
  if (rawError.name) {
@@ -911,7 +940,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
911
940
  clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],
912
941
  serviceErrorName: rawError.name,
913
942
  rawErrorMessage,
914
- httpStatusCode,
943
+ httpCode,
915
944
  });
916
945
  }
917
946
  }
@@ -926,16 +955,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
926
955
  SDP_OFFER_CREATION_ERROR_MAP[causeType] || SDP_OFFER_CREATION_ERROR_MAP.GENERAL,
927
956
  serviceErrorName: rawError.name,
928
957
  rawErrorMessage,
929
- httpStatusCode,
958
+ httpCode,
930
959
  });
931
960
  }
932
961
 
933
- const serviceErrorCode =
934
- rawError?.error?.body?.errorCode ||
935
- rawError?.body?.errorCode ||
936
- rawError?.body?.code ||
937
- rawError?.body?.reason?.reasonCode;
938
-
939
962
  if (serviceErrorCode) {
940
963
  const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];
941
964
  if (clientErrorCode && !payload) {
@@ -943,17 +966,30 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
943
966
  clientErrorCode,
944
967
  serviceErrorCode,
945
968
  rawErrorMessage,
946
- httpStatusCode,
969
+ httpCode,
947
970
  });
948
971
  }
972
+ }
949
973
 
974
+ const locusHttpClientErrorCode = LOCUS_HTTP_STATUS_TO_CLIENT_ERROR_CODE[httpCode];
975
+ const requestUrl = rawError.options?.uri || rawError.options?.url;
976
+ if (locusHttpClientErrorCode && !payload && requestUrl?.includes('locus')) {
977
+ payload = this.getErrorPayloadForClientErrorCode({
978
+ clientErrorCode: locusHttpClientErrorCode,
979
+ serviceErrorCode,
980
+ rawErrorMessage,
981
+ httpCode,
982
+ });
983
+ }
984
+
985
+ if (serviceErrorCode) {
950
986
  // by default, if it is locus error, return new locus err
951
987
  if (isLocusServiceErrorCode(serviceErrorCode) && !payload) {
952
988
  payload = this.getErrorPayloadForClientErrorCode({
953
989
  clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,
954
990
  serviceErrorCode,
955
991
  rawErrorMessage,
956
- httpStatusCode,
992
+ httpCode,
957
993
  });
958
994
  }
959
995
  }
@@ -963,7 +999,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
963
999
  clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,
964
1000
  serviceErrorCode,
965
1001
  rawErrorMessage,
966
- httpStatusCode,
1002
+ httpCode,
967
1003
  });
968
1004
  }
969
1005
 
@@ -973,7 +1009,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
973
1009
  serviceErrorCode,
974
1010
  payloadOverrides: rawError.payloadOverrides,
975
1011
  rawErrorMessage,
976
- httpStatusCode,
1012
+ httpCode,
977
1013
  });
978
1014
  }
979
1015
 
@@ -983,7 +1019,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
983
1019
  serviceErrorCode,
984
1020
  payloadOverrides: rawError.payloadOverrides,
985
1021
  rawErrorMessage,
986
- httpStatusCode,
1022
+ httpCode,
987
1023
  });
988
1024
  }
989
1025
 
@@ -995,7 +1031,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
995
1031
  serviceErrorName: rawError?.name,
996
1032
  payloadOverrides: rawError.payloadOverrides,
997
1033
  rawErrorMessage,
998
- httpStatusCode,
1034
+ httpCode,
999
1035
  });
1000
1036
  }
1001
1037
 
@@ -8,6 +8,8 @@ export const CALL_DIAGNOSTIC_LOG_IDENTIFIER = 'call-diagnostic-events -> ';
8
8
  export const CALL_FEATURE_LOG_IDENTIFIER = 'call-diagnostic-events-feature -> ';
9
9
 
10
10
  export const AUTHENTICATION_FAILED_CODE = 1010;
11
+ export const LOCUS_RATE_LIMITED_OUTGOING_CLIENT_CODE = 1002;
12
+ export const LOCUS_UNAVAILABLE_CLIENT_CODE = 1003;
11
13
  export const NETWORK_ERROR = 1026;
12
14
  export const NEW_LOCUS_ERROR_CLIENT_CODE = 4008;
13
15
  export const MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE = 4100;
package/src/config.js CHANGED
@@ -18,6 +18,10 @@ export default {
18
18
  unhandledExceptionTelemetry: {
19
19
  enabled: false,
20
20
  },
21
+ networkTelemetry: {
22
+ enabled: false,
23
+ intervalMs: 10 * 60 * 1_000,
24
+ },
21
25
  batcherWait: 500,
22
26
  batcherMaxCalls: 50,
23
27
  batcherMaxWait: 1500,
package/src/index.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
4
 
5
+ /* eslint-disable valid-jsdoc */
6
+
5
7
  import {registerInternalPlugin} from '@webex/webex-core';
6
8
 
7
9
  import Metrics from './metrics';
@@ -35,6 +37,13 @@ import PreLoginMetrics from './prelogin-metrics';
35
37
 
36
38
  registerInternalPlugin('metrics', Metrics, {
37
39
  config,
40
+ /**
41
+ * Stops network telemetry before SDK logout.
42
+ * @returns
43
+ */
44
+ onBeforeLogout() {
45
+ return this.stopNetworkTelemetry();
46
+ },
38
47
  });
39
48
 
40
49
  registerInternalPlugin('newMetrics', NewMetrics, {