Version using events for call joins / leaves and matrix events
This is probably conceptually nicer although isn't quite as nice in the jaeger / stalk UI. Also this may no loger work with the posthog exporter (unsure what it will do with events on spans).
This commit is contained in:
parent
2d91b43a7d
commit
63ede0b51a
1 changed files with 28 additions and 50 deletions
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import opentelemetry, { Context, Span } from "@opentelemetry/api";
|
import opentelemetry, { Span, Attributes } from "@opentelemetry/api";
|
||||||
import {
|
import {
|
||||||
GroupCall,
|
GroupCall,
|
||||||
MatrixClient,
|
MatrixClient,
|
||||||
|
@ -26,20 +26,25 @@ import { VoipEvent } from "matrix-js-sdk/src/webrtc/call";
|
||||||
import { tracer } from "./otel";
|
import { tracer } from "./otel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively sets the contents of a todevice event object as attributes on a span
|
* Flattens out an object into a single layer with components
|
||||||
|
* of the key separated by dots
|
||||||
*/
|
*/
|
||||||
function setNestedAttributesFromEvent(span: Span, event: VoipEvent) {
|
function flattenVoipEvent(event: VoipEvent): Attributes {
|
||||||
setSpanEventAttributesRecursive(
|
const flatObject = {};
|
||||||
span,
|
|
||||||
|
flattenVoipEventRecursive(
|
||||||
event as unknown as Record<string, unknown>, // XXX Types
|
event as unknown as Record<string, unknown>, // XXX Types
|
||||||
|
flatObject,
|
||||||
"matrix.event.",
|
"matrix.event.",
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return flatObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSpanEventAttributesRecursive(
|
function flattenVoipEventRecursive(
|
||||||
span: Span,
|
|
||||||
obj: Record<string, unknown>,
|
obj: Record<string, unknown>,
|
||||||
|
flatObject: Record<string, unknown>,
|
||||||
prefix: string,
|
prefix: string,
|
||||||
depth: number
|
depth: number
|
||||||
) {
|
) {
|
||||||
|
@ -50,11 +55,11 @@ function setSpanEventAttributesRecursive(
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(obj)) {
|
for (const [k, v] of Object.entries(obj)) {
|
||||||
if (["string", "number"].includes(typeof v)) {
|
if (["string", "number"].includes(typeof v)) {
|
||||||
span.setAttribute(prefix + k, v as string | number);
|
flatObject[prefix + k] = v;
|
||||||
} else if (typeof v === "object") {
|
} else if (typeof v === "object") {
|
||||||
setSpanEventAttributesRecursive(
|
flattenVoipEventRecursive(
|
||||||
span,
|
|
||||||
v as Record<string, unknown>,
|
v as Record<string, unknown>,
|
||||||
|
flatObject,
|
||||||
prefix + k + ".",
|
prefix + k + ".",
|
||||||
depth + 1
|
depth + 1
|
||||||
);
|
);
|
||||||
|
@ -66,7 +71,6 @@ function setSpanEventAttributesRecursive(
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
export class OTelGroupCallMembership {
|
export class OTelGroupCallMembership {
|
||||||
private context: Context;
|
|
||||||
private callMembershipSpan: Span;
|
private callMembershipSpan: Span;
|
||||||
private myUserId: string;
|
private myUserId: string;
|
||||||
private myMember: RoomMember;
|
private myMember: RoomMember;
|
||||||
|
@ -83,7 +87,6 @@ export class OTelGroupCallMembership {
|
||||||
|
|
||||||
// Create the main span that tracks the time we intend to be in the call
|
// Create the main span that tracks the time we intend to be in the call
|
||||||
this.callMembershipSpan = tracer.startSpan("otel_groupCallMembershipSpan");
|
this.callMembershipSpan = tracer.startSpan("otel_groupCallMembershipSpan");
|
||||||
|
|
||||||
this.callMembershipSpan.setAttribute(
|
this.callMembershipSpan.setAttribute(
|
||||||
"matrix.confId",
|
"matrix.confId",
|
||||||
this.groupCall.groupCallId
|
this.groupCall.groupCallId
|
||||||
|
@ -94,30 +97,16 @@ export class OTelGroupCallMembership {
|
||||||
this.myMember.name
|
this.myMember.name
|
||||||
);
|
);
|
||||||
|
|
||||||
this.context = opentelemetry.trace.setSpan(
|
opentelemetry.trace.setSpan(
|
||||||
opentelemetry.context.active(),
|
opentelemetry.context.active(),
|
||||||
this.callMembershipSpan
|
this.callMembershipSpan
|
||||||
);
|
);
|
||||||
|
|
||||||
// Here we start a very short span. This is a hack to trigger the posthog exporter.
|
this.callMembershipSpan.addEvent("matrix.joinCall");
|
||||||
// Only ended spans are processed by the exporter.
|
|
||||||
// We want the exporter to know that a call has started
|
|
||||||
const joinCallSpan = tracer.startSpan(
|
|
||||||
"otel_joinCallSpan",
|
|
||||||
undefined,
|
|
||||||
this.context
|
|
||||||
);
|
|
||||||
joinCallSpan.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLeaveCall() {
|
public onLeaveCall() {
|
||||||
// A very short span to represent us leaving the call
|
this.callMembershipSpan.addEvent("matrix.leaveCall");
|
||||||
const startCallSpan = tracer.startSpan(
|
|
||||||
"otel_leaveCallSpan",
|
|
||||||
undefined,
|
|
||||||
this.context
|
|
||||||
);
|
|
||||||
startCallSpan.end();
|
|
||||||
|
|
||||||
// and end the main span to indicate we've left
|
// and end the main span to indicate we've left
|
||||||
if (this.callMembershipSpan) this.callMembershipSpan.end();
|
if (this.callMembershipSpan) this.callMembershipSpan.end();
|
||||||
|
@ -128,17 +117,14 @@ export class OTelGroupCallMembership {
|
||||||
!event ||
|
!event ||
|
||||||
(!event.getType().startsWith("m.call") &&
|
(!event.getType().startsWith("m.call") &&
|
||||||
!event.getType().startsWith("org.matrix.msc3401.call"))
|
!event.getType().startsWith("org.matrix.msc3401.call"))
|
||||||
)
|
) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const span = tracer.startSpan(
|
this.callMembershipSpan.addEvent(
|
||||||
`otel_onRoomStateEvent_${event.getType()}`,
|
`otel_onRoomStateEvent_${event.getType()}`,
|
||||||
undefined,
|
flattenVoipEvent(event.getContent())
|
||||||
this.context
|
|
||||||
);
|
);
|
||||||
|
|
||||||
setNestedAttributesFromEvent(span, event.getContent());
|
|
||||||
span.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onSendEvent(event: VoipEvent) {
|
public onSendEvent(event: VoipEvent) {
|
||||||
|
@ -146,23 +132,15 @@ export class OTelGroupCallMembership {
|
||||||
if (!eventType.startsWith("m.call")) return;
|
if (!eventType.startsWith("m.call")) return;
|
||||||
|
|
||||||
if (event.type === "toDevice") {
|
if (event.type === "toDevice") {
|
||||||
const span = tracer.startSpan(
|
this.callMembershipSpan.addEvent(
|
||||||
`otel_sendToDeviceEvent_${event.eventType}`,
|
`matrix.sendToDeviceEvent_${event.eventType}`,
|
||||||
undefined,
|
flattenVoipEvent(event)
|
||||||
this.context
|
|
||||||
);
|
);
|
||||||
|
|
||||||
setNestedAttributesFromEvent(span, event);
|
|
||||||
span.end();
|
|
||||||
} else if (event.type === "sendEvent") {
|
} else if (event.type === "sendEvent") {
|
||||||
const span = tracer.startSpan(
|
this.callMembershipSpan.addEvent(
|
||||||
`otel_sendToRoomEvent_${event.eventType}`,
|
`matrix.sendToRoomEvent_${event.eventType}`,
|
||||||
undefined,
|
flattenVoipEvent(event)
|
||||||
this.context
|
|
||||||
);
|
);
|
||||||
|
|
||||||
setNestedAttributesFromEvent(span, event);
|
|
||||||
span.end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue