Add OpenTelemetry events for PeerConnection state changes / errors
Creates a new class to represent individual calls and adds the listeners there. Requires https://github.com/matrix-org/matrix-js-sdk/pull/3251 Based on https://github.com/vector-im/element-call/pull/974
This commit is contained in:
parent
3b06258e40
commit
c824ea6f9a
2 changed files with 109 additions and 14 deletions
103
src/otel/OTelCall.ts
Normal file
103
src/otel/OTelCall.ts
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
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(
|
||||
"iceconnectionstatechange",
|
||||
this.onIceConnectionStateChanged
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
|
@ -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<string, CallTrackingInfo>();
|
||||
private callsByCallId = new Map<string, OTelCall>();
|
||||
private statsReportSpan: {
|
||||
span: Span | undefined;
|
||||
stats: OTelStatsReportEvent[];
|
||||
|
@ -188,12 +182,10 @@ export class OTelGroupCallMembership {
|
|||
// XXX: anonymity
|
||||
span.setAttribute("matrix.call.target.userId", userId);
|
||||
span.setAttribute("matrix.call.target.deviceId", deviceId);
|
||||
this.callsByCallId.set(call.callId, {
|
||||
userId,
|
||||
deviceId,
|
||||
call,
|
||||
span,
|
||||
});
|
||||
this.callsByCallId.set(
|
||||
call.callId,
|
||||
new OTelCall(userId, deviceId, call, span)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue