From f8f5d2011d207c2c5e1add80b6c61b6fe3a28ae3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 17 Mar 2023 17:01:59 +0000 Subject: [PATCH] Add CORS to jaeger query endpoint and make spans nested Adds an nginx in front of the query endpoint so we can use stalk without faffing with browser extension to bypass CORS. Also make the spans correctly have the call membership span as parent, which they didn't because we hadn't set the span at the point we made the context. --- config/otel_dev/README.md | 9 ++++++++ config/otel_dev/docker-compose.yaml | 6 +++++ src/otel/OTelGroupCallMembership.ts | 35 ++++++++++++++++------------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/config/otel_dev/README.md b/config/otel_dev/README.md index 04690c7..8fe102d 100644 --- a/config/otel_dev/README.md +++ b/config/otel_dev/README.md @@ -6,4 +6,13 @@ traces into the jaeger. Jaeger has a built-in OpenTelemetry collector, but it ca configured to send CORS headers so can't be used from a browser. This sets the config on the collector to send CORS headers. +This also adds an nginx to add CORS headers to the jaeger query endpoint, such that it can +be used from webapps like stalk (https://deniz.co/stalk/). The CORS enabled endpoint is +exposed on port 16687. To use stalk, you should simply be able to navigate to it and add +http://127.0.0.1:16687/api as a data source. + +(Yes, we could enable the OTLP collector in jaeger all-in-one and passed this through +the nginx to enable CORS too, rather than running a separate collector. There's no reason +it's done this way other than that I'd already set up the separate collector.) + Running `docker compose up` in this directory should be all you need. diff --git a/config/otel_dev/docker-compose.yaml b/config/otel_dev/docker-compose.yaml index 40de4a5..0b43abe 100644 --- a/config/otel_dev/docker-compose.yaml +++ b/config/otel_dev/docker-compose.yaml @@ -21,3 +21,9 @@ services: - "55670:55679" # zpages extension depends_on: - jaeger-all-in-one + nginx: + image: nginxinc/nginx-unprivileged:latest + volumes: + - ./nginx_otel.conf:/etc/nginx/conf.d/default.conf:ro + ports: + - "16687:8080" diff --git a/src/otel/OTelGroupCallMembership.ts b/src/otel/OTelGroupCallMembership.ts index 5a8dae3..886b4ec 100644 --- a/src/otel/OTelGroupCallMembership.ts +++ b/src/otel/OTelGroupCallMembership.ts @@ -15,7 +15,12 @@ limitations under the License. */ import opentelemetry, { Context, Span } from "@opentelemetry/api"; -import { GroupCall, MatrixClient, MatrixEvent } from "matrix-js-sdk"; +import { + GroupCall, + MatrixClient, + MatrixEvent, + RoomMember, +} from "matrix-js-sdk"; import { VoipEvent } from "matrix-js-sdk/src/webrtc/call"; import { tracer } from "./otel"; @@ -63,27 +68,27 @@ function setSpanEventAttributesRecursive( export class OTelGroupCallMembership { private context: Context; private callMembershipSpan: Span; + private myUserId: string; + private myMember: RoomMember; - constructor(groupCall: GroupCall, client: MatrixClient) { + constructor(private groupCall: GroupCall, client: MatrixClient) { + this.myUserId = client.getUserId(); + this.myMember = groupCall.room.getMember(client.getUserId()); + } + + public onJoinCall() { // Create a new call based on the callIdContext. This context also has a span assigned to it. // Other spans can use this context to extract the parent span. // (When passing this context to startSpan the started span will use the span set in the context (in this case the callSpan) as the parent) - const myMember = groupCall.room.getMember(client.getUserId()); + // Create the main span that tracks the time we intend to be in the call + this.callMembershipSpan = tracer.startSpan("otel_groupCallMembershipSpan"); + this.context = opentelemetry.trace .setSpan(opentelemetry.context.active(), this.callMembershipSpan) - .setValue(Symbol("confId"), groupCall.groupCallId) - .setValue(Symbol("matrix.userId"), client.getUserId()) - .setValue(Symbol("matrix.displayName"), myMember.name); - } - - public onJoinCall() { - // Create the main span that tracks the time we intend to be in the call - this.callMembershipSpan = tracer.startSpan( - "otel_groupCallMembershipSpan", - undefined, - this.context - ); + .setValue(Symbol("confId"), this.groupCall.groupCallId) + .setValue(Symbol("matrix.userId"), this.myUserId) + .setValue(Symbol("matrix.displayName"), this.myMember.name); // Here we start a very short span. This is a hack to trigger the posthog exporter. // Only ended spans are processed by the exporter.