diff --git a/package.json b/package.json index 86a666f7..a8e5bfc5 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "i18next-browser-languagedetector": "^6.1.8", "i18next-http-backend": "^1.4.4", "lodash": "^4.17.21", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#fe79a6fa7ca50fc7d078e11826b5539bb0822c45", + "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#e89467c9fbf98182def2088a947155f30fdc7d1f", "matrix-widget-api": "^1.3.1", "mermaid": "^8.13.8", "normalize.css": "^8.0.1", diff --git a/src/otel/OTelCall.ts b/src/otel/OTelCall.ts new file mode 100644 index 00000000..79cc38d5 --- /dev/null +++ b/src/otel/OTelCall.ts @@ -0,0 +1,119 @@ +/* +Copyright 2023 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Span } from "@opentelemetry/api"; +import { MatrixCall } from "matrix-js-sdk"; +import { CallEvent } from "matrix-js-sdk/src/webrtc/call"; + +import { ObjectFlattener } from "./ObjectFlattener"; + +/** + * Tracks an individual call within a group call, either to a full-mesh peer or a focus + */ +export class OTelCall { + constructor( + public userId: string, + public deviceId: string, + public call: MatrixCall, + public span: Span + ) { + if (call.peerConn) { + this.addCallPeerConnListeners(); + } else { + this.call.once( + CallEvent.PeerConnectionCreated, + this.addCallPeerConnListeners + ); + } + } + + public dispose() { + this.call.peerConn.removeEventListener( + "connectionstatechange", + this.onCallConnectionStateChanged + ); + this.call.peerConn.removeEventListener( + "signalingstatechange", + this.onCallSignalingStateChanged + ); + this.call.peerConn.removeEventListener( + "iceconnectionstatechange", + this.onIceConnectionStateChanged + ); + this.call.peerConn.removeEventListener( + "icegatheringstatechange", + this.onIceGatheringStateChanged + ); + this.call.peerConn.removeEventListener( + "icecandidateerror", + this.onIceCandidateError + ); + } + + private addCallPeerConnListeners = (): void => { + this.call.peerConn.addEventListener( + "connectionstatechange", + this.onCallConnectionStateChanged + ); + this.call.peerConn.addEventListener( + "signalingstatechange", + this.onCallSignalingStateChanged + ); + this.call.peerConn.addEventListener( + "iceconnectionstatechange", + this.onIceConnectionStateChanged + ); + this.call.peerConn.addEventListener( + "icegatheringstatechange", + this.onIceGatheringStateChanged + ); + this.call.peerConn.addEventListener( + "icecandidateerror", + this.onIceCandidateError + ); + }; + + public onCallConnectionStateChanged = (): void => { + this.span.addEvent("matrix.call.callConnectionStateChange", { + callConnectionState: this.call.peerConn.connectionState, + }); + }; + + public onCallSignalingStateChanged = (): void => { + this.span.addEvent("matrix.call.callSignalingStateChange", { + callSignalingState: this.call.peerConn.signalingState, + }); + }; + + public onIceConnectionStateChanged = (): void => { + this.span.addEvent("matrix.call.iceConnectionStateChange", { + iceConnectionState: this.call.peerConn.iceConnectionState, + }); + }; + + public onIceGatheringStateChanged = (): void => { + this.span.addEvent("matrix.call.iceGatheringStateChange", { + iceGatheringState: this.call.peerConn.iceGatheringState, + }); + }; + + public onIceCandidateError = (ev: Event): void => { + const flatObject = {}; + ObjectFlattener.flattenObjectRecursive(ev, flatObject, "error.", 0); + + this.span.addEvent("matrix.call.iceCandidateError", flatObject); + }; +} diff --git a/src/otel/OTelGroupCallMembership.ts b/src/otel/OTelGroupCallMembership.ts index 49c9354d..8aa24c74 100644 --- a/src/otel/OTelGroupCallMembership.ts +++ b/src/otel/OTelGroupCallMembership.ts @@ -43,6 +43,7 @@ import { setSpan } from "@opentelemetry/api/build/esm/trace/context-utils"; import { ElementCallOpenTelemetry } from "./otel"; import { ObjectFlattener } from "./ObjectFlattener"; +import { OTelCall } from "./OTelCall"; /** * Flattens out an object into a single layer with components @@ -86,13 +87,6 @@ function flattenVoipEventRecursive( } } -interface CallTrackingInfo { - userId: string; - deviceId: string; - call: MatrixCall; - span: Span; -} - /** * Represent the span of time which we intend to be joined to a group call */ @@ -102,7 +96,7 @@ export class OTelGroupCallMembership { private myUserId = "unknown"; private myDeviceId: string; private myMember?: RoomMember; - private callsByCallId = new Map(); + private callsByCallId = new Map(); private statsReportSpan: { span: Span | undefined; stats: OTelStatsReportEvent[]; @@ -188,16 +182,13 @@ export class OTelGroupCallMembership { // XXX: anonymity span.setAttribute("matrix.call.target.userId", userId); span.setAttribute("matrix.call.target.deviceId", deviceId); - const displayName = this.groupCall.room.getMember(userId)?.name ?? "unknown"; span.setAttribute("matrix.call.target.displayName", displayName); - this.callsByCallId.set(call.callId, { - userId, - deviceId, - call, - span, - }); + this.callsByCallId.set( + call.callId, + new OTelCall(userId, deviceId, call, span) + ); } } } diff --git a/yarn.lock b/yarn.lock index d98a26fe..84a1c952 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10550,9 +10550,9 @@ matrix-events-sdk@0.0.1: resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd" integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#fe79a6fa7ca50fc7d078e11826b5539bb0822c45": +"matrix-js-sdk@github:matrix-org/matrix-js-sdk#e89467c9fbf98182def2088a947155f30fdc7d1f": version "24.0.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/fe79a6fa7ca50fc7d078e11826b5539bb0822c45" + resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/e89467c9fbf98182def2088a947155f30fdc7d1f" dependencies: "@babel/runtime" "^7.12.5" "@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.5"