@obtrace/browser 2.2.0 → 2.3.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/console.js +23 -6
- package/dist/browser/errors.js +38 -18
- package/dist/browser/index.js +43 -8
- package/dist/browser_entry.bundle.js +2259 -410
- package/dist/browser_entry.bundle.js.map +4 -4
- package/dist/core/otel-web-setup.js +18 -3
- package/dist/types/browser/console.d.ts +2 -1
- package/dist/types/browser/errors.d.ts +2 -1
- package/dist/types/core/otel-web-setup.d.ts +2 -0
- package/package.json +3 -1
package/dist/browser/console.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SpanStatusCode } from "@opentelemetry/api";
|
|
2
|
+
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
2
3
|
import { addBreadcrumb } from "./breadcrumbs";
|
|
3
4
|
const LEVEL_MAP = {
|
|
4
5
|
debug: "debug",
|
|
@@ -7,9 +8,16 @@ const LEVEL_MAP = {
|
|
|
7
8
|
warn: "warn",
|
|
8
9
|
error: "error",
|
|
9
10
|
};
|
|
11
|
+
const SEVERITY_MAP = {
|
|
12
|
+
debug: SeverityNumber.DEBUG,
|
|
13
|
+
log: SeverityNumber.INFO,
|
|
14
|
+
info: SeverityNumber.INFO,
|
|
15
|
+
warn: SeverityNumber.WARN,
|
|
16
|
+
error: SeverityNumber.ERROR,
|
|
17
|
+
};
|
|
10
18
|
let patched = false;
|
|
11
19
|
let originals = {};
|
|
12
|
-
export function installConsoleCapture(tracer, sessionId) {
|
|
20
|
+
export function installConsoleCapture(tracer, logger, sessionId) {
|
|
13
21
|
if (patched || typeof console === "undefined")
|
|
14
22
|
return () => { };
|
|
15
23
|
patched = true;
|
|
@@ -70,21 +78,30 @@ export function installConsoleCapture(tracer, sessionId) {
|
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
addBreadcrumb({ timestamp: Date.now(), category: `console.${method}`, message, level, data: attrs });
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
logger.emit({
|
|
82
|
+
severityNumber: SEVERITY_MAP[method] ?? SeverityNumber.INFO,
|
|
83
|
+
severityText: level.toUpperCase(),
|
|
84
|
+
body: message.slice(0, 4096),
|
|
75
85
|
attributes: {
|
|
76
|
-
"log.severity": level.toUpperCase(),
|
|
77
|
-
"log.message": message.slice(0, 1024),
|
|
78
86
|
"session.id": sessionId,
|
|
87
|
+
"log.source": "console",
|
|
79
88
|
...attrs,
|
|
80
89
|
},
|
|
81
90
|
});
|
|
82
91
|
if (method === "error") {
|
|
92
|
+
const spanName = (isErrorObj || attrs["error.stack"]) ? "browser.error" : "browser.console";
|
|
93
|
+
const span = tracer.startSpan(spanName, {
|
|
94
|
+
attributes: {
|
|
95
|
+
"error.message": message.slice(0, 1024),
|
|
96
|
+
"session.id": sessionId,
|
|
97
|
+
...attrs,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
83
100
|
span.setStatus({ code: SpanStatusCode.ERROR, message: message.slice(0, 1024) });
|
|
84
101
|
if (isErrorObj)
|
|
85
102
|
span.recordException(firstArg);
|
|
103
|
+
span.end();
|
|
86
104
|
}
|
|
87
|
-
span.end();
|
|
88
105
|
}
|
|
89
106
|
catch { }
|
|
90
107
|
};
|
package/dist/browser/errors.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SpanStatusCode } from "@opentelemetry/api";
|
|
2
|
+
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
2
3
|
import { addBreadcrumb, getBreadcrumbs } from "./breadcrumbs";
|
|
3
|
-
export function installBrowserErrorHooks(tracer, sessionId) {
|
|
4
|
+
export function installBrowserErrorHooks(tracer, logger, sessionId) {
|
|
4
5
|
if (typeof window === "undefined") {
|
|
5
6
|
return () => undefined;
|
|
6
7
|
}
|
|
@@ -10,19 +11,28 @@ export function installBrowserErrorHooks(tracer, sessionId) {
|
|
|
10
11
|
try {
|
|
11
12
|
const breadcrumbs = getBreadcrumbs();
|
|
12
13
|
const stack = ev.error instanceof Error ? ev.error.stack || "" : "";
|
|
13
|
-
const
|
|
14
|
+
const errorType = ev.error?.constructor?.name || "Error";
|
|
15
|
+
const attrs = {
|
|
16
|
+
"error.message": message,
|
|
17
|
+
"error.file": ev.filename || "",
|
|
18
|
+
"error.line": ev.lineno || 0,
|
|
19
|
+
"error.column": ev.colno || 0,
|
|
20
|
+
"error.stack": stack.slice(0, 4096),
|
|
21
|
+
"error.type": errorType,
|
|
22
|
+
"breadcrumbs.count": breadcrumbs.length,
|
|
23
|
+
"breadcrumbs.json": JSON.stringify(breadcrumbs.slice(-20)),
|
|
24
|
+
...(sessionId ? { "session.id": sessionId } : {}),
|
|
25
|
+
};
|
|
26
|
+
logger.emit({
|
|
27
|
+
severityNumber: SeverityNumber.ERROR,
|
|
28
|
+
severityText: "ERROR",
|
|
29
|
+
body: message,
|
|
14
30
|
attributes: {
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
"error.line": ev.lineno || 0,
|
|
18
|
-
"error.column": ev.colno || 0,
|
|
19
|
-
"error.stack": stack.slice(0, 4096),
|
|
20
|
-
"error.type": ev.error?.constructor?.name || "Error",
|
|
21
|
-
"breadcrumbs.count": breadcrumbs.length,
|
|
22
|
-
"breadcrumbs.json": JSON.stringify(breadcrumbs.slice(-20)),
|
|
23
|
-
...(sessionId ? { "session.id": sessionId } : {}),
|
|
31
|
+
"log.source": "window.error",
|
|
32
|
+
...attrs,
|
|
24
33
|
},
|
|
25
34
|
});
|
|
35
|
+
const span = tracer.startSpan("browser.error", { attributes: attrs });
|
|
26
36
|
span.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
27
37
|
if (ev.error instanceof Error) {
|
|
28
38
|
span.recordException(ev.error);
|
|
@@ -34,9 +44,11 @@ export function installBrowserErrorHooks(tracer, sessionId) {
|
|
|
34
44
|
const onRejection = (ev) => {
|
|
35
45
|
let reason;
|
|
36
46
|
let stack = "";
|
|
47
|
+
let errorType = "UnhandledRejection";
|
|
37
48
|
if (ev.reason instanceof Error) {
|
|
38
49
|
reason = `${ev.reason.name}: ${ev.reason.message}`;
|
|
39
50
|
stack = ev.reason.stack || "";
|
|
51
|
+
errorType = ev.reason.constructor?.name || "Error";
|
|
40
52
|
}
|
|
41
53
|
else {
|
|
42
54
|
reason = typeof ev.reason === "string" ? ev.reason : JSON.stringify(ev.reason ?? {});
|
|
@@ -44,16 +56,24 @@ export function installBrowserErrorHooks(tracer, sessionId) {
|
|
|
44
56
|
addBreadcrumb({ timestamp: Date.now(), category: "error", message: reason, level: "error" });
|
|
45
57
|
try {
|
|
46
58
|
const breadcrumbs = getBreadcrumbs();
|
|
47
|
-
const
|
|
59
|
+
const attrs = {
|
|
60
|
+
"error.message": reason,
|
|
61
|
+
"error.stack": stack.slice(0, 4096),
|
|
62
|
+
"error.type": errorType,
|
|
63
|
+
"breadcrumbs.count": breadcrumbs.length,
|
|
64
|
+
"breadcrumbs.json": JSON.stringify(breadcrumbs.slice(-20)),
|
|
65
|
+
...(sessionId ? { "session.id": sessionId } : {}),
|
|
66
|
+
};
|
|
67
|
+
logger.emit({
|
|
68
|
+
severityNumber: SeverityNumber.ERROR,
|
|
69
|
+
severityText: "ERROR",
|
|
70
|
+
body: reason,
|
|
48
71
|
attributes: {
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
"error.type": ev.reason?.constructor?.name || "UnhandledRejection",
|
|
52
|
-
"breadcrumbs.count": breadcrumbs.length,
|
|
53
|
-
"breadcrumbs.json": JSON.stringify(breadcrumbs.slice(-20)),
|
|
54
|
-
...(sessionId ? { "session.id": sessionId } : {}),
|
|
72
|
+
"log.source": "unhandledrejection",
|
|
73
|
+
...attrs,
|
|
55
74
|
},
|
|
56
75
|
});
|
|
76
|
+
const span = tracer.startSpan("browser.unhandledrejection", { attributes: attrs });
|
|
57
77
|
span.setStatus({ code: SpanStatusCode.ERROR, message: reason });
|
|
58
78
|
if (ev.reason instanceof Error) {
|
|
59
79
|
span.recordException(ev.reason);
|
package/dist/browser/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { record } from "rrweb";
|
|
2
2
|
import { SpanStatusCode } from "@opentelemetry/api";
|
|
3
|
+
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
3
4
|
import { ObtraceClient } from "../core/client";
|
|
4
5
|
import { setupOtelWeb } from "../core/otel-web-setup";
|
|
5
6
|
import { installBrowserErrorHooks } from "./errors";
|
|
@@ -165,6 +166,7 @@ export function initBrowserSDK(config) {
|
|
|
165
166
|
const otel = setupOtelWeb({ ...config, tracesSampleRate: sampleRate, sessionId: replay.sessionId });
|
|
166
167
|
const tracer = otel.tracer;
|
|
167
168
|
const meter = otel.meter;
|
|
169
|
+
const logger = otel.loggerProvider.getLogger("@obtrace/sdk-browser", "2.2.0");
|
|
168
170
|
const client = new ObtraceClient({
|
|
169
171
|
...config,
|
|
170
172
|
replay: {
|
|
@@ -207,14 +209,14 @@ export function initBrowserSDK(config) {
|
|
|
207
209
|
}).catch(() => { });
|
|
208
210
|
if (config.vitals?.enabled !== false)
|
|
209
211
|
cleanups.push(installWebVitals(meter, !!config.vitals?.reportAllChanges));
|
|
210
|
-
cleanups.push(installBrowserErrorHooks(tracer, replay.sessionId));
|
|
212
|
+
cleanups.push(installBrowserErrorHooks(tracer, logger, replay.sessionId));
|
|
211
213
|
cleanups.push(installClickBreadcrumbs());
|
|
212
214
|
cleanups.push(installClickTracking(tracer, replay.sessionId));
|
|
213
215
|
cleanups.push(installResourceTiming(meter));
|
|
214
216
|
cleanups.push(installLongTaskDetection(tracer));
|
|
215
217
|
cleanups.push(installMemoryTracking(meter));
|
|
216
218
|
if (config.captureConsole !== false) {
|
|
217
|
-
cleanups.push(installConsoleCapture(tracer, replay.sessionId));
|
|
219
|
+
cleanups.push(installConsoleCapture(tracer, logger, replay.sessionId));
|
|
218
220
|
}
|
|
219
221
|
cleanups.push(installOfflineSupport());
|
|
220
222
|
if (shouldReplay && config.replay?.enabled !== false && typeof window !== "undefined") {
|
|
@@ -263,22 +265,40 @@ export function initBrowserSDK(config) {
|
|
|
263
265
|
window.addEventListener("beforeunload", onBeforeUnload);
|
|
264
266
|
cleanups.push(() => window.removeEventListener("beforeunload", onBeforeUnload));
|
|
265
267
|
}
|
|
268
|
+
const sevToOtel = {
|
|
269
|
+
debug: SeverityNumber.DEBUG,
|
|
270
|
+
info: SeverityNumber.INFO,
|
|
271
|
+
warn: SeverityNumber.WARN,
|
|
272
|
+
error: SeverityNumber.ERROR,
|
|
273
|
+
fatal: SeverityNumber.FATAL,
|
|
274
|
+
};
|
|
266
275
|
const log = (level, message, context) => {
|
|
267
276
|
addCrumb({ timestamp: Date.now(), category: "log", message, level: level === "fatal" ? "error" : level });
|
|
268
|
-
|
|
277
|
+
logger.emit({
|
|
278
|
+
severityNumber: sevToOtel[level] ?? SeverityNumber.INFO,
|
|
279
|
+
severityText: level.toUpperCase(),
|
|
280
|
+
body: message.slice(0, 4096),
|
|
269
281
|
attributes: {
|
|
270
|
-
"log.severity": level.toUpperCase(),
|
|
271
|
-
"log.severity_number": severityToNumber(level),
|
|
272
|
-
"log.message": message,
|
|
273
282
|
"session.id": replay.sessionId,
|
|
283
|
+
"log.source": "sdk",
|
|
274
284
|
...userAttrs(),
|
|
275
285
|
...(context?.traceId ? { "obtrace.trace_id": context.traceId } : {}),
|
|
276
286
|
...context?.attrs,
|
|
277
287
|
},
|
|
278
288
|
});
|
|
279
|
-
if (level === "error" || level === "fatal")
|
|
289
|
+
if (level === "error" || level === "fatal") {
|
|
290
|
+
const span = tracer.startSpan("browser.error", {
|
|
291
|
+
attributes: {
|
|
292
|
+
"error.message": message,
|
|
293
|
+
"session.id": replay.sessionId,
|
|
294
|
+
...userAttrs(),
|
|
295
|
+
...(context?.traceId ? { "obtrace.trace_id": context.traceId } : {}),
|
|
296
|
+
...context?.attrs,
|
|
297
|
+
},
|
|
298
|
+
});
|
|
280
299
|
span.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
281
|
-
|
|
300
|
+
span.end();
|
|
301
|
+
}
|
|
282
302
|
};
|
|
283
303
|
const metricFn = (name, value, unit, context) => {
|
|
284
304
|
const gauge = meter.createGauge(name, { unit: unit ?? "1" });
|
|
@@ -286,11 +306,26 @@ export function initBrowserSDK(config) {
|
|
|
286
306
|
};
|
|
287
307
|
const captureException = (error, context) => {
|
|
288
308
|
const msg = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
309
|
+
const stack = error instanceof Error ? (error.stack || "").slice(0, 4096) : "";
|
|
289
310
|
const breadcrumbs = getBreadcrumbs();
|
|
290
311
|
addCrumb({ timestamp: Date.now(), category: "error", message: msg, level: "error" });
|
|
312
|
+
logger.emit({
|
|
313
|
+
severityNumber: SeverityNumber.ERROR,
|
|
314
|
+
severityText: "ERROR",
|
|
315
|
+
body: msg,
|
|
316
|
+
attributes: {
|
|
317
|
+
"session.id": replay.sessionId,
|
|
318
|
+
"log.source": "exception",
|
|
319
|
+
"error.stack": stack,
|
|
320
|
+
"error.type": error instanceof Error ? error.name : "Error",
|
|
321
|
+
...userAttrs(),
|
|
322
|
+
...context?.attrs,
|
|
323
|
+
},
|
|
324
|
+
});
|
|
291
325
|
const span = tracer.startSpan("browser.exception", {
|
|
292
326
|
attributes: {
|
|
293
327
|
"error.message": msg,
|
|
328
|
+
"error.stack": stack,
|
|
294
329
|
"session.id": replay.sessionId,
|
|
295
330
|
"breadcrumbs.count": breadcrumbs.length,
|
|
296
331
|
"breadcrumbs.json": JSON.stringify(breadcrumbs.slice(-20)),
|