38 lines · 1.9 KB · TypeScript
RawDownload
// ---------------------------------------------------------------------------// Browser tracing layer — extracted from client.tsx so the export path itself// is testable: what leaves the page is exactly what this layer serializes.// --------------------------------------------------------------------------- import { FetchHttpClient, HttpClient } from "effect/unstable/http";import { OtlpTracer } from "effect/unstable/observability";import * as Layer from "effect/Layer"; import { UrlRedactingOtlpSerializationJson } from "@executor-js/sdk/shared"; /** * OTLP tracing for the browser client, exporting to `tracesUrl`. * * The serialization layer is the redacting one from `@executor-js/sdk`: the * page exports its own spans (no server-side span processor ever sees them), * so credential-bearing URL components — query values, userinfo, fragments, * and URLs embedded in error text — are scrubbed at the serialization seam * before the batch leaves the page. * * `TracerDisabledWhen` must be URL-scoped, NOT a blanket `() => true` on the * exporter's client: addGlobalLayer leaks provided references into the shared * runtime context, and a blanket predicate silently disables tracing for * EVERY HttpClient — no spans, no traceparent, no export, no error. * URL-scoped, the leak is the desired behavior: any client posting to the * OTLP endpoint (the exporter) goes untraced, everything else is traced. */export const makeBrowserTracingLayer = (tracesUrl: string): Layer.Layer<never> =>  Layer.mergeAll(    OtlpTracer.layer({      url: tracesUrl,      resource: { serviceName: "executor-web" },      // Browser sessions are short; the 5s default loses the tail spans when      // the tab closes.      exportInterval: "1 second",    }).pipe(Layer.provide(UrlRedactingOtlpSerializationJson), Layer.provide(FetchHttpClient.layer)),    Layer.succeed(HttpClient.TracerDisabledWhen, (request) => request.url.includes("/v1/traces")),  );