@dxos/observability 0.8.3 → 0.8.4-main.2e9d522
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/lib/browser/chunk-5ICT2XF2.mjs +1 -0
- package/dist/lib/browser/{chunk-G6EE7HFV.mjs → chunk-MWTIKIBZ.mjs} +9 -9
- package/dist/lib/browser/{chunk-YQJELTRP.mjs → chunk-UG3VTDOH.mjs} +18 -18
- package/dist/lib/browser/{chunk-YQJELTRP.mjs.map → chunk-UG3VTDOH.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-JA5VJRKF.mjs → chunk-YEPQFAES.mjs} +3 -3
- package/dist/lib/browser/index.mjs +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/observability-7LFMAZBF.mjs +10 -0
- package/dist/lib/browser/{otel-LHAFLNBQ.mjs → otel-IRDZ7PES.mjs} +7 -7
- package/dist/lib/browser/segment/index.mjs +3 -3
- package/dist/lib/browser/sentry/index.mjs +2 -2
- package/dist/lib/browser/{sentry-log-processor-625AISXI.mjs → sentry-log-processor-N3QNOQ2O.mjs} +9 -7
- package/dist/lib/browser/sentry-log-processor-N3QNOQ2O.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-AZMSBUWR.mjs → chunk-552KLA6Z.mjs} +9 -9
- package/dist/lib/node-esm/{chunk-YJ4KVBWC.mjs → chunk-QUZL7LKE.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-H7Y2DDUN.mjs → chunk-TEH6VIKV.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-M7QJLFGR.mjs → chunk-WLRNZ2S2.mjs} +18 -18
- package/dist/lib/node-esm/{chunk-M7QJLFGR.mjs.map → chunk-WLRNZ2S2.mjs.map} +2 -2
- package/dist/lib/node-esm/index.mjs +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/observability-F2NNZIF6.mjs +11 -0
- package/dist/lib/node-esm/{otel-AF5TSABC.mjs → otel-62HYJETM.mjs} +6 -6
- package/dist/lib/node-esm/segment/index.mjs +3 -3
- package/dist/lib/node-esm/sentry/index.mjs +2 -2
- package/dist/lib/node-esm/{sentry-log-processor-HPUPCMRG.mjs → sentry-log-processor-FN6Y5TNI.mjs} +9 -7
- package/dist/lib/node-esm/sentry-log-processor-FN6Y5TNI.mjs.map +7 -0
- package/dist/types/src/helpers/node-observability.js +2 -2
- package/dist/types/src/helpers/node-observability.js.map +1 -1
- package/dist/types/src/sentry/index.d.ts +1 -1
- package/dist/types/src/sentry/index.d.ts.map +1 -1
- package/dist/types/src/sentry/index.js +0 -1
- package/dist/types/src/sentry/index.js.map +1 -1
- package/dist/types/src/sentry/sentry-log-processor.d.ts.map +1 -1
- package/dist/types/src/sentry/sentry-log-processor.js +12 -10
- package/dist/types/src/sentry/sentry-log-processor.js.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -15
- package/src/helpers/node-observability.ts +2 -2
- package/src/sentry/index.ts +1 -1
- package/src/sentry/sentry-log-processor.ts +13 -5
- package/dist/lib/browser/chunk-KDP3SESE.mjs +0 -1
- package/dist/lib/browser/observability-HDE3I7TA.mjs +0 -10
- package/dist/lib/browser/sentry-log-processor-625AISXI.mjs.map +0 -7
- package/dist/lib/node/chunk-325GAGFA.cjs +0 -213
- package/dist/lib/node/chunk-325GAGFA.cjs.map +0 -7
- package/dist/lib/node/chunk-BZHVFSLF.cjs +0 -1025
- package/dist/lib/node/chunk-BZHVFSLF.cjs.map +0 -7
- package/dist/lib/node/chunk-GIYJMZEQ.cjs +0 -2
- package/dist/lib/node/chunk-GIYJMZEQ.cjs.map +0 -7
- package/dist/lib/node/chunk-MZ3PMDTP.cjs +0 -163
- package/dist/lib/node/chunk-MZ3PMDTP.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -60
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/observability-E2NGRIEN.cjs +0 -32
- package/dist/lib/node/observability-E2NGRIEN.cjs.map +0 -7
- package/dist/lib/node/otel-VF5YNCR3.cjs +0 -278
- package/dist/lib/node/otel-VF5YNCR3.cjs.map +0 -7
- package/dist/lib/node/segment/index.cjs +0 -33
- package/dist/lib/node/segment/index.cjs.map +0 -7
- package/dist/lib/node/sentry/index.cjs +0 -46
- package/dist/lib/node/sentry/index.cjs.map +0 -7
- package/dist/lib/node/sentry-log-processor-CCV4RL7N.cjs +0 -164
- package/dist/lib/node/sentry-log-processor-CCV4RL7N.cjs.map +0 -7
- package/dist/lib/node-esm/observability-7BTI46NM.mjs +0 -11
- package/dist/lib/node-esm/sentry-log-processor-HPUPCMRG.mjs.map +0 -7
- /package/dist/lib/browser/{chunk-KDP3SESE.mjs.map → chunk-5ICT2XF2.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-G6EE7HFV.mjs.map → chunk-MWTIKIBZ.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-JA5VJRKF.mjs.map → chunk-YEPQFAES.mjs.map} +0 -0
- /package/dist/lib/browser/{observability-HDE3I7TA.mjs.map → observability-7LFMAZBF.mjs.map} +0 -0
- /package/dist/lib/browser/{otel-LHAFLNBQ.mjs.map → otel-IRDZ7PES.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-AZMSBUWR.mjs.map → chunk-552KLA6Z.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-YJ4KVBWC.mjs.map → chunk-QUZL7LKE.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-H7Y2DDUN.mjs.map → chunk-TEH6VIKV.mjs.map} +0 -0
- /package/dist/lib/node-esm/{observability-7BTI46NM.mjs.map → observability-F2NNZIF6.mjs.map} +0 -0
- /package/dist/lib/node-esm/{otel-AF5TSABC.mjs.map → otel-62HYJETM.mjs.map} +0 -0
|
@@ -1,1025 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var chunk_BZHVFSLF_exports = {};
|
|
30
|
-
__export(chunk_BZHVFSLF_exports, {
|
|
31
|
-
OBSERVABILITY_DISABLED_KEY: () => OBSERVABILITY_DISABLED_KEY,
|
|
32
|
-
OBSERVABILITY_GROUP_KEY: () => OBSERVABILITY_GROUP_KEY,
|
|
33
|
-
Observability: () => Observability,
|
|
34
|
-
getObservabilityGroup: () => getObservabilityGroup,
|
|
35
|
-
getObservabilityState: () => getObservabilityState,
|
|
36
|
-
getTelemetryIdentifier: () => getTelemetryIdentifier,
|
|
37
|
-
getTelemetryIdentity: () => getTelemetryIdentity,
|
|
38
|
-
initializeAppObservability: () => initializeAppObservability,
|
|
39
|
-
initializeNodeObservability: () => initializeNodeObservability,
|
|
40
|
-
isObservabilityDisabled: () => isObservabilityDisabled,
|
|
41
|
-
mapSpaces: () => mapSpaces,
|
|
42
|
-
setupTelemetryListeners: () => setupTelemetryListeners,
|
|
43
|
-
showObservabilityBanner: () => showObservabilityBanner,
|
|
44
|
-
storeObservabilityDisabled: () => storeObservabilityDisabled,
|
|
45
|
-
storeObservabilityGroup: () => storeObservabilityGroup
|
|
46
|
-
});
|
|
47
|
-
module.exports = __toCommonJS(chunk_BZHVFSLF_exports);
|
|
48
|
-
var import_chunk_325GAGFA = require("./chunk-325GAGFA.cjs");
|
|
49
|
-
var import_async = require("@dxos/async");
|
|
50
|
-
var import_client = require("@dxos/client");
|
|
51
|
-
var import_context = require("@dxos/context");
|
|
52
|
-
var import_invariant = require("@dxos/invariant");
|
|
53
|
-
var import_log = require("@dxos/log");
|
|
54
|
-
var import_network_manager = require("@dxos/network-manager");
|
|
55
|
-
var import_services = require("@dxos/protocols/proto/dxos/client/services");
|
|
56
|
-
var import_util = require("@dxos/util");
|
|
57
|
-
var localForage = __toESM(require("localforage"));
|
|
58
|
-
var import_log2 = require("@dxos/log");
|
|
59
|
-
var import_js_yaml = __toESM(require("js-yaml"));
|
|
60
|
-
var import_node_fs = require("node:fs");
|
|
61
|
-
var import_promises = require("node:fs/promises");
|
|
62
|
-
var import_node_path = require("node:path");
|
|
63
|
-
var import_uuid = require("uuid");
|
|
64
|
-
var import_log3 = require("@dxos/log");
|
|
65
|
-
var cli_observability_secrets_default = {
|
|
66
|
-
SENTRY_DESTINATION: "https://2647916221e643869965e78469479aa4@o4504012000067584.ingest.sentry.io/4504012027265029",
|
|
67
|
-
TELEMETRY_API_KEY: "B00QG6PtJJrJ0VVFe0H5a6bcUUShKyZM",
|
|
68
|
-
IPDATA_API_KEY: "73dfdecdf979c18f07d50cf841bbdd9e589f237256326ac8cca23786",
|
|
69
|
-
OTEL_ENDPOINT: "https://otlp-proxy.dxos.workers.dev",
|
|
70
|
-
OTEL_AUTHORIZATION: "Basic OTA3MzIzOmdsY19leUp2SWpvaU1URXdNVEl6TnlJc0ltNGlPaUp6ZEdGamF5MDVNRGN6TWpNdGFXNTBaV2R5WVhScGIyNHRZMnh2ZFdSbWJHRnlaUzF2ZEd4d0xYQnliM2g1SWl3aWF5STZJalZ2Tkd4cFYydE5iRmszTlRNMGJUVXpTemRTVjNBeVNpSXNJbTBpT25zaWNpSTZJbkJ5YjJRdGRYTXRaV0Z6ZEMwd0luMTk="
|
|
71
|
-
};
|
|
72
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/sdk/observability/src/helpers/browser-observability.ts";
|
|
73
|
-
var OBSERVABILITY_DISABLED_KEY = "observability-disabled";
|
|
74
|
-
var OBSERVABILITY_GROUP_KEY = "observability-group";
|
|
75
|
-
var isObservabilityDisabled = async (namespace) => {
|
|
76
|
-
try {
|
|
77
|
-
return await localForage.getItem(`${namespace}:${OBSERVABILITY_DISABLED_KEY}`) === "true";
|
|
78
|
-
} catch (err) {
|
|
79
|
-
import_log2.log.catch("Failed to check if observability is disabled, assuming it is", err, {
|
|
80
|
-
F: __dxlog_file,
|
|
81
|
-
L: 24,
|
|
82
|
-
S: void 0,
|
|
83
|
-
C: (f, a) => f(...a)
|
|
84
|
-
});
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
var storeObservabilityDisabled = async (namespace, value) => {
|
|
89
|
-
try {
|
|
90
|
-
await localForage.setItem(`${namespace}:${OBSERVABILITY_DISABLED_KEY}`, String(value));
|
|
91
|
-
} catch (err) {
|
|
92
|
-
import_log2.log.catch("Failed to store observability disabled", err, {
|
|
93
|
-
F: __dxlog_file,
|
|
94
|
-
L: 33,
|
|
95
|
-
S: void 0,
|
|
96
|
-
C: (f, a) => f(...a)
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
var getObservabilityGroup = async (namespace) => {
|
|
101
|
-
try {
|
|
102
|
-
return await localForage.getItem(`${namespace}:${OBSERVABILITY_GROUP_KEY}`) ?? void 0;
|
|
103
|
-
} catch (err) {
|
|
104
|
-
import_log2.log.catch("Failed to get observability group", err, {
|
|
105
|
-
F: __dxlog_file,
|
|
106
|
-
L: 41,
|
|
107
|
-
S: void 0,
|
|
108
|
-
C: (f, a) => f(...a)
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
var storeObservabilityGroup = async (namespace, value) => {
|
|
113
|
-
try {
|
|
114
|
-
await localForage.setItem(`${namespace}:${OBSERVABILITY_GROUP_KEY}`, value);
|
|
115
|
-
} catch (err) {
|
|
116
|
-
import_log2.log.catch("Failed to store observability group", err, {
|
|
117
|
-
F: __dxlog_file,
|
|
118
|
-
L: 49,
|
|
119
|
-
S: void 0,
|
|
120
|
-
C: (f, a) => f(...a)
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
var initializeAppObservability = async ({
|
|
125
|
-
namespace,
|
|
126
|
-
config,
|
|
127
|
-
// TODO(nf): Configure mode.
|
|
128
|
-
mode = "basic",
|
|
129
|
-
tracingEnable = false,
|
|
130
|
-
replayEnable = false
|
|
131
|
-
}) => {
|
|
132
|
-
(0, import_log2.log)("initializeAppObservability", {
|
|
133
|
-
config
|
|
134
|
-
}, {
|
|
135
|
-
F: __dxlog_file,
|
|
136
|
-
L: 73,
|
|
137
|
-
S: void 0,
|
|
138
|
-
C: (f, a) => f(...a)
|
|
139
|
-
});
|
|
140
|
-
const group = await getObservabilityGroup(namespace) ?? void 0;
|
|
141
|
-
const release = `${namespace}@${config.get("runtime.app.build.version")}`;
|
|
142
|
-
const environment = config.get("runtime.app.env.DX_ENVIRONMENT");
|
|
143
|
-
const { Observability: Observability2 } = await import("./observability-E2NGRIEN.cjs");
|
|
144
|
-
const observability = new Observability2({
|
|
145
|
-
namespace,
|
|
146
|
-
release,
|
|
147
|
-
environment,
|
|
148
|
-
group,
|
|
149
|
-
mode,
|
|
150
|
-
config,
|
|
151
|
-
errorLog: {
|
|
152
|
-
sentryInitOptions: {
|
|
153
|
-
environment,
|
|
154
|
-
release,
|
|
155
|
-
tracing: tracingEnable,
|
|
156
|
-
replay: replayEnable,
|
|
157
|
-
// TODO(wittjosiah): Configure these.
|
|
158
|
-
// Consider using a sampling function to dynamically configure these values.
|
|
159
|
-
// https://docs.sentry.io/platforms/javascript/configuration/sampling/#setting-a-sampling-function
|
|
160
|
-
sampleRate: 1,
|
|
161
|
-
replaySampleRate: 1,
|
|
162
|
-
replaySampleRateOnError: 1
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
const observabilityDisabled = await isObservabilityDisabled(namespace);
|
|
167
|
-
if (observabilityDisabled) {
|
|
168
|
-
observability.setMode("disabled");
|
|
169
|
-
import_log2.log.info("observability disabled", void 0, {
|
|
170
|
-
F: __dxlog_file,
|
|
171
|
-
L: 113,
|
|
172
|
-
S: void 0,
|
|
173
|
-
C: (f, a) => f(...a)
|
|
174
|
-
});
|
|
175
|
-
return observability;
|
|
176
|
-
}
|
|
177
|
-
try {
|
|
178
|
-
const getIPData = async (config2) => {
|
|
179
|
-
const IP_DATA_CACHE_TIMEOUT = 6 * 60 * 60 * 1e3;
|
|
180
|
-
const cachedData = await localForage.getItem("dxos:observability:ipdata");
|
|
181
|
-
if (cachedData && cachedData.timestamp > Date.now() - IP_DATA_CACHE_TIMEOUT) {
|
|
182
|
-
return cachedData.data;
|
|
183
|
-
}
|
|
184
|
-
const IPDATA_API_KEY = config2.get("runtime.app.env.DX_IPDATA_API_KEY");
|
|
185
|
-
if (IPDATA_API_KEY) {
|
|
186
|
-
return fetch(`https://api.ipdata.co?api-key=${IPDATA_API_KEY}`).then((res) => res.json()).then((data) => {
|
|
187
|
-
localForage.setItem("dxos:observability:ipdata", {
|
|
188
|
-
data,
|
|
189
|
-
timestamp: Date.now()
|
|
190
|
-
}).catch((err) => observability.captureException(err));
|
|
191
|
-
return data;
|
|
192
|
-
}).catch((err) => observability.captureException(err));
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
await observability.initialize();
|
|
196
|
-
observability.startErrorLogs();
|
|
197
|
-
const ipData = await getIPData(config);
|
|
198
|
-
ipData && observability.setIPDataTelemetryTags(ipData);
|
|
199
|
-
if (typeof navigator !== "undefined" && navigator.storage?.estimate) {
|
|
200
|
-
setInterval(async () => {
|
|
201
|
-
try {
|
|
202
|
-
const storageEstimate = await navigator.storage.estimate();
|
|
203
|
-
storageEstimate.usage && observability.setTag("storageUsage", storageEstimate.usage.toString(), "telemetry");
|
|
204
|
-
storageEstimate.quota && observability.setTag("storageQuota", storageEstimate.quota.toString(), "telemetry");
|
|
205
|
-
} catch (error) {
|
|
206
|
-
import_log2.log.warn("Failed to run estimate()", error, {
|
|
207
|
-
F: __dxlog_file,
|
|
208
|
-
L: 168,
|
|
209
|
-
S: void 0,
|
|
210
|
-
C: (f, a) => f(...a)
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}, 1e4);
|
|
214
|
-
}
|
|
215
|
-
} catch (err) {
|
|
216
|
-
import_log2.log.error("Failed to initialize app observability", err, {
|
|
217
|
-
F: __dxlog_file,
|
|
218
|
-
L: 173,
|
|
219
|
-
S: void 0,
|
|
220
|
-
C: (f, a) => f(...a)
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
return observability;
|
|
224
|
-
};
|
|
225
|
-
var getTelemetryIdentifier = (client) => {
|
|
226
|
-
if (!client?.initialized) {
|
|
227
|
-
return void 0;
|
|
228
|
-
}
|
|
229
|
-
const identity = client.halo.identity.get();
|
|
230
|
-
if (identity) {
|
|
231
|
-
return identity.did;
|
|
232
|
-
}
|
|
233
|
-
return void 0;
|
|
234
|
-
};
|
|
235
|
-
var getTelemetryIdentity = (client) => {
|
|
236
|
-
const did = getTelemetryIdentifier(client);
|
|
237
|
-
return {
|
|
238
|
-
did
|
|
239
|
-
};
|
|
240
|
-
};
|
|
241
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/sdk/observability/src/helpers/node-observability.ts";
|
|
242
|
-
var showObservabilityBanner = async (configDir, bannercb) => {
|
|
243
|
-
const path = (0, import_node_path.join)(configDir, ".observability-banner-printed");
|
|
244
|
-
if ((0, import_node_fs.existsSync)(path)) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
bannercb(
|
|
248
|
-
// eslint-disable-next-line no-multi-str
|
|
249
|
-
"Basic observability data will be sent to the DXOS team in order to improve the product. This includes performance metrics, error logs, and usage data. No personally identifiable information, other than your public key, is included with this data and no private data ever leaves your devices. To disable sending observability data, set the environment variable DX_DISABLE_OBSERVABILITY=true."
|
|
250
|
-
);
|
|
251
|
-
await (0, import_promises.writeFile)(path, "", "utf-8");
|
|
252
|
-
};
|
|
253
|
-
var getObservabilityState = async (configDir) => {
|
|
254
|
-
if ((0, import_node_fs.existsSync)(configDir)) {
|
|
255
|
-
if (!(0, import_node_fs.statSync)(configDir).isDirectory()) {
|
|
256
|
-
throw new Error(`Config directory ${configDir} exists but is not a directory`);
|
|
257
|
-
}
|
|
258
|
-
} else {
|
|
259
|
-
await (0, import_promises.mkdir)(configDir, {
|
|
260
|
-
recursive: true
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
const idPath = (0, import_node_path.join)(configDir, "observability.yml");
|
|
264
|
-
if ((0, import_node_fs.existsSync)(idPath)) {
|
|
265
|
-
const context = await (0, import_promises.readFile)(idPath, "utf-8");
|
|
266
|
-
return validate(context) ?? initializeState(idPath);
|
|
267
|
-
}
|
|
268
|
-
return initializeState(idPath);
|
|
269
|
-
};
|
|
270
|
-
var initializeState = async (idPath) => {
|
|
271
|
-
const observabilityState = {
|
|
272
|
-
installationId: (0, import_uuid.v4)(),
|
|
273
|
-
group: process.env.DX_OBSERVABILITY_GROUP ?? void 0,
|
|
274
|
-
mode: process.env.DX_DISABLE_OBSERVABILITY ? "disabled" : process.env.DX_OBSERVABILITY_MODE ?? "basic"
|
|
275
|
-
};
|
|
276
|
-
await (0, import_promises.writeFile)(idPath, "# This file is automatically generated by the @dxos/cli.\n" + import_js_yaml.default.dump(observabilityState), "utf-8");
|
|
277
|
-
return observabilityState;
|
|
278
|
-
};
|
|
279
|
-
var validate = (contextString) => {
|
|
280
|
-
const context = import_js_yaml.default.load(contextString);
|
|
281
|
-
if (Boolean(context.installationId) && (0, import_uuid.validate)(context.installationId)) {
|
|
282
|
-
return {
|
|
283
|
-
...context,
|
|
284
|
-
mode: process.env.DX_DISABLE_OBSERVABILITY ? "disabled" : context.mode ?? "basic"
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
var initializeNodeObservability = async ({ namespace, version, config, installationId, group, mode = "basic", tracingEnable = true, replayEnable = true }) => {
|
|
289
|
-
(0, import_log3.log)("initializeCliObservability", {
|
|
290
|
-
config
|
|
291
|
-
}, {
|
|
292
|
-
F: __dxlog_file2,
|
|
293
|
-
L: 110,
|
|
294
|
-
S: void 0,
|
|
295
|
-
C: (f, a) => f(...a)
|
|
296
|
-
});
|
|
297
|
-
const release = `${namespace}@${version}`;
|
|
298
|
-
const environment = process.env.DX_ENVIRONMENT ?? "unknown";
|
|
299
|
-
const observability = new Observability({
|
|
300
|
-
mode,
|
|
301
|
-
namespace,
|
|
302
|
-
release,
|
|
303
|
-
environment,
|
|
304
|
-
group,
|
|
305
|
-
errorLog: {
|
|
306
|
-
sentryInitOptions: {
|
|
307
|
-
environment,
|
|
308
|
-
release,
|
|
309
|
-
// TODO(wittjosiah): Configure this.
|
|
310
|
-
sampleRate: 1
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
observability.setTag("installationId", installationId);
|
|
315
|
-
const IPDATA_API_KEY = config.get("runtime.app.env.DX_IPDATA_API_KEY");
|
|
316
|
-
try {
|
|
317
|
-
const res = await fetch(`https://api.ipdata.co/?api-key=${IPDATA_API_KEY}`);
|
|
318
|
-
const ipData = await res.json();
|
|
319
|
-
ipData && observability.setIPDataTelemetryTags(ipData);
|
|
320
|
-
} catch (err) {
|
|
321
|
-
observability?.captureException(err);
|
|
322
|
-
}
|
|
323
|
-
return observability;
|
|
324
|
-
};
|
|
325
|
-
var mapSpaces = (spaces, options = {
|
|
326
|
-
verbose: false,
|
|
327
|
-
truncateKeys: false
|
|
328
|
-
}) => {
|
|
329
|
-
return spaces.map((space) => {
|
|
330
|
-
const { open, ready } = space.internal.data.metrics ?? {};
|
|
331
|
-
const startup = open && ready && ready.getTime() - open.getTime();
|
|
332
|
-
const pipeline = space.internal.data.pipeline;
|
|
333
|
-
const startDataMutations = pipeline?.currentEpoch?.subject.assertion.timeframe.totalMessages() ?? 0;
|
|
334
|
-
const epoch = pipeline?.currentEpoch?.subject.assertion.number;
|
|
335
|
-
const currentDataMutations = pipeline?.currentDataTimeframe?.totalMessages() ?? 0;
|
|
336
|
-
const totalDataMutations = pipeline?.targetDataTimeframe?.totalMessages() ?? 0;
|
|
337
|
-
return {
|
|
338
|
-
// TODO(nf): truncate keys for DD?
|
|
339
|
-
key: space.key.truncate(),
|
|
340
|
-
open: space.isOpen,
|
|
341
|
-
members: space.members.get().length,
|
|
342
|
-
objects: space.db.coreDatabase.getAllObjectIds().length,
|
|
343
|
-
startup,
|
|
344
|
-
epoch,
|
|
345
|
-
// appliedEpoch,
|
|
346
|
-
startDataMutations,
|
|
347
|
-
currentDataMutations,
|
|
348
|
-
totalDataMutations,
|
|
349
|
-
// TODO(burdon): Negative?
|
|
350
|
-
progress: (Math.min(Math.abs((currentDataMutations - startDataMutations) / (totalDataMutations - startDataMutations)), 1) * 100).toFixed(0)
|
|
351
|
-
};
|
|
352
|
-
});
|
|
353
|
-
};
|
|
354
|
-
var lastFocusEvent = /* @__PURE__ */ new Date();
|
|
355
|
-
var totalTime = 0;
|
|
356
|
-
var setupTelemetryListeners = (namespace, client, observability) => {
|
|
357
|
-
const clickCallback = (event) => {
|
|
358
|
-
const id = event.target?.id;
|
|
359
|
-
if (!id) {
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
setTimeout(() => {
|
|
363
|
-
observability.track({
|
|
364
|
-
...getTelemetryIdentity(client),
|
|
365
|
-
action: "window.click",
|
|
366
|
-
properties: {
|
|
367
|
-
id: event.target?.id,
|
|
368
|
-
path: event.composedPath().filter((el) => Boolean(el.tagName)).map((el) => `${el.tagName.toLowerCase()}${el.id ? `#${el.id}` : ""}`).reverse().join(">")
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
};
|
|
373
|
-
const focusCallback = () => {
|
|
374
|
-
const now = /* @__PURE__ */ new Date();
|
|
375
|
-
setTimeout(() => {
|
|
376
|
-
observability.track({
|
|
377
|
-
...getTelemetryIdentity(client),
|
|
378
|
-
action: "window.focus",
|
|
379
|
-
properties: {
|
|
380
|
-
timeAway: now.getTime() - lastFocusEvent.getTime()
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
lastFocusEvent = now;
|
|
385
|
-
};
|
|
386
|
-
const blurCallback = () => {
|
|
387
|
-
const now = /* @__PURE__ */ new Date();
|
|
388
|
-
const duration = now.getTime() - lastFocusEvent.getTime();
|
|
389
|
-
setTimeout(() => {
|
|
390
|
-
observability.track({
|
|
391
|
-
...getTelemetryIdentity(client),
|
|
392
|
-
action: "window.blur",
|
|
393
|
-
properties: {
|
|
394
|
-
duration
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
});
|
|
398
|
-
lastFocusEvent = now;
|
|
399
|
-
totalTime = totalTime + duration;
|
|
400
|
-
};
|
|
401
|
-
const unloadCallback = () => {
|
|
402
|
-
setTimeout(() => {
|
|
403
|
-
observability.track({
|
|
404
|
-
...getTelemetryIdentity(client),
|
|
405
|
-
action: "page.unload",
|
|
406
|
-
properties: {
|
|
407
|
-
duration: totalTime
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
});
|
|
411
|
-
};
|
|
412
|
-
const errorCallback = (event) => {
|
|
413
|
-
setTimeout(() => {
|
|
414
|
-
observability.track({
|
|
415
|
-
...getTelemetryIdentity(client),
|
|
416
|
-
action: "window.error",
|
|
417
|
-
properties: {
|
|
418
|
-
message: event.message,
|
|
419
|
-
filename: event.filename,
|
|
420
|
-
stack: event.error?.stack,
|
|
421
|
-
cause: event.error?.cause
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
});
|
|
425
|
-
};
|
|
426
|
-
window.addEventListener("click", clickCallback, true);
|
|
427
|
-
window.addEventListener("focus", focusCallback);
|
|
428
|
-
window.addEventListener("blur", blurCallback);
|
|
429
|
-
window.addEventListener("beforeunload", unloadCallback);
|
|
430
|
-
window.addEventListener("error", errorCallback);
|
|
431
|
-
return () => {
|
|
432
|
-
window.removeEventListener("click", clickCallback, true);
|
|
433
|
-
window.removeEventListener("focus", focusCallback);
|
|
434
|
-
window.removeEventListener("blur", blurCallback);
|
|
435
|
-
window.removeEventListener("beforeunload", unloadCallback);
|
|
436
|
-
window.removeEventListener("error", errorCallback);
|
|
437
|
-
};
|
|
438
|
-
};
|
|
439
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/sdk/observability/src/observability.ts";
|
|
440
|
-
var SPACE_METRICS_MIN_INTERVAL = 1e3 * 60;
|
|
441
|
-
var SPACE_TELEMETRY_MIN_INTERVAL = 1e3 * 60 * 60;
|
|
442
|
-
var NETWORK_METRICS_MIN_INTERVAL = 1e3 * 60 * 5;
|
|
443
|
-
var Observability = class {
|
|
444
|
-
// TODO(nf): make platform a required extension?
|
|
445
|
-
constructor({ mode, namespace, environment, release, config, group, secrets, telemetry, errorLog }) {
|
|
446
|
-
this._tags = /* @__PURE__ */ new Map();
|
|
447
|
-
this._ctx = new import_context.Context(void 0, {
|
|
448
|
-
F: __dxlog_file3,
|
|
449
|
-
L: 115
|
|
450
|
-
});
|
|
451
|
-
this.setIPDataTelemetryTags = (ipData) => {
|
|
452
|
-
this.setTag("city", ipData.city, "telemetry");
|
|
453
|
-
this.setTag("region", ipData.region, "telemetry");
|
|
454
|
-
this.setTag("country", ipData.country, "telemetry");
|
|
455
|
-
ipData.latitude && this.setTag("latitude", ipData.latitude.toString(), "telemetry");
|
|
456
|
-
ipData.longitude && this.setTag("longitude", ipData.longitude.toString(), "telemetry");
|
|
457
|
-
};
|
|
458
|
-
this._mode = mode;
|
|
459
|
-
this._namespace = namespace;
|
|
460
|
-
this._config = config;
|
|
461
|
-
this._group = group;
|
|
462
|
-
this._secrets = this._loadSecrets(config, secrets);
|
|
463
|
-
this._telemetryBatchSize = telemetry?.batchSize ?? 30;
|
|
464
|
-
this._errorReportingOptions = errorLog?.sentryInitOptions;
|
|
465
|
-
this.setTag("mode", this._mode);
|
|
466
|
-
this.setTag("namespace", this._namespace);
|
|
467
|
-
this.setTag("environment", environment);
|
|
468
|
-
this.setTag("release", release);
|
|
469
|
-
this.setTag("session", import_client.PublicKey.random().toHex());
|
|
470
|
-
this.setTag("group", this._group);
|
|
471
|
-
}
|
|
472
|
-
get mode() {
|
|
473
|
-
return this._mode;
|
|
474
|
-
}
|
|
475
|
-
get group() {
|
|
476
|
-
return this._group;
|
|
477
|
-
}
|
|
478
|
-
get enabled() {
|
|
479
|
-
return this._mode !== "disabled";
|
|
480
|
-
}
|
|
481
|
-
_loadSecrets(config, secrets) {
|
|
482
|
-
if ((0, import_util.isNode)()) {
|
|
483
|
-
const mergedSecrets = {
|
|
484
|
-
...cli_observability_secrets_default,
|
|
485
|
-
...secrets
|
|
486
|
-
};
|
|
487
|
-
process.env.DX_ENVIRONMENT && (mergedSecrets.DX_ENVIRONMENT = process.env.DX_ENVIRONMENT);
|
|
488
|
-
process.env.DX_RELEASE && (mergedSecrets.DX_RELEASE = process.env.DX_RELEASE);
|
|
489
|
-
process.env.SENTRY_DESTINATION && (mergedSecrets.SENTRY_DESTINATION = process.env.SENTRY_DESTINATION);
|
|
490
|
-
process.env.TELEMETRY_API_KEY && (mergedSecrets.TELEMETRY_API_KEY = process.env.TELEMETRY_API_KEY);
|
|
491
|
-
process.env.IPDATA_API_KEY && (mergedSecrets.IPDATA_API_KEY = process.env.IPDATA_API_KEY);
|
|
492
|
-
process.env.DX_OTEL_ENDPOINT && (mergedSecrets.OTEL_ENDPOINT = process.env.DX_OTEL_ENDPOINT);
|
|
493
|
-
process.env.DX_OTEL_AUTHORIZATION && (mergedSecrets.OTEL_AUTHORIZATION = process.env.DX_OTEL_AUTHORIZATION);
|
|
494
|
-
return mergedSecrets;
|
|
495
|
-
} else {
|
|
496
|
-
(0, import_log.log)("config", {
|
|
497
|
-
rtc: this._secrets,
|
|
498
|
-
config
|
|
499
|
-
}, {
|
|
500
|
-
F: __dxlog_file3,
|
|
501
|
-
L: 176,
|
|
502
|
-
S: this,
|
|
503
|
-
C: (f, a) => f(...a)
|
|
504
|
-
});
|
|
505
|
-
return {
|
|
506
|
-
DX_ENVIRONMENT: config?.get("runtime.app.env.DX_ENVIRONMENT"),
|
|
507
|
-
DX_RELEASE: config?.get("runtime.app.env.DX_RELEASE"),
|
|
508
|
-
SENTRY_DESTINATION: config?.get("runtime.app.env.DX_SENTRY_DESTINATION"),
|
|
509
|
-
TELEMETRY_API_KEY: config?.get("runtime.app.env.DX_TELEMETRY_API_KEY"),
|
|
510
|
-
IPDATA_API_KEY: config?.get("runtime.app.env.DX_IPDATA_API_KEY"),
|
|
511
|
-
OTEL_ENDPOINT: config?.get("runtime.app.env.DX_OTEL_ENDPOINT"),
|
|
512
|
-
OTEL_AUTHORIZATION: config?.get("runtime.app.env.DX_OTEL_AUTHORIZATION"),
|
|
513
|
-
...secrets
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
async initialize() {
|
|
518
|
-
(0, import_log.log)("initializing...", void 0, {
|
|
519
|
-
F: __dxlog_file3,
|
|
520
|
-
L: 191,
|
|
521
|
-
S: this,
|
|
522
|
-
C: (f, a) => f(...a)
|
|
523
|
-
});
|
|
524
|
-
await this._initLogs();
|
|
525
|
-
await this._initMetrics();
|
|
526
|
-
await this._initTelemetry();
|
|
527
|
-
await this._initErrorLogs();
|
|
528
|
-
await this._initTraces();
|
|
529
|
-
}
|
|
530
|
-
async close() {
|
|
531
|
-
(0, import_log.log)("closing...", void 0, {
|
|
532
|
-
F: __dxlog_file3,
|
|
533
|
-
L: 200,
|
|
534
|
-
S: this,
|
|
535
|
-
C: (f, a) => f(...a)
|
|
536
|
-
});
|
|
537
|
-
const closes = [];
|
|
538
|
-
this._telemetry && closes.push(this._telemetry.close());
|
|
539
|
-
this._otelMetrics && closes.push(this._otelMetrics.close());
|
|
540
|
-
this._otelLogs && closes.push(this._otelLogs.close());
|
|
541
|
-
await Promise.all(closes);
|
|
542
|
-
await this._ctx.dispose();
|
|
543
|
-
}
|
|
544
|
-
setMode(mode) {
|
|
545
|
-
this._mode = mode;
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* camelCase keys are converted to snake_case in Segment.
|
|
549
|
-
*/
|
|
550
|
-
setTag(key, value, scope) {
|
|
551
|
-
if (value === void 0) {
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
|
-
if (this.enabled && (scope === void 0 || scope === "all" || scope === "errors")) {
|
|
555
|
-
this._setTag?.(key, value);
|
|
556
|
-
}
|
|
557
|
-
if (!scope) {
|
|
558
|
-
scope = "all";
|
|
559
|
-
}
|
|
560
|
-
this._tags.set(key, {
|
|
561
|
-
value,
|
|
562
|
-
scope
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
getTag(key) {
|
|
566
|
-
return this._tags.get(key);
|
|
567
|
-
}
|
|
568
|
-
// TODO(wittjosiah): Improve privacy of telemetry identifiers. See `getTelemetryIdentifier`.
|
|
569
|
-
async setIdentityTags(clientServices) {
|
|
570
|
-
if (clientServices.IdentityService) {
|
|
571
|
-
clientServices.IdentityService.queryIdentity().subscribe((idqr) => {
|
|
572
|
-
if (!idqr?.identity?.did) {
|
|
573
|
-
(0, import_log.log)("empty response from identity service", {
|
|
574
|
-
idqr
|
|
575
|
-
}, {
|
|
576
|
-
F: __dxlog_file3,
|
|
577
|
-
L: 247,
|
|
578
|
-
S: this,
|
|
579
|
-
C: (f, a) => f(...a)
|
|
580
|
-
});
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
this.setTag("did", idqr.identity.did);
|
|
584
|
-
this._telemetry?.identify({
|
|
585
|
-
userId: idqr.identity.did
|
|
586
|
-
});
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
if (clientServices.DevicesService) {
|
|
590
|
-
clientServices.DevicesService.queryDevices().subscribe((dqr) => {
|
|
591
|
-
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
592
|
-
(0, import_log.log)("empty response from device service", {
|
|
593
|
-
device: dqr
|
|
594
|
-
}, {
|
|
595
|
-
F: __dxlog_file3,
|
|
596
|
-
L: 259,
|
|
597
|
-
S: this,
|
|
598
|
-
C: (f, a) => f(...a)
|
|
599
|
-
});
|
|
600
|
-
return;
|
|
601
|
-
}
|
|
602
|
-
(0, import_invariant.invariant)(dqr, "empty response from device service", {
|
|
603
|
-
F: __dxlog_file3,
|
|
604
|
-
L: 263,
|
|
605
|
-
S: this,
|
|
606
|
-
A: [
|
|
607
|
-
"dqr",
|
|
608
|
-
"'empty response from device service'"
|
|
609
|
-
]
|
|
610
|
-
});
|
|
611
|
-
const thisDevice = dqr.devices.find((device) => device.kind === import_services.DeviceKind.CURRENT);
|
|
612
|
-
if (!thisDevice) {
|
|
613
|
-
(0, import_log.log)("no current device", {
|
|
614
|
-
device: dqr
|
|
615
|
-
}, {
|
|
616
|
-
F: __dxlog_file3,
|
|
617
|
-
L: 266,
|
|
618
|
-
S: this,
|
|
619
|
-
C: (f, a) => f(...a)
|
|
620
|
-
});
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
this.setTag("deviceKey", thisDevice.deviceKey.truncate());
|
|
624
|
-
if (thisDevice.profile?.label) {
|
|
625
|
-
this.setTag("deviceProfile", thisDevice.profile.label);
|
|
626
|
-
}
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
//
|
|
631
|
-
// Logs
|
|
632
|
-
//
|
|
633
|
-
async _initLogs() {
|
|
634
|
-
if (this._secrets.OTEL_ENDPOINT && this._secrets.OTEL_AUTHORIZATION && this._mode !== "disabled") {
|
|
635
|
-
const { OtelLogs } = await import("./otel-VF5YNCR3.cjs");
|
|
636
|
-
this._otelLogs = new OtelLogs({
|
|
637
|
-
endpoint: this._secrets.OTEL_ENDPOINT,
|
|
638
|
-
authorizationHeader: this._secrets.OTEL_AUTHORIZATION,
|
|
639
|
-
serviceName: this._namespace,
|
|
640
|
-
serviceVersion: this.getTag("release")?.value ?? "0.0.0",
|
|
641
|
-
getTags: () => Object.fromEntries(Array.from(this._tags).filter(([key, value]) => {
|
|
642
|
-
return value.scope === "all" || value.scope === "errors";
|
|
643
|
-
}).map(([key, value]) => [
|
|
644
|
-
key,
|
|
645
|
-
value.value
|
|
646
|
-
])),
|
|
647
|
-
logLevel: import_log.LogLevel.VERBOSE,
|
|
648
|
-
includeSharedWorkerLogs: false
|
|
649
|
-
});
|
|
650
|
-
this._otelLogs && import_log.log.runtimeConfig.processors.push(this._otelLogs.logProcessor);
|
|
651
|
-
(0, import_log.log)("otel logs enabled", {
|
|
652
|
-
namespace: this._namespace
|
|
653
|
-
}, {
|
|
654
|
-
F: __dxlog_file3,
|
|
655
|
-
L: 310,
|
|
656
|
-
S: this,
|
|
657
|
-
C: (f, a) => f(...a)
|
|
658
|
-
});
|
|
659
|
-
} else {
|
|
660
|
-
(0, import_log.log)("otel logs disabled", void 0, {
|
|
661
|
-
F: __dxlog_file3,
|
|
662
|
-
L: 312,
|
|
663
|
-
S: this,
|
|
664
|
-
C: (f, a) => f(...a)
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
//
|
|
669
|
-
// Metrics
|
|
670
|
-
//
|
|
671
|
-
async _initMetrics() {
|
|
672
|
-
if (this.enabled && this._secrets.OTEL_ENDPOINT && this._secrets.OTEL_AUTHORIZATION) {
|
|
673
|
-
const { OtelMetrics } = await import("./otel-VF5YNCR3.cjs");
|
|
674
|
-
this._otelMetrics = new OtelMetrics({
|
|
675
|
-
endpoint: this._secrets.OTEL_ENDPOINT,
|
|
676
|
-
authorizationHeader: this._secrets.OTEL_AUTHORIZATION,
|
|
677
|
-
serviceName: this._namespace,
|
|
678
|
-
serviceVersion: this.getTag("release")?.value ?? "0.0.0",
|
|
679
|
-
getTags: () => Object.fromEntries(Array.from(this._tags).filter(([key, value]) => {
|
|
680
|
-
return value.scope === "all" || value.scope === "metrics";
|
|
681
|
-
}).map(([key, value]) => [
|
|
682
|
-
key,
|
|
683
|
-
value.value
|
|
684
|
-
]))
|
|
685
|
-
});
|
|
686
|
-
(0, import_log.log)("otel metrics enabled", void 0, {
|
|
687
|
-
F: __dxlog_file3,
|
|
688
|
-
L: 337,
|
|
689
|
-
S: this,
|
|
690
|
-
C: (f, a) => f(...a)
|
|
691
|
-
});
|
|
692
|
-
} else {
|
|
693
|
-
(0, import_log.log)("otel metrics disabled", void 0, {
|
|
694
|
-
F: __dxlog_file3,
|
|
695
|
-
L: 339,
|
|
696
|
-
S: this,
|
|
697
|
-
C: (f, a) => f(...a)
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Gauge metric.
|
|
703
|
-
*
|
|
704
|
-
* The default implementation uses OpenTelemetry
|
|
705
|
-
*/
|
|
706
|
-
gauge(name, value, extraTags) {
|
|
707
|
-
this._otelMetrics?.gauge(name, value, extraTags);
|
|
708
|
-
}
|
|
709
|
-
// TODO(nf): Refactor into ObservabilityExtensions.
|
|
710
|
-
startNetworkMetrics(clientServices) {
|
|
711
|
-
if (!clientServices.NetworkService) {
|
|
712
|
-
return;
|
|
713
|
-
}
|
|
714
|
-
const updateSignalMetrics = new import_async.Event().debounce(NETWORK_METRICS_MIN_INTERVAL);
|
|
715
|
-
updateSignalMetrics.on(this._ctx, async () => {
|
|
716
|
-
(0, import_log.log)("send signal metrics", void 0, {
|
|
717
|
-
F: __dxlog_file3,
|
|
718
|
-
L: 361,
|
|
719
|
-
S: this,
|
|
720
|
-
C: (f, a) => f(...a)
|
|
721
|
-
});
|
|
722
|
-
this._lastNetworkStatus?.signaling?.forEach(({ server, state }) => {
|
|
723
|
-
this.gauge("dxos.client.network.signal.connectionState", state, {
|
|
724
|
-
server
|
|
725
|
-
});
|
|
726
|
-
});
|
|
727
|
-
let swarmCount = 0;
|
|
728
|
-
const connectionStates = /* @__PURE__ */ new Map();
|
|
729
|
-
for (const state in import_network_manager.ConnectionState) {
|
|
730
|
-
connectionStates.set(state, 0);
|
|
731
|
-
}
|
|
732
|
-
let totalReadBufferSize = 0;
|
|
733
|
-
let totalWriteBufferSize = 0;
|
|
734
|
-
let totalChannelBufferSize = 0;
|
|
735
|
-
this._lastNetworkStatus?.connectionInfo?.forEach((connectionInfo) => {
|
|
736
|
-
swarmCount++;
|
|
737
|
-
for (const conn of connectionInfo.connections ?? []) {
|
|
738
|
-
connectionStates.set(conn.state, (connectionStates.get(conn.state) ?? 0) + 1);
|
|
739
|
-
totalReadBufferSize += conn.readBufferSize ?? 0;
|
|
740
|
-
totalWriteBufferSize += conn.writeBufferSize ?? 0;
|
|
741
|
-
for (const stream of conn.streams ?? []) {
|
|
742
|
-
totalChannelBufferSize += stream.writeBufferSize ?? 0;
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
this.gauge("dxos.client.network.swarm.count", swarmCount);
|
|
746
|
-
for (const state in import_network_manager.ConnectionState) {
|
|
747
|
-
this.gauge("dxos.client.network.connection.count", connectionStates.get(state) ?? 0, {
|
|
748
|
-
state
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
this.gauge("dxos.client.network.totalReadBufferSize", totalReadBufferSize);
|
|
752
|
-
this.gauge("dxos.client.network.totalWriteBufferSize", totalWriteBufferSize);
|
|
753
|
-
this.gauge("dxos.client.network.totalChannelBufferSize", totalChannelBufferSize);
|
|
754
|
-
});
|
|
755
|
-
});
|
|
756
|
-
clientServices.NetworkService.queryStatus().subscribe((networkStatus) => {
|
|
757
|
-
this._lastNetworkStatus = networkStatus;
|
|
758
|
-
updateSignalMetrics.emit();
|
|
759
|
-
});
|
|
760
|
-
(0, import_async.scheduleTaskInterval)(this._ctx, async () => updateSignalMetrics.emit(), NETWORK_METRICS_MIN_INTERVAL);
|
|
761
|
-
}
|
|
762
|
-
startSpacesMetrics(client, namespace) {
|
|
763
|
-
const spaces = client.spaces.get();
|
|
764
|
-
const subscriptions = /* @__PURE__ */ new Map();
|
|
765
|
-
this._ctx.onDispose(() => subscriptions.forEach((subscription) => subscription.unsubscribe()));
|
|
766
|
-
const updateSpaceMetrics = new import_async.Event().debounce(SPACE_METRICS_MIN_INTERVAL);
|
|
767
|
-
updateSpaceMetrics.on(this._ctx, async () => {
|
|
768
|
-
(0, import_log.log)("send space metrics", void 0, {
|
|
769
|
-
F: __dxlog_file3,
|
|
770
|
-
L: 414,
|
|
771
|
-
S: this,
|
|
772
|
-
C: (f, a) => f(...a)
|
|
773
|
-
});
|
|
774
|
-
for (const data of mapSpaces(spaces, {
|
|
775
|
-
truncateKeys: true
|
|
776
|
-
})) {
|
|
777
|
-
this.gauge("dxos.client.space.members", data.members, {
|
|
778
|
-
key: data.key
|
|
779
|
-
});
|
|
780
|
-
this.gauge("dxos.client.space.objects", data.objects, {
|
|
781
|
-
key: data.key
|
|
782
|
-
});
|
|
783
|
-
this.gauge("dxos.client.space.epoch", data.epoch, {
|
|
784
|
-
key: data.key
|
|
785
|
-
});
|
|
786
|
-
this.gauge("dxos.client.space.currentDataMutations", data.currentDataMutations, {
|
|
787
|
-
key: data.key
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
});
|
|
791
|
-
const updateSpaceTelemetry = new import_async.Event().debounce(SPACE_TELEMETRY_MIN_INTERVAL);
|
|
792
|
-
updateSpaceTelemetry.on(this._ctx, async () => {
|
|
793
|
-
(0, import_log.log)("send space telemetry", void 0, {
|
|
794
|
-
F: __dxlog_file3,
|
|
795
|
-
L: 425,
|
|
796
|
-
S: this,
|
|
797
|
-
C: (f, a) => f(...a)
|
|
798
|
-
});
|
|
799
|
-
for (const data of mapSpaces(spaces, {
|
|
800
|
-
truncateKeys: true
|
|
801
|
-
})) {
|
|
802
|
-
this.track({
|
|
803
|
-
...getTelemetryIdentity(client),
|
|
804
|
-
event: import_chunk_325GAGFA.TelemetryEvent.METRICS,
|
|
805
|
-
action: "space.update",
|
|
806
|
-
properties: data
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
});
|
|
810
|
-
const subscribeToSpaceUpdate = (space) => space.pipeline.subscribe({
|
|
811
|
-
next: () => {
|
|
812
|
-
updateSpaceMetrics.emit();
|
|
813
|
-
updateSpaceTelemetry.emit();
|
|
814
|
-
}
|
|
815
|
-
});
|
|
816
|
-
spaces.forEach((space) => {
|
|
817
|
-
subscriptions.set(space.id, subscribeToSpaceUpdate(space));
|
|
818
|
-
});
|
|
819
|
-
client.spaces.subscribe({
|
|
820
|
-
next: async (spaces2) => {
|
|
821
|
-
spaces2.filter((space) => !subscriptions.has(space.id)).forEach((space) => {
|
|
822
|
-
subscriptions.set(space.id, subscribeToSpaceUpdate(space));
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
});
|
|
826
|
-
(0, import_async.scheduleTaskInterval)(this._ctx, async () => updateSpaceMetrics.emit(), NETWORK_METRICS_MIN_INTERVAL);
|
|
827
|
-
}
|
|
828
|
-
async startRuntimeMetrics(client, frequency = NETWORK_METRICS_MIN_INTERVAL) {
|
|
829
|
-
const platform = await client.services.services.SystemService?.getPlatform();
|
|
830
|
-
(0, import_invariant.invariant)(platform, "platform is required", {
|
|
831
|
-
F: __dxlog_file3,
|
|
832
|
-
L: 463,
|
|
833
|
-
S: this,
|
|
834
|
-
A: [
|
|
835
|
-
"platform",
|
|
836
|
-
"'platform is required'"
|
|
837
|
-
]
|
|
838
|
-
});
|
|
839
|
-
this.setTag("platformType", import_services.Platform.PLATFORM_TYPE[platform.type].toLowerCase());
|
|
840
|
-
if (this._mode === "full") {
|
|
841
|
-
if (platform.platform) {
|
|
842
|
-
this.setTag("platform", platform.platform);
|
|
843
|
-
}
|
|
844
|
-
if (platform.arch) {
|
|
845
|
-
this.setTag("arch", platform.arch);
|
|
846
|
-
}
|
|
847
|
-
if (platform.runtime) {
|
|
848
|
-
this.setTag("runtime", platform.runtime);
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
(0, import_async.scheduleTaskInterval)(this._ctx, async () => {
|
|
852
|
-
if (client.services.constructor.name === "WorkerClientServices") {
|
|
853
|
-
const memory = window.performance.memory;
|
|
854
|
-
if (memory) {
|
|
855
|
-
this.gauge("dxos.client.runtime.heapTotal", memory.totalJSHeapSize);
|
|
856
|
-
this.gauge("dxos.client.runtime.heapUsed", memory.usedJSHeapSize);
|
|
857
|
-
this.gauge("dxos.client.runtime.heapSizeLimit", memory.jsHeapSizeLimit);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
client.services.services.SystemService?.getPlatform().then((platform2) => {
|
|
861
|
-
if (platform2.memory) {
|
|
862
|
-
this.gauge("dxos.client.services.runtime.rss", platform2.memory.rss);
|
|
863
|
-
this.gauge("dxos.client.services.runtime.heapTotal", platform2.memory.heapTotal);
|
|
864
|
-
this.gauge("dxos.client.services.runtime.heapUsed", platform2.memory.heapUsed);
|
|
865
|
-
}
|
|
866
|
-
}).catch((error) => (0, import_log.log)("platform error", {
|
|
867
|
-
error
|
|
868
|
-
}, {
|
|
869
|
-
F: __dxlog_file3,
|
|
870
|
-
L: 497,
|
|
871
|
-
S: this,
|
|
872
|
-
C: (f, a) => f(...a)
|
|
873
|
-
}));
|
|
874
|
-
}, frequency);
|
|
875
|
-
}
|
|
876
|
-
//
|
|
877
|
-
// Telemetry
|
|
878
|
-
//
|
|
879
|
-
async _initTelemetry() {
|
|
880
|
-
if (this._secrets.TELEMETRY_API_KEY && this._mode !== "disabled" && typeof document !== "undefined") {
|
|
881
|
-
const { SegmentTelemetry } = await import("./segment/index.cjs");
|
|
882
|
-
this._telemetry = new SegmentTelemetry({
|
|
883
|
-
apiKey: this._secrets.TELEMETRY_API_KEY,
|
|
884
|
-
batchSize: this._telemetryBatchSize,
|
|
885
|
-
getTags: () => Object.fromEntries(Array.from(this._tags).filter(([key, value]) => {
|
|
886
|
-
return value.scope === "all" || value.scope === "telemetry";
|
|
887
|
-
}).map(([key, value]) => [
|
|
888
|
-
key,
|
|
889
|
-
value.value
|
|
890
|
-
]))
|
|
891
|
-
});
|
|
892
|
-
} else {
|
|
893
|
-
(0, import_log.log)("segment disabled", void 0, {
|
|
894
|
-
F: __dxlog_file3,
|
|
895
|
-
L: 523,
|
|
896
|
-
S: this,
|
|
897
|
-
C: (f, a) => f(...a)
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
/**
|
|
902
|
-
* Submit telemetry page view.
|
|
903
|
-
* The default implementation uses Segment.
|
|
904
|
-
*/
|
|
905
|
-
page(options) {
|
|
906
|
-
this._telemetry?.page(options);
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Submit telemetry user action.
|
|
910
|
-
* The default implementation uses Segment.
|
|
911
|
-
*/
|
|
912
|
-
track(options) {
|
|
913
|
-
this._telemetry?.track(options);
|
|
914
|
-
}
|
|
915
|
-
//
|
|
916
|
-
// Error Logs
|
|
917
|
-
//
|
|
918
|
-
async _initErrorLogs() {
|
|
919
|
-
if (this._secrets.SENTRY_DESTINATION && this._mode !== "disabled") {
|
|
920
|
-
const { captureException, captureUserFeedback, init, setTag } = await import("./sentry/index.cjs");
|
|
921
|
-
const { SentryLogProcessor } = await import("./sentry-log-processor-CCV4RL7N.cjs");
|
|
922
|
-
this._captureException = captureException;
|
|
923
|
-
this._captureUserFeedback = captureUserFeedback;
|
|
924
|
-
this._setTag = setTag;
|
|
925
|
-
import_log.log.info("Initializing Sentry", {
|
|
926
|
-
dest: this._secrets.SENTRY_DESTINATION,
|
|
927
|
-
options: this._errorReportingOptions
|
|
928
|
-
}, {
|
|
929
|
-
F: __dxlog_file3,
|
|
930
|
-
L: 556,
|
|
931
|
-
S: this,
|
|
932
|
-
C: (f, a) => f(...a)
|
|
933
|
-
});
|
|
934
|
-
this._sentryLogProcessor = new SentryLogProcessor();
|
|
935
|
-
init({
|
|
936
|
-
...this._errorReportingOptions,
|
|
937
|
-
destination: this._secrets.SENTRY_DESTINATION,
|
|
938
|
-
scrubFilenames: this._mode !== "full",
|
|
939
|
-
onError: (event) => this._sentryLogProcessor.addLogBreadcrumbsTo(event)
|
|
940
|
-
});
|
|
941
|
-
this._tags.forEach((v, k) => {
|
|
942
|
-
if (v.scope === "all" || v.scope === "errors") {
|
|
943
|
-
setTag(k, v.value);
|
|
944
|
-
}
|
|
945
|
-
});
|
|
946
|
-
} else {
|
|
947
|
-
(0, import_log.log)("sentry disabled", void 0, {
|
|
948
|
-
F: __dxlog_file3,
|
|
949
|
-
L: 576,
|
|
950
|
-
S: this,
|
|
951
|
-
C: (f, a) => f(...a)
|
|
952
|
-
});
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
startErrorLogs() {
|
|
956
|
-
this._sentryLogProcessor && import_log.log.runtimeConfig.processors.push(this._sentryLogProcessor.logProcessor);
|
|
957
|
-
}
|
|
958
|
-
startTraces() {
|
|
959
|
-
this._otelTraces && this._otelTraces.start();
|
|
960
|
-
}
|
|
961
|
-
// TODO(nf): Refactor init based on providers and their capabilities.
|
|
962
|
-
async _initTraces() {
|
|
963
|
-
if (this._secrets.OTEL_ENDPOINT && this._secrets.OTEL_AUTHORIZATION && this._mode !== "disabled") {
|
|
964
|
-
const { OtelTraces } = await import("./otel-VF5YNCR3.cjs");
|
|
965
|
-
this._otelTraces = new OtelTraces({
|
|
966
|
-
endpoint: this._secrets.OTEL_ENDPOINT,
|
|
967
|
-
authorizationHeader: this._secrets.OTEL_AUTHORIZATION,
|
|
968
|
-
serviceName: this._namespace,
|
|
969
|
-
serviceVersion: this.getTag("release")?.value ?? "0.0.0",
|
|
970
|
-
getTags: () => Object.fromEntries(Array.from(this._tags).filter(([key, value]) => {
|
|
971
|
-
return value.scope === "all" || value.scope === "metrics";
|
|
972
|
-
}).map(([key, value]) => [
|
|
973
|
-
key,
|
|
974
|
-
value.value
|
|
975
|
-
]))
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
/**
|
|
980
|
-
* Manually capture an exception.
|
|
981
|
-
* The default implementation uses Sentry.
|
|
982
|
-
*/
|
|
983
|
-
captureException(err) {
|
|
984
|
-
if (this.enabled) {
|
|
985
|
-
this._captureException?.(err);
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
/**
|
|
989
|
-
* Manually capture user feedback.
|
|
990
|
-
* The default implementation uses Sentry.
|
|
991
|
-
*/
|
|
992
|
-
captureUserFeedback(message) {
|
|
993
|
-
if (!this._secrets.SENTRY_DESTINATION) {
|
|
994
|
-
import_log.log.info("Feedback submitted without Sentry destination", {
|
|
995
|
-
message
|
|
996
|
-
}, {
|
|
997
|
-
F: __dxlog_file3,
|
|
998
|
-
L: 625,
|
|
999
|
-
S: this,
|
|
1000
|
-
C: (f, a) => f(...a)
|
|
1001
|
-
});
|
|
1002
|
-
return;
|
|
1003
|
-
}
|
|
1004
|
-
void this._captureUserFeedback?.(message);
|
|
1005
|
-
}
|
|
1006
|
-
};
|
|
1007
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1008
|
-
0 && (module.exports = {
|
|
1009
|
-
OBSERVABILITY_DISABLED_KEY,
|
|
1010
|
-
OBSERVABILITY_GROUP_KEY,
|
|
1011
|
-
Observability,
|
|
1012
|
-
getObservabilityGroup,
|
|
1013
|
-
getObservabilityState,
|
|
1014
|
-
getTelemetryIdentifier,
|
|
1015
|
-
getTelemetryIdentity,
|
|
1016
|
-
initializeAppObservability,
|
|
1017
|
-
initializeNodeObservability,
|
|
1018
|
-
isObservabilityDisabled,
|
|
1019
|
-
mapSpaces,
|
|
1020
|
-
setupTelemetryListeners,
|
|
1021
|
-
showObservabilityBanner,
|
|
1022
|
-
storeObservabilityDisabled,
|
|
1023
|
-
storeObservabilityGroup
|
|
1024
|
-
});
|
|
1025
|
-
//# sourceMappingURL=chunk-BZHVFSLF.cjs.map
|