Merge pull request #984 from vector-im/dbkr/otel_peerconn_events
Add OpenTelemetry events for PeerConnection state changes / errors
This commit is contained in:
commit
7b88c4330e
4 changed files with 128 additions and 18 deletions
|
@ -53,7 +53,7 @@
|
||||||
"i18next-browser-languagedetector": "^6.1.8",
|
"i18next-browser-languagedetector": "^6.1.8",
|
||||||
"i18next-http-backend": "^1.4.4",
|
"i18next-http-backend": "^1.4.4",
|
||||||
"lodash": "^4.17.21",
|
"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",
|
"matrix-widget-api": "^1.3.1",
|
||||||
"mermaid": "^8.13.8",
|
"mermaid": "^8.13.8",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
|
|
119
src/otel/OTelCall.ts
Normal file
119
src/otel/OTelCall.ts
Normal file
|
@ -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);
|
||||||
|
};
|
||||||
|
}
|
|
@ -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,16 +182,13 @@ 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);
|
||||||
|
|
||||||
const displayName =
|
const displayName =
|
||||||
this.groupCall.room.getMember(userId)?.name ?? "unknown";
|
this.groupCall.room.getMember(userId)?.name ?? "unknown";
|
||||||
span.setAttribute("matrix.call.target.displayName", displayName);
|
span.setAttribute("matrix.call.target.displayName", displayName);
|
||||||
this.callsByCallId.set(call.callId, {
|
this.callsByCallId.set(
|
||||||
userId,
|
call.callId,
|
||||||
deviceId,
|
new OTelCall(userId, deviceId, call, span)
|
||||||
call,
|
);
|
||||||
span,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
|
||||||
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
|
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"
|
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:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.5"
|
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.5"
|
||||||
|
|
Loading…
Add table
Reference in a new issue