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 { ElementCallOpenTelemetry } from "./otel";
|
||||||
import { ObjectFlattener } from "./ObjectFlattener";
|
import { ObjectFlattener } from "./ObjectFlattener";
|
||||||
|
import { OTelCall } from "./OTelCall";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flattens out an object into a single layer with components
|
* 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
|
* 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 myUserId = "unknown";
|
||||||
private myDeviceId: string;
|
private myDeviceId: string;
|
||||||
private myMember?: RoomMember;
|
private myMember?: RoomMember;
|
||||||
private callsByCallId = new Map<string, CallTrackingInfo>();
|
private callsByCallId = new Map<string, OTelCall>();
|
||||||
private statsReportSpan: {
|
private statsReportSpan: {
|
||||||
span: Span | undefined;
|
span: Span | undefined;
|
||||||
stats: OTelStatsReportEvent[];
|
stats: OTelStatsReportEvent[];
|
||||||
|
@ -188,12 +182,10 @@ export class OTelGroupCallMembership {
|
||||||
// XXX: anonymity
|
// XXX: anonymity
|
||||||
span.setAttribute("matrix.call.target.userId", userId);
|
span.setAttribute("matrix.call.target.userId", userId);
|
||||||
span.setAttribute("matrix.call.target.deviceId", deviceId);
|
span.setAttribute("matrix.call.target.deviceId", deviceId);
|
||||||
this.callsByCallId.set(call.callId, {
|
this.callsByCallId.set(
|
||||||
userId,
|
call.callId,
|
||||||
deviceId,
|
new OTelCall(userId, deviceId, call, span)
|
||||||
call,
|
);
|
||||||
span,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue