@obtrace/browser 2.4.1 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser/index.js
CHANGED
|
@@ -13,7 +13,6 @@ import { installResourceTiming } from "./resources";
|
|
|
13
13
|
import { installLongTaskDetection } from "./longtasks";
|
|
14
14
|
import { installMemoryTracking } from "./memory";
|
|
15
15
|
import { installOfflineSupport } from "./offline";
|
|
16
|
-
import { installSupabaseFetchInterceptor } from "./supabase-intercept";
|
|
17
16
|
const instances = new Set();
|
|
18
17
|
const replayBuffers = new Set();
|
|
19
18
|
let currentUser = null;
|
|
@@ -216,7 +215,9 @@ export function initBrowserSDK(config) {
|
|
|
216
215
|
cleanups.push(installResourceTiming(meter));
|
|
217
216
|
cleanups.push(installLongTaskDetection(tracer));
|
|
218
217
|
cleanups.push(installMemoryTracking(meter));
|
|
219
|
-
|
|
218
|
+
// supabase-intercept removed: child spans are now created inside
|
|
219
|
+
// FetchInstrumentation's applyCustomAttributesOnSpan callback so all
|
|
220
|
+
// spans share the same traceId (single connected trace per request).
|
|
220
221
|
if (config.captureConsole !== false) {
|
|
221
222
|
cleanups.push(installConsoleCapture(tracer, logger, replay.sessionId));
|
|
222
223
|
}
|
|
@@ -29722,13 +29722,59 @@ function setupOtelWeb(config) {
|
|
|
29722
29722
|
});
|
|
29723
29723
|
const ingestPattern = new RegExp(`^${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`);
|
|
29724
29724
|
const instrumentations = [];
|
|
29725
|
-
const
|
|
29725
|
+
const sessionId = config.sessionId || "";
|
|
29726
|
+
const applySupabaseAttrs = (parentSpan, req, result2) => {
|
|
29726
29727
|
try {
|
|
29727
29728
|
const url = typeof req === "string" ? req : req instanceof URL ? req.href : req?.url || "";
|
|
29728
29729
|
const method = req?.method || "GET";
|
|
29729
|
-
if (url
|
|
29730
|
-
|
|
29731
|
-
|
|
29730
|
+
if (!url || !isSupabaseURL(url)) return;
|
|
29731
|
+
enrichSupabaseSpan(parentSpan, url, method);
|
|
29732
|
+
if (sessionId) parentSpan.setAttribute("session.id", sessionId);
|
|
29733
|
+
const parsed = parseSupabaseURL(url, method);
|
|
29734
|
+
if (!parsed) return;
|
|
29735
|
+
const status = typeof result2?.status === "number" ? result2.status : 0;
|
|
29736
|
+
const t = trace.getTracer("@obtrace/sdk-browser", "2.4.0");
|
|
29737
|
+
const synth = { "session.id": sessionId, "supabase.ref": parsed.ref, "span.synthetic": "true" };
|
|
29738
|
+
const parentCtx = trace.setSpan(context.active(), parentSpan);
|
|
29739
|
+
context.with(parentCtx, () => {
|
|
29740
|
+
const gw = t.startSpan("supabase.gateway", {
|
|
29741
|
+
attributes: { ...synth, "http.method": method.toUpperCase(), "http.status_code": status, "peer.service": "supabase.kong" }
|
|
29742
|
+
});
|
|
29743
|
+
const gwCtx = trace.setSpan(context.active(), gw);
|
|
29744
|
+
context.with(gwCtx, () => {
|
|
29745
|
+
if (parsed.service === "postgrest") {
|
|
29746
|
+
const db2 = t.startSpan("supabase.db.query", {
|
|
29747
|
+
attributes: { ...synth, "db.system": "postgresql", "db.operation": parsed.operation, "db.sql.table": parsed.table, "db.statement": parsed.detail, "peer.service": "supabase.postgresql" }
|
|
29748
|
+
});
|
|
29749
|
+
db2.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
|
|
29750
|
+
db2.end();
|
|
29751
|
+
}
|
|
29752
|
+
if (parsed.service === "auth") {
|
|
29753
|
+
const auth = t.startSpan("supabase.auth." + parsed.operation, {
|
|
29754
|
+
attributes: { ...synth, "auth.operation": parsed.operation, "peer.service": "supabase.gotrue" }
|
|
29755
|
+
});
|
|
29756
|
+
auth.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
|
|
29757
|
+
auth.end();
|
|
29758
|
+
}
|
|
29759
|
+
if (parsed.service === "storage") {
|
|
29760
|
+
const stor = t.startSpan("supabase.storage." + parsed.operation, {
|
|
29761
|
+
attributes: { ...synth, "storage.operation": parsed.operation, "peer.service": "supabase.storage" }
|
|
29762
|
+
});
|
|
29763
|
+
stor.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
|
|
29764
|
+
stor.end();
|
|
29765
|
+
}
|
|
29766
|
+
if (parsed.service === "edge-function") {
|
|
29767
|
+
const fnName = parsed.operation.replace("invoke:", "");
|
|
29768
|
+
const fn = t.startSpan("supabase.function." + fnName, {
|
|
29769
|
+
attributes: { ...synth, "faas.name": fnName, "faas.trigger": "http", "peer.service": "supabase.edge-runtime" }
|
|
29770
|
+
});
|
|
29771
|
+
fn.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
|
|
29772
|
+
fn.end();
|
|
29773
|
+
}
|
|
29774
|
+
});
|
|
29775
|
+
gw.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
|
|
29776
|
+
gw.end();
|
|
29777
|
+
});
|
|
29732
29778
|
} catch {
|
|
29733
29779
|
}
|
|
29734
29780
|
};
|
|
@@ -30429,127 +30475,6 @@ function installMemoryTracking(meter) {
|
|
|
30429
30475
|
return () => clearInterval(timer);
|
|
30430
30476
|
}
|
|
30431
30477
|
|
|
30432
|
-
// src/browser/supabase-intercept.ts
|
|
30433
|
-
function installSupabaseFetchInterceptor(tracer, sessionId) {
|
|
30434
|
-
if (typeof window === "undefined" || typeof window.fetch === "undefined") return () => {
|
|
30435
|
-
};
|
|
30436
|
-
const originalFetch = window.fetch;
|
|
30437
|
-
window.fetch = async function(input2, init) {
|
|
30438
|
-
const url = typeof input2 === "string" ? input2 : input2 instanceof URL ? input2.href : input2 instanceof Request ? input2.url : "";
|
|
30439
|
-
if (!url || !isSupabaseURL(url)) {
|
|
30440
|
-
return originalFetch.call(this, input2, init);
|
|
30441
|
-
}
|
|
30442
|
-
const method = init?.method || (input2 instanceof Request ? input2.method : "GET") || "GET";
|
|
30443
|
-
const parsed = parseSupabaseURL(url, method);
|
|
30444
|
-
if (!parsed) {
|
|
30445
|
-
return originalFetch.call(this, input2, init);
|
|
30446
|
-
}
|
|
30447
|
-
const rootSpan = tracer.startSpan(`supabase.${parsed.service} ${parsed.detail}`, {
|
|
30448
|
-
attributes: {
|
|
30449
|
-
"supabase.ref": parsed.ref,
|
|
30450
|
-
"supabase.service": parsed.service,
|
|
30451
|
-
"supabase.operation": parsed.operation,
|
|
30452
|
-
"supabase.detail": parsed.detail,
|
|
30453
|
-
"http.method": method.toUpperCase(),
|
|
30454
|
-
"http.url": url.split("?")[0],
|
|
30455
|
-
"peer.service": `supabase.${parsed.service}`,
|
|
30456
|
-
"session.id": sessionId,
|
|
30457
|
-
...parsed.service === "postgrest" ? {
|
|
30458
|
-
"db.system": "postgresql",
|
|
30459
|
-
"db.operation": parsed.operation,
|
|
30460
|
-
"db.sql.table": parsed.table
|
|
30461
|
-
} : {}
|
|
30462
|
-
}
|
|
30463
|
-
});
|
|
30464
|
-
const rootCtx = trace.setSpan(context.active(), rootSpan);
|
|
30465
|
-
const startMs = performance.now();
|
|
30466
|
-
try {
|
|
30467
|
-
const response = await originalFetch.call(this, input2, init);
|
|
30468
|
-
const durationMs = performance.now() - startMs;
|
|
30469
|
-
rootSpan.setAttribute("http.status_code", response.status);
|
|
30470
|
-
rootSpan.setAttribute("supabase.duration_ms", Math.round(durationMs));
|
|
30471
|
-
context.with(rootCtx, () => {
|
|
30472
|
-
createChildSpans(tracer, parsed, method, response.status, durationMs, sessionId);
|
|
30473
|
-
});
|
|
30474
|
-
if (response.status >= 400) {
|
|
30475
|
-
rootSpan.setStatus({ code: SpanStatusCode.ERROR, message: `HTTP ${response.status}` });
|
|
30476
|
-
addBreadcrumb({ timestamp: Date.now(), category: "supabase", message: `${parsed.detail} \u2192 ${response.status}`, level: "error" });
|
|
30477
|
-
} else {
|
|
30478
|
-
rootSpan.setStatus({ code: SpanStatusCode.OK });
|
|
30479
|
-
addBreadcrumb({ timestamp: Date.now(), category: "supabase", message: `${parsed.detail} \u2192 ${response.status} (${Math.round(durationMs)}ms)`, level: "info" });
|
|
30480
|
-
}
|
|
30481
|
-
rootSpan.end();
|
|
30482
|
-
return response;
|
|
30483
|
-
} catch (err) {
|
|
30484
|
-
rootSpan.setStatus({ code: SpanStatusCode.ERROR, message: err instanceof Error ? err.message : "fetch failed" });
|
|
30485
|
-
if (err instanceof Error) rootSpan.recordException(err);
|
|
30486
|
-
rootSpan.end();
|
|
30487
|
-
addBreadcrumb({ timestamp: Date.now(), category: "supabase", message: `${parsed.detail} \u2192 FAILED`, level: "error" });
|
|
30488
|
-
throw err;
|
|
30489
|
-
}
|
|
30490
|
-
};
|
|
30491
|
-
return () => {
|
|
30492
|
-
window.fetch = originalFetch;
|
|
30493
|
-
};
|
|
30494
|
-
}
|
|
30495
|
-
function createChildSpans(tracer, parsed, method, status, _durationMs, sessionId) {
|
|
30496
|
-
const synth = { "session.id": sessionId, "supabase.ref": parsed.ref, "span.synthetic": "true" };
|
|
30497
|
-
const gatewaySpan = tracer.startSpan("supabase.gateway", {
|
|
30498
|
-
attributes: {
|
|
30499
|
-
...synth,
|
|
30500
|
-
"http.method": method.toUpperCase(),
|
|
30501
|
-
"http.status_code": status,
|
|
30502
|
-
"peer.service": "supabase.kong"
|
|
30503
|
-
}
|
|
30504
|
-
});
|
|
30505
|
-
const gatewayCtx = trace.setSpan(context.active(), gatewaySpan);
|
|
30506
|
-
context.with(gatewayCtx, () => {
|
|
30507
|
-
if (parsed.service === "postgrest") {
|
|
30508
|
-
const dbSpan = tracer.startSpan("supabase.db.query", {
|
|
30509
|
-
attributes: {
|
|
30510
|
-
...synth,
|
|
30511
|
-
"db.system": "postgresql",
|
|
30512
|
-
"db.operation": parsed.operation,
|
|
30513
|
-
"db.sql.table": parsed.table,
|
|
30514
|
-
"db.statement": parsed.detail,
|
|
30515
|
-
"peer.service": "supabase.postgresql"
|
|
30516
|
-
}
|
|
30517
|
-
});
|
|
30518
|
-
if (status >= 400) dbSpan.setStatus({ code: SpanStatusCode.ERROR, message: `HTTP ${status}` });
|
|
30519
|
-
else dbSpan.setStatus({ code: SpanStatusCode.OK });
|
|
30520
|
-
dbSpan.end();
|
|
30521
|
-
}
|
|
30522
|
-
if (parsed.service === "auth") {
|
|
30523
|
-
const authSpan = tracer.startSpan("supabase.auth." + parsed.operation, {
|
|
30524
|
-
attributes: { ...synth, "auth.operation": parsed.operation, "peer.service": "supabase.gotrue" }
|
|
30525
|
-
});
|
|
30526
|
-
if (status >= 400) authSpan.setStatus({ code: SpanStatusCode.ERROR, message: `HTTP ${status}` });
|
|
30527
|
-
else authSpan.setStatus({ code: SpanStatusCode.OK });
|
|
30528
|
-
authSpan.end();
|
|
30529
|
-
}
|
|
30530
|
-
if (parsed.service === "storage") {
|
|
30531
|
-
const storageSpan = tracer.startSpan("supabase.storage." + parsed.operation, {
|
|
30532
|
-
attributes: { ...synth, "storage.operation": parsed.operation, "peer.service": "supabase.storage" }
|
|
30533
|
-
});
|
|
30534
|
-
if (status >= 400) storageSpan.setStatus({ code: SpanStatusCode.ERROR, message: `HTTP ${status}` });
|
|
30535
|
-
else storageSpan.setStatus({ code: SpanStatusCode.OK });
|
|
30536
|
-
storageSpan.end();
|
|
30537
|
-
}
|
|
30538
|
-
if (parsed.service === "edge-function") {
|
|
30539
|
-
const fnName = parsed.operation.replace("invoke:", "");
|
|
30540
|
-
const fnSpan = tracer.startSpan("supabase.function." + fnName, {
|
|
30541
|
-
attributes: { ...synth, "faas.name": fnName, "faas.trigger": "http", "peer.service": "supabase.edge-runtime" }
|
|
30542
|
-
});
|
|
30543
|
-
if (status >= 400) fnSpan.setStatus({ code: SpanStatusCode.ERROR, message: `HTTP ${status}` });
|
|
30544
|
-
else fnSpan.setStatus({ code: SpanStatusCode.OK });
|
|
30545
|
-
fnSpan.end();
|
|
30546
|
-
}
|
|
30547
|
-
});
|
|
30548
|
-
if (status >= 400) gatewaySpan.setStatus({ code: SpanStatusCode.ERROR, message: `HTTP ${status}` });
|
|
30549
|
-
else gatewaySpan.setStatus({ code: SpanStatusCode.OK });
|
|
30550
|
-
gatewaySpan.end();
|
|
30551
|
-
}
|
|
30552
|
-
|
|
30553
30478
|
// src/browser/index.ts
|
|
30554
30479
|
var instances = /* @__PURE__ */ new Set();
|
|
30555
30480
|
var replayBuffers = /* @__PURE__ */ new Set();
|
|
@@ -30727,7 +30652,6 @@ function initBrowserSDK(config) {
|
|
|
30727
30652
|
cleanups.push(installResourceTiming(meter));
|
|
30728
30653
|
cleanups.push(installLongTaskDetection(tracer));
|
|
30729
30654
|
cleanups.push(installMemoryTracking(meter));
|
|
30730
|
-
cleanups.push(installSupabaseFetchInterceptor(tracer, replay.sessionId));
|
|
30731
30655
|
if (config.captureConsole !== false) {
|
|
30732
30656
|
cleanups.push(installConsoleCapture(tracer, logger, replay.sessionId));
|
|
30733
30657
|
}
|