Slightly evolved but not-yet-working OpenTelemetry

More usefully, including docker config for starting a CORS enabled
OTLP collector so we don't have to use zipkin.
This commit is contained in:
David Baker
2023-03-15 14:35:10 +00:00
parent 4c59638d00
commit 0cca5ae174
5 changed files with 370 additions and 0 deletions

96
src/otel/otel.ts Normal file
View File

@@ -0,0 +1,96 @@
/* document-load.ts|js file - the code is the same for both the languages */
import {
ConsoleSpanExporter,
SimpleSpanProcessor,
} from "@opentelemetry/sdk-trace-base";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
import opentelemetry from "@opentelemetry/api";
import { Context } from "@opentelemetry/api";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { PosthogSpanExporter } from "../analytics/OtelPosthogExporter";
const SERVICE_NAME = "element-call";
const otlpExporter = new OTLPTraceExporter();
const consoleExporter = new ConsoleSpanExporter();
const posthogExporter = new PosthogSpanExporter();
// This is how we can make Jaeger show a reaonsable service in the dropdown on the left.
const providerConfig = {
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: SERVICE_NAME,
}),
};
const provider = new WebTracerProvider(providerConfig);
provider.addSpanProcessor(new SimpleSpanProcessor(otlpExporter));
provider.addSpanProcessor(new SimpleSpanProcessor(posthogExporter));
provider.addSpanProcessor(new SimpleSpanProcessor(consoleExporter));
// This is not the serviceName shown in jaeger
export const tracer = opentelemetry.trace.getTracer(
"my-element-call-otl-tracer"
);
class CallTracer {
// We create one tracer class for each main context.
// Even if differnt tracer classes overlap in time space, we might want to visulaize them seperately.
// The Call Tracer should only contain spans/events that are relevant to understand the procedure of the individual candidates.
// Another Tracer Class (for example a ConnectionTracer) can contain a very granular list of all steps to connect to a call.
private callSpan;
private callContext;
private muteSpan?;
public startGroupCall(groupCallId: string) {}
public startCall(callId: string): Context {
// The main context will be set when initiating the main/parent span.
// Create an initial context with the callId param
const callIdContext = opentelemetry.context
.active()
.setValue(Symbol("callId"), callId);
// Create the main span that tracks the whole call
this.callSpan = tracer.startSpan("otel_callSpan", undefined, callIdContext);
// 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)
this.callContext = opentelemetry.trace.setSpan(
opentelemetry.context.active(),
this.callSpan
);
// Here we start a very short span. This is a hack to trigger the posthog exporter.
// Only ended spans are processed by the exporter.
// We want the exporter to know that a call has started
const startCallSpan = tracer.startSpan(
"otel_startCallSpan",
undefined,
this.callContext
);
startCallSpan.end();
}
public muteMic(muteState: boolean) {
if (muteState) {
this.muteSpan = tracer.startSpan(
"otel_muteSpan",
undefined,
this.callContext
);
} else if (this.muteSpan) {
this.muteSpan.end();
this.muteSpan = null;
}
}
public endCall() {
this.callSpan?.end();
}
}
export const callTracer = new CallTracer();