@dxos/observability 0.4.7-main.33db07e → 0.4.7-main.340e96b

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.
Files changed (53) hide show
  1. package/dist/lib/browser/{chunk-XF67HMEA.mjs → chunk-3JYXUPHN.mjs} +149 -26
  2. package/dist/lib/browser/chunk-3JYXUPHN.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-6KUJPLEH.mjs → chunk-G5DKURIM.mjs} +38 -16
  4. package/dist/lib/browser/chunk-G5DKURIM.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +2 -1
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/observability-HDPP5QG7.mjs +8 -0
  8. package/dist/lib/browser/segment/index.mjs +1 -1
  9. package/dist/lib/browser/sentry/index.mjs +7 -5
  10. package/dist/lib/node/{chunk-FSAOBKO2.cjs → chunk-VYXPK6C2.cjs} +38 -51
  11. package/dist/lib/node/chunk-VYXPK6C2.cjs.map +7 -0
  12. package/dist/lib/node/{chunk-T2S7C5J2.cjs → chunk-Z5MY7GRJ.cjs} +145 -29
  13. package/dist/lib/node/chunk-Z5MY7GRJ.cjs.map +7 -0
  14. package/dist/lib/node/index.cjs +16 -15
  15. package/dist/lib/node/index.cjs.map +2 -2
  16. package/dist/lib/node/meta.json +1 -1
  17. package/dist/lib/node/{observability-M64E2QBA.cjs → observability-R327UKSF.cjs} +7 -6
  18. package/dist/lib/node/observability-R327UKSF.cjs.map +7 -0
  19. package/dist/lib/node/segment/index.cjs +2 -2
  20. package/dist/lib/node/sentry/index.cjs +13 -13
  21. package/dist/lib/node/sentry/index.cjs.map +1 -1
  22. package/dist/types/src/helpers/node-observability.d.ts.map +1 -1
  23. package/dist/types/src/helpers/node-observability.js +0 -1
  24. package/dist/types/src/helpers/node-observability.js.map +1 -1
  25. package/dist/types/src/observability.d.ts +0 -2
  26. package/dist/types/src/observability.d.ts.map +1 -1
  27. package/dist/types/src/observability.js +6 -6
  28. package/dist/types/src/observability.js.map +1 -1
  29. package/dist/types/src/sentry/browser.d.ts +3 -2
  30. package/dist/types/src/sentry/browser.d.ts.map +1 -1
  31. package/dist/types/src/sentry/browser.js +15 -5
  32. package/dist/types/src/sentry/browser.js.map +1 -1
  33. package/dist/types/src/sentry/node.d.ts +3 -4
  34. package/dist/types/src/sentry/node.d.ts.map +1 -1
  35. package/dist/types/src/sentry/node.js +11 -43
  36. package/dist/types/src/sentry/node.js.map +1 -1
  37. package/dist/types/src/sentry/sentry-log-processor.d.ts +9 -0
  38. package/dist/types/src/sentry/sentry-log-processor.d.ts.map +1 -0
  39. package/dist/types/src/sentry/sentry-log-processor.js +133 -0
  40. package/dist/types/src/sentry/sentry-log-processor.js.map +1 -0
  41. package/package.json +14 -14
  42. package/src/helpers/node-observability.ts +0 -1
  43. package/src/observability.ts +8 -7
  44. package/src/sentry/browser.ts +17 -4
  45. package/src/sentry/node.ts +11 -48
  46. package/src/sentry/sentry-log-processor.ts +144 -0
  47. package/dist/lib/browser/chunk-6KUJPLEH.mjs.map +0 -7
  48. package/dist/lib/browser/chunk-XF67HMEA.mjs.map +0 -7
  49. package/dist/lib/browser/observability-MK4LFDOW.mjs +0 -7
  50. package/dist/lib/node/chunk-FSAOBKO2.cjs.map +0 -7
  51. package/dist/lib/node/chunk-T2S7C5J2.cjs.map +0 -7
  52. package/dist/lib/node/observability-M64E2QBA.cjs.map +0 -7
  53. /package/dist/lib/browser/{observability-MK4LFDOW.mjs.map → observability-HDPP5QG7.mjs.map} +0 -0
@@ -0,0 +1,9 @@
1
+ import type { Event } from '@sentry/types';
2
+ import { type LogProcessor } from '@dxos/log';
3
+ export declare class SentryLogProcessor {
4
+ private _breadcrumbs;
5
+ readonly logProcessor: LogProcessor;
6
+ addLogBreadcrumbsTo(event: Event): void;
7
+ private _addBreadcrumb;
8
+ }
9
+ //# sourceMappingURL=sentry-log-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry-log-processor.d.ts","sourceRoot":"","sources":["../../../../src/sentry/sentry-log-processor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAA6B,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtE,OAAO,EAA2C,KAAK,YAAY,EAAa,MAAM,WAAW,CAAC;AAOlG,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,YAAY,CAAuD;IAE3E,SAAgB,YAAY,EAAE,YAAY,CA+CxC;IAEK,mBAAmB,CAAC,KAAK,EAAE,KAAK;IAavC,OAAO,CAAC,cAAc;CA8BvB"}
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ //
3
+ // Copyright 2024 DXOS.org
4
+ //
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SentryLogProcessor = void 0;
7
+ const log_1 = require("@dxos/log");
8
+ const util_1 = require("@dxos/util");
9
+ const _1 = require("./");
10
+ const MAX_LOG_BREADCRUMBS = 80;
11
+ class SentryLogProcessor {
12
+ constructor() {
13
+ this._breadcrumbs = new util_1.CircularBuffer(MAX_LOG_BREADCRUMBS);
14
+ this.logProcessor = (config, entry) => {
15
+ const { level, meta, error } = entry;
16
+ if (!(0, log_1.shouldLog)(entry, config.captureFilters)) {
17
+ return;
18
+ }
19
+ if (entry.level !== log_1.LogLevel.WARN && entry.level !== log_1.LogLevel.ERROR) {
20
+ return;
21
+ }
22
+ // TODO(nf): add rate limiting to avoid spamming Sentry/consuming excessive quota.
23
+ (0, _1.withScope)((scope) => {
24
+ var _a, _b, _c, _d, _e, _f;
25
+ const severity = convertLevel(level);
26
+ scope.setLevel(severity);
27
+ scope.setContext('dxoslog', (_a = entry.context) !== null && _a !== void 0 ? _a : null);
28
+ if (meta) {
29
+ scope.setTag('transaction', `${getRelativeFilename(meta.F)}:${meta.L}`);
30
+ if ((_b = meta.S) === null || _b === void 0 ? void 0 : _b.hostSessionId) {
31
+ scope.setTags({
32
+ service_host_issue: true,
33
+ service_host_session: (_c = meta.S) === null || _c === void 0 ? void 0 : _c.hostSessionId,
34
+ });
35
+ }
36
+ if (!Number.isNaN((_d = meta.S) === null || _d === void 0 ? void 0 : _d.uptimeSeconds)) {
37
+ scope.setExtra('uptime_seconds', (_e = meta.S) === null || _e === void 0 ? void 0 : _e.uptimeSeconds);
38
+ }
39
+ }
40
+ const extendedMessage = formatMessageForSentry(entry);
41
+ let capturedError = error;
42
+ if (capturedError == null && entry.level === log_1.LogLevel.ERROR) {
43
+ capturedError = Object.values((_f = entry.context) !== null && _f !== void 0 ? _f : {}).find((v) => v instanceof Error);
44
+ }
45
+ if (capturedError) {
46
+ const isMessageDifferentFromStackTrace = error == null;
47
+ if (isMessageDifferentFromStackTrace) {
48
+ scope.setExtra('message', extendedMessage);
49
+ }
50
+ const eventId = (0, _1.captureException)(capturedError);
51
+ this._addBreadcrumb(eventId, extendedMessage, severity, entry.context);
52
+ return;
53
+ }
54
+ scope.setFingerprint([entry.message]);
55
+ const eventId = (0, _1.captureMessage)(extendedMessage);
56
+ this._addBreadcrumb(eventId, extendedMessage, severity, entry.context);
57
+ });
58
+ };
59
+ }
60
+ addLogBreadcrumbsTo(event) {
61
+ var _a;
62
+ (_a = event.breadcrumbs) !== null && _a !== void 0 ? _a : (event.breadcrumbs = []);
63
+ for (const breadcrumb of this._breadcrumbs) {
64
+ event.breadcrumbs.push(breadcrumb);
65
+ }
66
+ event.breadcrumbs.sort((b1, b2) => {
67
+ if (b1.timestamp === undefined || b2.timestamp === undefined) {
68
+ return b1.timestamp === b2.timestamp ? 0 : b1.timestamp === undefined ? -1 : 1;
69
+ }
70
+ return b1.timestamp - b2.timestamp;
71
+ });
72
+ }
73
+ _addBreadcrumb(eventId, message, severity, context) {
74
+ var _a, _b, _c, _d, _e;
75
+ const breadcrumb = {
76
+ type: 'console',
77
+ level: severity,
78
+ event_id: eventId,
79
+ category: 'log',
80
+ message,
81
+ data: context,
82
+ timestamp: Math.floor(Date.now() / 1000),
83
+ };
84
+ const lastRecorded = this._breadcrumbs.getLast();
85
+ if (lastRecorded && lastRecorded.message === breadcrumb.message) {
86
+ const firstBreadcrumbData = (_c = (_b = (_a = lastRecorded.data) === null || _a === void 0 ? void 0 : _a.firstBreadcrumbData) !== null && _b !== void 0 ? _b : lastRecorded.data) !== null && _c !== void 0 ? _c : {};
87
+ const mergedBreadcrumbCount = Number.isNaN((_d = lastRecorded.data) === null || _d === void 0 ? void 0 : _d.mergedBreadcrumbCount)
88
+ ? 1
89
+ : Number((_e = lastRecorded.data) === null || _e === void 0 ? void 0 : _e.mergedBreadcrumbCount);
90
+ lastRecorded.data = {
91
+ mergedBreadcrumbCount: mergedBreadcrumbCount + 1,
92
+ firstBreadcrumbData,
93
+ lastBreadcrumbData: breadcrumb.data,
94
+ };
95
+ return;
96
+ }
97
+ this._breadcrumbs.push(breadcrumb);
98
+ }
99
+ }
100
+ exports.SentryLogProcessor = SentryLogProcessor;
101
+ const formatMessageForSentry = (entry) => {
102
+ var _a, _b, _c, _d;
103
+ let scopePrefix;
104
+ if ((_a = entry.meta) === null || _a === void 0 ? void 0 : _a.S) {
105
+ const scope = (_b = entry.meta) === null || _b === void 0 ? void 0 : _b.S;
106
+ scopePrefix = scope.name || (0, util_1.getDebugName)(scope);
107
+ }
108
+ if (scopePrefix == null) {
109
+ return entry.message;
110
+ }
111
+ const workerPrefix = ((_d = (_c = entry.meta) === null || _c === void 0 ? void 0 : _c.S) === null || _d === void 0 ? void 0 : _d.hostSessionId) ? '[worker] ' : '';
112
+ return `${workerPrefix}${scopePrefix} ${entry.message}`;
113
+ };
114
+ const convertLevel = (level) => {
115
+ if (level === log_1.LogLevel.TRACE) {
116
+ return 'debug';
117
+ }
118
+ if (level === log_1.LogLevel.WARN) {
119
+ return 'warning';
120
+ }
121
+ return log_1.LogLevel[level].toLowerCase();
122
+ };
123
+ const getRelativeFilename = (filename) => {
124
+ // TODO(burdon): Hack uses "packages" as an anchor (pre-parse NX?)
125
+ // Including `packages/` part of the path so that excluded paths (e.g. from dist) are clickable in vscode.
126
+ const match = filename.match(/.+\/(packages\/.+\/.+)/);
127
+ if (match) {
128
+ const [, filePath] = match;
129
+ return filePath;
130
+ }
131
+ return filename;
132
+ };
133
+ //# sourceMappingURL=sentry-log-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry-log-processor.js","sourceRoot":"","sources":["../../../../src/sentry/sentry-log-processor.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AAIF,mCAAkG;AAClG,qCAA0D;AAE1D,yBAAiE;AAEjE,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,MAAa,kBAAkB;IAA/B;QACU,iBAAY,GAAG,IAAI,qBAAc,CAAa,mBAAmB,CAAC,CAAC;QAE3D,iBAAY,GAAiB,CAAC,MAAiB,EAAE,KAAe,EAAE,EAAE;YAClF,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;YACrC,IAAI,CAAC,IAAA,eAAS,EAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC,EAAE;gBAC5C,OAAO;aACR;YACD,IAAI,KAAK,CAAC,KAAK,KAAK,cAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,cAAQ,CAAC,KAAK,EAAE;gBACnE,OAAO;aACR;YACD,kFAAkF;YAClF,IAAA,YAAS,EAAC,CAAC,KAAK,EAAE,EAAE;;gBAClB,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;gBACrC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACzB,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,MAAA,KAAK,CAAC,OAAO,mCAAI,IAAI,CAAC,CAAC;gBACnD,IAAI,IAAI,EAAE;oBACR,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;oBAExE,IAAI,MAAA,IAAI,CAAC,CAAC,0CAAE,aAAa,EAAE;wBACzB,KAAK,CAAC,OAAO,CAAC;4BACZ,kBAAkB,EAAE,IAAI;4BACxB,oBAAoB,EAAE,MAAA,IAAI,CAAC,CAAC,0CAAE,aAAa;yBAC5C,CAAC,CAAC;qBACJ;oBAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAA,IAAI,CAAC,CAAC,0CAAE,aAAa,CAAC,EAAE;wBACxC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAA,IAAI,CAAC,CAAC,0CAAE,aAAa,CAAC,CAAC;qBACzD;iBACF;gBAED,MAAM,eAAe,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;gBACtD,IAAI,aAAa,GAAG,KAAK,CAAC;gBAC1B,IAAI,aAAa,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,cAAQ,CAAC,KAAK,EAAE;oBAC3D,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,MAAA,KAAK,CAAC,OAAO,mCAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAc,EAAE,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC;iBAChG;gBACD,IAAI,aAAa,EAAE;oBACjB,MAAM,gCAAgC,GAAG,KAAK,IAAI,IAAI,CAAC;oBACvD,IAAI,gCAAgC,EAAE;wBACpC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;qBAC5C;oBACD,MAAM,OAAO,GAAG,IAAA,mBAAgB,EAAC,aAAa,CAAC,CAAC;oBAChD,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;oBACvE,OAAO;iBACR;gBAED,KAAK,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBACtC,MAAM,OAAO,GAAG,IAAA,iBAAc,EAAC,eAAe,CAAC,CAAC;gBAChD,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACzE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IA6CJ,CAAC;IA3CQ,mBAAmB,CAAC,KAAY;;QACrC,MAAA,KAAK,CAAC,WAAW,oCAAjB,KAAK,CAAC,WAAW,GAAK,EAAE,EAAC;QACzB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE;YAC1C,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SACpC;QACD,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;YAChC,IAAI,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,CAAC,SAAS,KAAK,SAAS,EAAE;gBAC5D,OAAO,EAAE,CAAC,SAAS,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAChF;YACD,OAAO,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,cAAc,CACpB,OAAe,EACf,OAAe,EACf,QAAuB,EACvB,OAA2C;;QAE3C,MAAM,UAAU,GAAe;YAC7B,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK;YACf,OAAO;YACP,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;SACzC,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QACjD,IAAI,YAAY,IAAI,YAAY,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE;YAC/D,MAAM,mBAAmB,GAAG,MAAA,MAAA,MAAA,YAAY,CAAC,IAAI,0CAAE,mBAAmB,mCAAI,YAAY,CAAC,IAAI,mCAAI,EAAE,CAAC;YAC9F,MAAM,qBAAqB,GAAG,MAAM,CAAC,KAAK,CAAC,MAAA,YAAY,CAAC,IAAI,0CAAE,qBAAqB,CAAC;gBAClF,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,MAAM,CAAC,MAAA,YAAY,CAAC,IAAI,0CAAE,qBAAqB,CAAC,CAAC;YACrD,YAAY,CAAC,IAAI,GAAG;gBAClB,qBAAqB,EAAE,qBAAqB,GAAG,CAAC;gBAChD,mBAAmB;gBACnB,kBAAkB,EAAE,UAAU,CAAC,IAAI;aACpC,CAAC;YACF,OAAO;SACR;QACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;CACF;AA/FD,gDA+FC;AAED,MAAM,sBAAsB,GAAG,CAAC,KAAe,EAAE,EAAE;;IACjD,IAAI,WAA+B,CAAC;IACpC,IAAI,MAAA,KAAK,CAAC,IAAI,0CAAE,CAAC,EAAE;QACjB,MAAM,KAAK,GAAG,MAAA,KAAK,CAAC,IAAI,0CAAE,CAAC,CAAC;QAC5B,WAAW,GAAG,KAAK,CAAC,IAAI,IAAI,IAAA,mBAAY,EAAC,KAAK,CAAC,CAAC;KACjD;IACD,IAAI,WAAW,IAAI,IAAI,EAAE;QACvB,OAAO,KAAK,CAAC,OAAO,CAAC;KACtB;IACD,MAAM,YAAY,GAAG,CAAA,MAAA,MAAA,KAAK,CAAC,IAAI,0CAAE,CAAC,0CAAE,aAAa,EAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,OAAO,GAAG,YAAY,GAAG,WAAW,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,KAAe,EAAiB,EAAE;IACtD,IAAI,KAAK,KAAK,cAAQ,CAAC,KAAK,EAAE;QAC5B,OAAO,OAAO,CAAC;KAChB;IACD,IAAI,KAAK,KAAK,cAAQ,CAAC,IAAI,EAAE;QAC3B,OAAO,SAAS,CAAC;KAClB;IACD,OAAO,cAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAmB,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAE,EAAE;IAC/C,kEAAkE;IAClE,0GAA0G;IAC1G,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACvD,IAAI,KAAK,EAAE;QACT,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC;QAC3B,OAAO,QAAQ,CAAC;KACjB;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/observability",
3
- "version": "0.4.7-main.33db07e",
3
+ "version": "0.4.7-main.340e96b",
4
4
  "description": "Provides a common interface for app and platform observability",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -69,19 +69,19 @@
69
69
  "js-yaml": "^4.1.0",
70
70
  "localforage": "^1.10.0",
71
71
  "uuid": "^8.3.2",
72
- "@dxos/async": "0.4.7-main.33db07e",
73
- "@dxos/client-protocol": "0.4.7-main.33db07e",
74
- "@dxos/config": "0.4.7-main.33db07e",
75
- "@dxos/context": "0.4.7-main.33db07e",
76
- "@dxos/debug": "0.4.7-main.33db07e",
77
- "@dxos/invariant": "0.4.7-main.33db07e",
78
- "@dxos/client-services": "0.4.7-main.33db07e",
79
- "@dxos/network-manager": "0.4.7-main.33db07e",
80
- "@dxos/node-std": "0.4.7-main.33db07e",
81
- "@dxos/log": "0.4.7-main.33db07e",
82
- "@dxos/protocols": "0.4.7-main.33db07e",
83
- "@dxos/react-client": "0.4.7-main.33db07e",
84
- "@dxos/util": "0.4.7-main.33db07e"
72
+ "@dxos/client-protocol": "0.4.7-main.340e96b",
73
+ "@dxos/async": "0.4.7-main.340e96b",
74
+ "@dxos/client-services": "0.4.7-main.340e96b",
75
+ "@dxos/config": "0.4.7-main.340e96b",
76
+ "@dxos/debug": "0.4.7-main.340e96b",
77
+ "@dxos/context": "0.4.7-main.340e96b",
78
+ "@dxos/invariant": "0.4.7-main.340e96b",
79
+ "@dxos/network-manager": "0.4.7-main.340e96b",
80
+ "@dxos/log": "0.4.7-main.340e96b",
81
+ "@dxos/node-std": "0.4.7-main.340e96b",
82
+ "@dxos/protocols": "0.4.7-main.340e96b",
83
+ "@dxos/react-client": "0.4.7-main.340e96b",
84
+ "@dxos/util": "0.4.7-main.340e96b"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@sentry/types": "^7.100.1",
@@ -126,7 +126,6 @@ export const initializeNodeObservability = async ({
126
126
  // TODO(wittjosiah): Configure this.
127
127
  sampleRate: 1.0,
128
128
  },
129
- logProcessor: true,
130
129
  },
131
130
  });
132
131
 
@@ -17,6 +17,7 @@ import { type DatadogMetrics } from './datadog';
17
17
  import { type IPData, getTelemetryIdentifier, mapSpaces } from './helpers';
18
18
  import { type SegmentTelemetry, type EventOptions, type PageOptions } from './segment';
19
19
  import { type InitOptions, type captureException as SentryCaptureException } from './sentry';
20
+ import { SentryLogProcessor } from './sentry/sentry-log-processor';
20
21
 
21
22
  const SPACE_METRICS_MIN_INTERVAL = 1000 * 60;
22
23
  // const DATADOG_IDLE_INTERVAL = 1000 * 60 * 5;
@@ -55,7 +56,6 @@ export type ObservabilityOptions = {
55
56
 
56
57
  errorLog?: {
57
58
  sentryInitOptions?: InitOptions;
58
- logProcessor?: boolean;
59
59
  };
60
60
  };
61
61
 
@@ -71,7 +71,6 @@ export class Observability {
71
71
  private _telemetry?: SegmentTelemetry;
72
72
  // TODO(wittjosiah): Generic error logging interface.
73
73
  private _errorReportingOptions?: InitOptions;
74
- private _errorLogProcessor: boolean;
75
74
  private _captureException?: typeof SentryCaptureException;
76
75
  private _setTag?: (key: string, value: string) => void;
77
76
 
@@ -103,7 +102,6 @@ export class Observability {
103
102
  this._secrets = this._loadSecrets(config, secrets);
104
103
  this._telemetryBatchSize = telemetry?.batchSize ?? 30;
105
104
  this._errorReportingOptions = errorLog?.sentryInitOptions;
106
- this._errorLogProcessor = errorLog?.logProcessor ?? false;
107
105
 
108
106
  if (this._group) {
109
107
  this.setTag('group', this._group);
@@ -447,7 +445,7 @@ export class Observability {
447
445
 
448
446
  private async _initErrorLogs() {
449
447
  if (this._secrets.SENTRY_DESTINATION && this._mode !== 'disabled') {
450
- const { captureException, enableSentryLogProcessor, configureTracing, init, setTag } = await import('./sentry');
448
+ const { captureException, configureTracing, init, setTag } = await import('./sentry');
451
449
  this._captureException = captureException;
452
450
  this._setTag = setTag;
453
451
 
@@ -456,18 +454,21 @@ export class Observability {
456
454
  dest: this._secrets.SENTRY_DESTINATION,
457
455
  options: this._errorReportingOptions,
458
456
  });
457
+
458
+ const logProcessor = new SentryLogProcessor();
459
459
  init({
460
460
  ...this._errorReportingOptions,
461
461
  destination: this._secrets.SENTRY_DESTINATION,
462
462
  scrubFilenames: this._mode !== 'full',
463
+ onError: (event) => logProcessor.addLogBreadcrumbsTo(event),
463
464
  });
464
465
  if (this._errorReportingOptions?.tracing) {
465
466
  configureTracing();
466
467
  }
468
+
467
469
  // TODO(nf): set platform at instantiation? needed for node.
468
- if (this._errorLogProcessor) {
469
- enableSentryLogProcessor();
470
- }
470
+ log.runtimeConfig.processors.push(logProcessor.logProcessor);
471
+
471
472
  // TODO(nf): is this different than passing as properties in options?
472
473
  this._tags.forEach((v, k) => {
473
474
  if (v.scope === 'all' || v.scope === 'errors') {
@@ -7,10 +7,13 @@ import {
7
7
  setTag,
8
8
  addBreadcrumb as naturalAddBreadcrumb,
9
9
  captureException as naturalCaptureException,
10
+ captureMessage as naturalCaptureMessage,
11
+ withScope as naturalWithScope,
10
12
  BrowserTracing,
11
13
  replayIntegration,
14
+ breadcrumbsIntegration,
12
15
  } from '@sentry/browser';
13
- import { captureConsoleIntegration, httpClientIntegration } from '@sentry/integrations';
16
+ import { httpClientIntegration } from '@sentry/integrations';
14
17
 
15
18
  import { log } from '@dxos/log';
16
19
 
@@ -37,7 +40,7 @@ export const init = (options: InitOptions) => {
37
40
  release: options.release,
38
41
  environment: options.environment,
39
42
  integrations: [
40
- captureConsoleIntegration({ levels: ['error', 'warn'] }),
43
+ breadcrumbsIntegration({ console: false, fetch: false }),
41
44
  httpClientIntegration({ failedRequestStatusCodes: [[400, 599]] }),
42
45
  ...(options.tracing ? [new BrowserTracing()] : []),
43
46
  ...(options.replay ? [replayIntegration({ blockAllMedia: true, maskAllText: true })] : []),
@@ -96,5 +99,15 @@ export const captureException: typeof naturalCaptureException = (exception, capt
96
99
  }
97
100
  };
98
101
 
99
- // Not needed for browser.
100
- export const enableSentryLogProcessor = () => {};
102
+ export const captureMessage: typeof naturalCaptureMessage = (exception, captureContext) => {
103
+ try {
104
+ const eventId = naturalCaptureMessage(exception, captureContext);
105
+ log('capture message', { exception, eventId, captureContext });
106
+ return eventId;
107
+ } catch (err) {
108
+ log.catch('Failed to capture message', err);
109
+ return 'unknown';
110
+ }
111
+ };
112
+
113
+ export const withScope = naturalWithScope;
@@ -9,12 +9,11 @@ import {
9
9
  addBreadcrumb as naturalAddBreadcrumb,
10
10
  captureException as naturalCaptureException,
11
11
  captureMessage as naturalCaptureMessage,
12
- withScope,
12
+ withScope as naturalWithScope,
13
13
  } from '@sentry/node';
14
14
  import type { Event } from '@sentry/node';
15
- import type { SeverityLevel } from '@sentry/types';
16
15
 
17
- import { log, LogLevel, shouldLog } from '@dxos/log';
16
+ import { log } from '@dxos/log';
18
17
 
19
18
  import { type InitOptions } from './types';
20
19
 
@@ -103,51 +102,15 @@ export const captureException: typeof naturalCaptureException = (exception, capt
103
102
  }
104
103
  };
105
104
 
106
- // TODO(nf): move to log package as a first-class processor.
107
- export const enableSentryLogProcessor = (filter?: string | string[] | LogLevel) => {
108
- log.runtimeConfig.processors.push(SENTRY_LOG_PROCESSOR);
109
- };
110
-
111
- export const SENTRY_LOG_PROCESSOR = (config: any, entry: any) => {
112
- const { message, level, meta, error } = entry;
113
- if (!shouldLog(entry, config.captureFilters)) {
114
- return;
115
- }
116
- // TODO(nf): add rate limiting to avoid spamming Sentry/consuming excessive quota.
117
- withScope((scope) => {
118
- scope.setLevel(convertLevel(level));
119
- scope.setContext('dxoslog', entry.context);
120
- if (meta) {
121
- scope.setTransactionName(`${getRelativeFilename(meta.F)}:${meta.L}`);
122
- }
123
- // Is this ever used?
124
- if (error) {
125
- scope.setExtra('message', message);
126
- return naturalCaptureException(error);
127
- }
128
-
129
- naturalCaptureMessage(message);
130
- });
131
- };
132
-
133
- const convertLevel = (level: LogLevel): SeverityLevel => {
134
- if (level === LogLevel.TRACE) {
135
- return 'debug';
136
- }
137
- if (level === LogLevel.WARN) {
138
- return 'warning';
105
+ export const captureMessage: typeof naturalCaptureMessage = (exception, captureContext) => {
106
+ try {
107
+ const eventId = naturalCaptureMessage(exception, captureContext);
108
+ log('capture message', { exception, eventId, captureContext });
109
+ return eventId;
110
+ } catch (err) {
111
+ log.catch('Failed to capture message', err);
112
+ return 'unknown';
139
113
  }
140
- return LogLevel[level].toLowerCase() as SeverityLevel;
141
114
  };
142
115
 
143
- const getRelativeFilename = (filename: string) => {
144
- // TODO(burdon): Hack uses "packages" as an anchor (pre-parse NX?)
145
- // Including `packages/` part of the path so that excluded paths (e.g. from dist) are clickable in vscode.
146
- const match = filename.match(/.+\/(packages\/.+\/.+)/);
147
- if (match) {
148
- const [, filePath] = match;
149
- return filePath;
150
- }
151
-
152
- return filename;
153
- };
116
+ export const withScope = naturalWithScope;
@@ -0,0 +1,144 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import type { Breadcrumb, SeverityLevel, Event } from '@sentry/types';
6
+
7
+ import { type LogConfig, type LogEntry, LogLevel, type LogProcessor, shouldLog } from '@dxos/log';
8
+ import { CircularBuffer, getDebugName } from '@dxos/util';
9
+
10
+ import { withScope, captureException, captureMessage } from './';
11
+
12
+ const MAX_LOG_BREADCRUMBS = 80;
13
+
14
+ export class SentryLogProcessor {
15
+ private _breadcrumbs = new CircularBuffer<Breadcrumb>(MAX_LOG_BREADCRUMBS);
16
+
17
+ public readonly logProcessor: LogProcessor = (config: LogConfig, entry: LogEntry) => {
18
+ const { level, meta, error } = entry;
19
+ if (!shouldLog(entry, config.captureFilters)) {
20
+ return;
21
+ }
22
+ if (entry.level !== LogLevel.WARN && entry.level !== LogLevel.ERROR) {
23
+ return;
24
+ }
25
+ // TODO(nf): add rate limiting to avoid spamming Sentry/consuming excessive quota.
26
+ withScope((scope) => {
27
+ const severity = convertLevel(level);
28
+ scope.setLevel(severity);
29
+ scope.setContext('dxoslog', entry.context ?? null);
30
+ if (meta) {
31
+ scope.setTag('transaction', `${getRelativeFilename(meta.F)}:${meta.L}`);
32
+
33
+ if (meta.S?.hostSessionId) {
34
+ scope.setTags({
35
+ service_host_issue: true,
36
+ service_host_session: meta.S?.hostSessionId,
37
+ });
38
+ }
39
+
40
+ if (!Number.isNaN(meta.S?.uptimeSeconds)) {
41
+ scope.setExtra('uptime_seconds', meta.S?.uptimeSeconds);
42
+ }
43
+ }
44
+
45
+ const extendedMessage = formatMessageForSentry(entry);
46
+ let capturedError = error;
47
+ if (capturedError == null && entry.level === LogLevel.ERROR) {
48
+ capturedError = Object.values(entry.context ?? {}).find((v): v is Error => v instanceof Error);
49
+ }
50
+ if (capturedError) {
51
+ const isMessageDifferentFromStackTrace = error == null;
52
+ if (isMessageDifferentFromStackTrace) {
53
+ scope.setExtra('message', extendedMessage);
54
+ }
55
+ const eventId = captureException(capturedError);
56
+ this._addBreadcrumb(eventId, extendedMessage, severity, entry.context);
57
+ return;
58
+ }
59
+
60
+ scope.setFingerprint([entry.message]);
61
+ const eventId = captureMessage(extendedMessage);
62
+ this._addBreadcrumb(eventId, extendedMessage, severity, entry.context);
63
+ });
64
+ };
65
+
66
+ public addLogBreadcrumbsTo(event: Event) {
67
+ event.breadcrumbs ??= [];
68
+ for (const breadcrumb of this._breadcrumbs) {
69
+ event.breadcrumbs.push(breadcrumb);
70
+ }
71
+ event.breadcrumbs.sort((b1, b2) => {
72
+ if (b1.timestamp === undefined || b2.timestamp === undefined) {
73
+ return b1.timestamp === b2.timestamp ? 0 : b1.timestamp === undefined ? -1 : 1;
74
+ }
75
+ return b1.timestamp - b2.timestamp;
76
+ });
77
+ }
78
+
79
+ private _addBreadcrumb(
80
+ eventId: string,
81
+ message: string,
82
+ severity: SeverityLevel,
83
+ context: { [key: string]: any } | undefined,
84
+ ): void {
85
+ const breadcrumb: Breadcrumb = {
86
+ type: 'console',
87
+ level: severity,
88
+ event_id: eventId,
89
+ category: 'log',
90
+ message,
91
+ data: context,
92
+ timestamp: Math.floor(Date.now() / 1000),
93
+ };
94
+ const lastRecorded = this._breadcrumbs.getLast();
95
+ if (lastRecorded && lastRecorded.message === breadcrumb.message) {
96
+ const firstBreadcrumbData = lastRecorded.data?.firstBreadcrumbData ?? lastRecorded.data ?? {};
97
+ const mergedBreadcrumbCount = Number.isNaN(lastRecorded.data?.mergedBreadcrumbCount)
98
+ ? 1
99
+ : Number(lastRecorded.data?.mergedBreadcrumbCount);
100
+ lastRecorded.data = {
101
+ mergedBreadcrumbCount: mergedBreadcrumbCount + 1,
102
+ firstBreadcrumbData,
103
+ lastBreadcrumbData: breadcrumb.data,
104
+ };
105
+ return;
106
+ }
107
+ this._breadcrumbs.push(breadcrumb);
108
+ }
109
+ }
110
+
111
+ const formatMessageForSentry = (entry: LogEntry) => {
112
+ let scopePrefix: string | undefined;
113
+ if (entry.meta?.S) {
114
+ const scope = entry.meta?.S;
115
+ scopePrefix = scope.name || getDebugName(scope);
116
+ }
117
+ if (scopePrefix == null) {
118
+ return entry.message;
119
+ }
120
+ const workerPrefix = entry.meta?.S?.hostSessionId ? '[worker] ' : '';
121
+ return `${workerPrefix}${scopePrefix} ${entry.message}`;
122
+ };
123
+
124
+ const convertLevel = (level: LogLevel): SeverityLevel => {
125
+ if (level === LogLevel.TRACE) {
126
+ return 'debug';
127
+ }
128
+ if (level === LogLevel.WARN) {
129
+ return 'warning';
130
+ }
131
+ return LogLevel[level].toLowerCase() as SeverityLevel;
132
+ };
133
+
134
+ const getRelativeFilename = (filename: string) => {
135
+ // TODO(burdon): Hack uses "packages" as an anchor (pre-parse NX?)
136
+ // Including `packages/` part of the path so that excluded paths (e.g. from dist) are clickable in vscode.
137
+ const match = filename.match(/.+\/(packages\/.+\/.+)/);
138
+ if (match) {
139
+ const [, filePath] = match;
140
+ return filePath;
141
+ }
142
+
143
+ return filename;
144
+ };
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/sentry/browser.ts", "../../../src/sentry/tracing.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport {\n init as naturalInit,\n setTag,\n addBreadcrumb as naturalAddBreadcrumb,\n captureException as naturalCaptureException,\n BrowserTracing,\n replayIntegration,\n} from '@sentry/browser';\nimport { captureConsoleIntegration, httpClientIntegration } from '@sentry/integrations';\n\nimport { log } from '@dxos/log';\n\nimport { type InitOptions } from './types';\n\n// Browser only feature.\nexport * from './tracing';\n\n// Polyfill export.\nexport { setTag, setTags, setUser } from '@sentry/browser';\n\n/**\n * To use this SDK, call the init function as early as possible when loading the web page.\n * To set context information or send manual events, use the provided methods.\n *\n * @param options {InitOptions}\n */\nexport const init = (options: InitOptions) => {\n try {\n log('sentry init', options);\n naturalInit({\n enabled: options.enable ?? true,\n dsn: options.destination,\n release: options.release,\n environment: options.environment,\n integrations: [\n captureConsoleIntegration({ levels: ['error', 'warn'] }),\n httpClientIntegration({ failedRequestStatusCodes: [[400, 599]] }),\n ...(options.tracing ? [new BrowserTracing()] : []),\n ...(options.replay ? [replayIntegration({ blockAllMedia: true, maskAllText: true })] : []),\n ],\n replaysSessionSampleRate: options.replaySampleRate,\n replaysOnErrorSampleRate: options.replaySampleRateOnError,\n tracesSampleRate: options.sampleRate,\n transport: options.transport,\n beforeSend: (event) => {\n options.onError?.(event);\n return event;\n },\n });\n\n Object.entries(options.properties ?? {}).forEach(([key, value]) => {\n setTag(key, value);\n });\n } catch (err) {\n log.catch('Failed to initialize sentry', err);\n }\n};\n\n/**\n * Records a new breadcrumb which will be attached to future events.\n *\n * Breadcrumbs will be added to subsequent events to provide more context on user's actions prior to an error or crash.\n *\n * https://docs.sentry.io/platforms/javascript/enriching-events/breadcrumbs/\n *\n * @param breadcrumb — The breadcrumb to record.\n */\nexport const addBreadcrumb: typeof naturalAddBreadcrumb = (breadcrumb) => {\n try {\n naturalAddBreadcrumb(breadcrumb);\n log('add breadcrumb', breadcrumb);\n } catch (err) {\n log.catch('Failed to add breadcrumb', err);\n }\n};\n\n/**\n * Captures an exception event and sends it to Sentry.\n *\n * @param exception — An exception-like object.\n * @param captureContext — Additional scope data to apply to exception event.\n * @returns — The generated eventId.\n */\nexport const captureException: typeof naturalCaptureException = (exception, captureContext) => {\n try {\n const eventId = naturalCaptureException(exception, captureContext);\n log('capture exception', { exception, eventId, ...captureContext });\n return eventId;\n } catch (err) {\n log.catch('Failed to capture exception', err);\n return 'unknown';\n }\n};\n\n// Not needed for browser.\nexport const enableSentryLogProcessor = () => {};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// NOTE: Browser only API. There is no node polyfill.\n\nimport { getCurrentHub } from '@sentry/browser';\nimport { type Transaction, type Span } from '@sentry/types';\n\nimport { runInContext, scheduleMicroTask, Trigger } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { getContextFromEntry, log, LogLevel, type LogProcessor } from '@dxos/log';\n\nconst REPORT_SPANS = false;\n\nlet TX!: Transaction;\nconst SPAN_MAP = new Map<string, Span>();\nconst SENTRY_INITIALIZED = new Trigger();\nconst ctx = new Context({ onError: (err) => log.warn('Unhandled error in Sentry context', err) });\nctx.maxSafeDisposeCallbacks = 10_000;\n\nlet tracingConfigured = false;\n\nexport const configureTracing = () => {\n tracingConfigured = true;\n runInContext(ctx, () => {\n // Configure root transaction.\n TX = getCurrentHub().startTransaction({\n name: 'DXOS Core Tracing',\n op: 'dxos',\n });\n invariant(TX, 'Failed to create trace');\n if (typeof window !== 'undefined') {\n window.addEventListener('beforeunload', () => {\n finish();\n });\n }\n if (typeof process !== 'undefined') {\n process.on('exit', () => {\n finish();\n });\n }\n\n SENTRY_INITIALIZED.wake();\n });\n};\n\nexport const finish = () => {\n for (const span of Array.from(SPAN_MAP.values()).reverse()) {\n try {\n span.finish();\n } catch (err) {\n log.warn('Failed to finish span', err);\n }\n }\n TX.finish();\n};\n\nexport const SENTRY_PROCESSOR: LogProcessor = (config, entry) => {\n if (!tracingConfigured) {\n return;\n }\n\n const { message, level, error } = entry;\n const context = getContextFromEntry(entry);\n\n if (level !== LogLevel.TRACE) {\n return;\n }\n\n // NOTE: Make sure `entry` is not captured in this closure to avoid a memory leak.\n scheduleMicroTask(ctx, async () => {\n await SENTRY_INITIALIZED.wait();\n\n if (REPORT_SPANS && context?.span) {\n switch (context.span.command) {\n case 'begin': {\n const id = context.span.id;\n\n if (!id || SPAN_MAP.has(id)) {\n log.warn('Cannot begin span', id);\n return;\n }\n\n let parentSpan: Span = TX;\n if (context.span.parent) {\n parentSpan = SPAN_MAP.get(context.span.parent) ?? TX;\n }\n\n let logContext: string;\n try {\n logContext = JSON.stringify({ ...context, message, level, error });\n } catch (err) {\n logContext = JSON.stringify(context);\n }\n\n const span = parentSpan.startChild({\n op: message,\n data: {\n ...context.span.data,\n '@dxos/log': logContext,\n },\n });\n SPAN_MAP.set(context.span.id, span);\n break;\n }\n\n case 'end': {\n const span = SPAN_MAP.get(context.span.id);\n if (span) {\n span.setStatus(getSpanStatus(context.span.status));\n context.span.data && Object.entries(context.span.data).forEach(([key, value]) => span.setData(key, value));\n span.finish();\n SPAN_MAP.delete(context.span.id);\n } else {\n log.warn('Cannot end span', context.span.id);\n }\n break;\n }\n\n case 'update': {\n const span = SPAN_MAP.get(context.span.id);\n if (span) {\n context.span.data && Object.entries(context.span.data).forEach(([key, value]) => span.setData(key, value));\n } else {\n log.warn('Cannot update span', context.span.id);\n }\n break;\n }\n\n default: {\n log.warn('Unknown span command', context.span.command);\n }\n }\n }\n });\n};\n\nlog.runtimeConfig.processors.push(SENTRY_PROCESSOR);\n\n/**\n * @see https://develop.sentry.dev/sdk/event-payloads/span/#:~:text=this%20value%20explicitly.-,status,-Optional.%20Describes%20the\n */\nconst getSpanStatus = (status?: 'ok' | 'error') => {\n switch (status) {\n case 'ok':\n return 'ok';\n case 'error':\n return 'not_found';\n }\n return status ?? 'ok';\n};\n"],
5
- "mappings": "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",
6
- "names": ["init", "naturalInit", "setTag", "addBreadcrumb", "naturalAddBreadcrumb", "captureException", "naturalCaptureException", "BrowserTracing", "replayIntegration", "captureConsoleIntegration", "httpClientIntegration", "log", "getCurrentHub", "runInContext", "scheduleMicroTask", "Trigger", "Context", "invariant", "getContextFromEntry", "log", "LogLevel", "REPORT_SPANS", "TX", "SPAN_MAP", "Map", "SENTRY_INITIALIZED", "ctx", "onError", "err", "warn", "maxSafeDisposeCallbacks", "tracingConfigured", "configureTracing", "startTransaction", "name", "op", "window", "addEventListener", "finish", "process", "on", "wake", "span", "Array", "from", "values", "reverse", "SENTRY_PROCESSOR", "config", "entry", "message", "level", "error", "context", "TRACE", "wait", "command", "id", "has", "parentSpan", "parent", "get", "logContext", "JSON", "stringify", "startChild", "data", "set", "setStatus", "getSpanStatus", "status", "Object", "entries", "forEach", "key", "value", "setData", "delete", "runtimeConfig", "processors", "push", "setTag", "setTags", "setUser", "init", "options", "log", "naturalInit", "enabled", "enable", "dsn", "destination", "release", "environment", "integrations", "captureConsoleIntegration", "levels", "httpClientIntegration", "failedRequestStatusCodes", "tracing", "BrowserTracing", "replay", "replayIntegration", "blockAllMedia", "maskAllText", "replaysSessionSampleRate", "replaySampleRate", "replaysOnErrorSampleRate", "replaySampleRateOnError", "tracesSampleRate", "sampleRate", "transport", "beforeSend", "event", "onError", "Object", "entries", "properties", "forEach", "key", "value", "err", "catch", "addBreadcrumb", "breadcrumb", "naturalAddBreadcrumb", "captureException", "exception", "captureContext", "eventId", "naturalCaptureException", "enableSentryLogProcessor"]
7
- }