@obtrace/browser 2.4.0 → 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.
@@ -1,4 +1,4 @@
1
- import { trace, metrics } from "@opentelemetry/api";
1
+ import { trace, metrics, context, SpanStatusCode } from "@opentelemetry/api";
2
2
  import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
3
3
  import { BatchSpanProcessor, TraceIdRatioBasedSampler, ParentBasedSampler } from "@opentelemetry/sdk-trace-web";
4
4
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
@@ -14,7 +14,7 @@ import { DocumentLoadInstrumentation } from "@opentelemetry/instrumentation-docu
14
14
  import { UserInteractionInstrumentation } from "@opentelemetry/instrumentation-user-interaction";
15
15
  import { ZoneContextManager } from "@opentelemetry/context-zone";
16
16
  import { registerInstrumentations } from "@opentelemetry/instrumentation";
17
- import { enrichSupabaseSpan, isSupabaseURL } from "../browser/supabase";
17
+ import { enrichSupabaseSpan, isSupabaseURL, parseSupabaseURL } from "../browser/supabase";
18
18
  export function setupOtelWeb(config) {
19
19
  const baseUrl = (config.ingestBaseUrl || "https://ingest.obtrace.ai").replace(/\/$/, "");
20
20
  const authHeaders = {
@@ -75,13 +75,62 @@ export function setupOtelWeb(config) {
75
75
  });
76
76
  const ingestPattern = new RegExp(`^${baseUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`);
77
77
  const instrumentations = [];
78
- const applySupabaseAttrs = (span, req, _result) => {
78
+ const sessionId = config.sessionId || "";
79
+ const applySupabaseAttrs = (parentSpan, req, result) => {
79
80
  try {
80
81
  const url = typeof req === "string" ? req : req instanceof URL ? req.href : req?.url || "";
81
82
  const method = req?.method || "GET";
82
- if (url && isSupabaseURL(url)) {
83
- enrichSupabaseSpan(span, url, method);
84
- }
83
+ if (!url || !isSupabaseURL(url))
84
+ return;
85
+ enrichSupabaseSpan(parentSpan, url, method);
86
+ if (sessionId)
87
+ parentSpan.setAttribute("session.id", sessionId);
88
+ const parsed = parseSupabaseURL(url, method);
89
+ if (!parsed)
90
+ return;
91
+ const status = typeof result?.status === "number" ? result.status : 0;
92
+ const t = trace.getTracer("@obtrace/sdk-browser", "2.4.0");
93
+ const synth = { "session.id": sessionId, "supabase.ref": parsed.ref, "span.synthetic": "true" };
94
+ const parentCtx = trace.setSpan(context.active(), parentSpan);
95
+ context.with(parentCtx, () => {
96
+ const gw = t.startSpan("supabase.gateway", {
97
+ attributes: { ...synth, "http.method": method.toUpperCase(), "http.status_code": status, "peer.service": "supabase.kong" },
98
+ });
99
+ const gwCtx = trace.setSpan(context.active(), gw);
100
+ context.with(gwCtx, () => {
101
+ if (parsed.service === "postgrest") {
102
+ const db = t.startSpan("supabase.db.query", {
103
+ attributes: { ...synth, "db.system": "postgresql", "db.operation": parsed.operation, "db.sql.table": parsed.table, "db.statement": parsed.detail, "peer.service": "supabase.postgresql" },
104
+ });
105
+ db.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
106
+ db.end();
107
+ }
108
+ if (parsed.service === "auth") {
109
+ const auth = t.startSpan("supabase.auth." + parsed.operation, {
110
+ attributes: { ...synth, "auth.operation": parsed.operation, "peer.service": "supabase.gotrue" },
111
+ });
112
+ auth.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
113
+ auth.end();
114
+ }
115
+ if (parsed.service === "storage") {
116
+ const stor = t.startSpan("supabase.storage." + parsed.operation, {
117
+ attributes: { ...synth, "storage.operation": parsed.operation, "peer.service": "supabase.storage" },
118
+ });
119
+ stor.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
120
+ stor.end();
121
+ }
122
+ if (parsed.service === "edge-function") {
123
+ const fnName = parsed.operation.replace("invoke:", "");
124
+ const fn = t.startSpan("supabase.function." + fnName, {
125
+ attributes: { ...synth, "faas.name": fnName, "faas.trigger": "http", "peer.service": "supabase.edge-runtime" },
126
+ });
127
+ fn.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
128
+ fn.end();
129
+ }
130
+ });
131
+ gw.setStatus({ code: status >= 400 ? SpanStatusCode.ERROR : SpanStatusCode.OK });
132
+ gw.end();
133
+ });
85
134
  }
86
135
  catch { }
87
136
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obtrace/browser",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Obtrace Browser SDK with frontend wrappers",
5
5
  "type": "module",
6
6
  "license": "MIT",