@dxos/observability 0.3.11-main.e19f39d → 0.3.11-main.e28df4f
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-ROSK6U3K.mjs +83 -0
- package/dist/lib/browser/chunk-ROSK6U3K.mjs.map +7 -0
- package/dist/lib/browser/chunk-STWCJK52.mjs +748 -0
- package/dist/lib/browser/chunk-STWCJK52.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +28 -553
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/observability-XIDFB6PJ.mjs +10 -0
- package/dist/lib/browser/observability-XIDFB6PJ.mjs.map +7 -0
- package/dist/lib/browser/segment/index.mjs +8 -0
- package/dist/lib/browser/segment/index.mjs.map +7 -0
- package/dist/lib/node/chunk-ARUBPK2W.cjs +170 -0
- package/dist/lib/node/chunk-ARUBPK2W.cjs.map +7 -0
- package/dist/lib/node/chunk-DE7OVD7T.cjs +769 -0
- package/dist/lib/node/chunk-DE7OVD7T.cjs.map +7 -0
- package/dist/lib/node/index.cjs +26 -602
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/observability-YMIQHLME.cjs +32 -0
- package/dist/lib/node/observability-YMIQHLME.cjs.map +7 -0
- package/dist/lib/node/segment/index.cjs +30 -0
- package/dist/lib/node/segment/index.cjs.map +7 -0
- package/dist/types/src/helpers/app-observability.d.ts +19 -0
- package/dist/types/src/helpers/app-observability.d.ts.map +1 -0
- package/dist/types/src/helpers/app-observability.js +195 -0
- package/dist/types/src/helpers/app-observability.js.map +1 -0
- package/dist/types/src/helpers/index.d.ts +4 -0
- package/dist/types/src/helpers/index.d.ts.map +1 -0
- package/dist/types/src/helpers/index.js +23 -0
- package/dist/types/src/helpers/index.js.map +1 -0
- package/dist/types/src/{util.d.ts → helpers/map-spaces.d.ts} +2 -3
- package/dist/types/src/helpers/map-spaces.d.ts.map +1 -0
- package/dist/types/src/{util.js → helpers/map-spaces.js} +1 -2
- package/dist/types/src/helpers/map-spaces.js.map +1 -0
- package/dist/types/src/helpers/setup-telemetry-listeners.d.ts +4 -0
- package/dist/types/src/helpers/setup-telemetry-listeners.d.ts.map +1 -0
- package/dist/types/src/helpers/setup-telemetry-listeners.js +96 -0
- package/dist/types/src/helpers/setup-telemetry-listeners.js.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/index.js +1 -0
- package/dist/types/src/index.js.map +1 -1
- package/dist/types/src/observability.d.ts +3 -4
- package/dist/types/src/observability.d.ts.map +1 -1
- package/dist/types/src/observability.js +26 -25
- package/dist/types/src/observability.js.map +1 -1
- package/package.json +15 -14
- package/src/helpers/app-observability.ts +205 -0
- package/src/helpers/index.ts +7 -0
- package/src/{util.ts → helpers/map-spaces.ts} +1 -2
- package/src/helpers/setup-telemetry-listeners.ts +115 -0
- package/src/index.ts +1 -0
- package/src/observability.ts +26 -24
- package/dist/types/src/util.d.ts.map +0 -1
- package/dist/types/src/util.js.map +0 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import type { Client } from '@dxos/client';
|
|
6
|
+
|
|
7
|
+
import { BASE_TELEMETRY_PROPERTIES, getTelemetryIdentifier } from './app-observability';
|
|
8
|
+
import type { Observability } from '../observability';
|
|
9
|
+
|
|
10
|
+
let lastFocusEvent = new Date();
|
|
11
|
+
let totalTime = 0;
|
|
12
|
+
|
|
13
|
+
export const setupTelemetryListeners = (namespace: string, client: Client, observability: Observability) => {
|
|
14
|
+
const clickCallback = (event: any) => {
|
|
15
|
+
if (BASE_TELEMETRY_PROPERTIES.group === 'dxos' && event.target && !event.target.id) {
|
|
16
|
+
// TODO(wittjosiah): Use @dxos/log so these can be filtered.
|
|
17
|
+
console.warn('Click event on element without id:', event.target);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setTimeout(() =>
|
|
21
|
+
observability.event({
|
|
22
|
+
identityId: getTelemetryIdentifier(client),
|
|
23
|
+
name: `${namespace}.window.click`,
|
|
24
|
+
properties: {
|
|
25
|
+
...BASE_TELEMETRY_PROPERTIES,
|
|
26
|
+
href: window.location.href,
|
|
27
|
+
id: (event.target as HTMLElement)?.id,
|
|
28
|
+
path: (event.path as HTMLElement[])
|
|
29
|
+
?.filter((el) => Boolean(el.tagName))
|
|
30
|
+
.map((el) => `${el.tagName.toLowerCase()}${el.id ? `#${el.id}` : ''}`)
|
|
31
|
+
.reverse()
|
|
32
|
+
.join('>'),
|
|
33
|
+
},
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const focusCallback = () => {
|
|
39
|
+
const now = new Date();
|
|
40
|
+
setTimeout(() =>
|
|
41
|
+
observability.event({
|
|
42
|
+
identityId: getTelemetryIdentifier(client),
|
|
43
|
+
name: `${namespace}.window.focus`,
|
|
44
|
+
properties: {
|
|
45
|
+
...BASE_TELEMETRY_PROPERTIES,
|
|
46
|
+
href: window.location.href,
|
|
47
|
+
timeAway: now.getTime() - lastFocusEvent.getTime(),
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
lastFocusEvent = now;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const blurCallback = () => {
|
|
55
|
+
const now = new Date();
|
|
56
|
+
const timeSpent = now.getTime() - lastFocusEvent.getTime();
|
|
57
|
+
setTimeout(() =>
|
|
58
|
+
observability.event({
|
|
59
|
+
identityId: getTelemetryIdentifier(client),
|
|
60
|
+
name: `${namespace}.window.blur`,
|
|
61
|
+
properties: {
|
|
62
|
+
...BASE_TELEMETRY_PROPERTIES,
|
|
63
|
+
href: window.location.href,
|
|
64
|
+
timeSpent,
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
lastFocusEvent = now;
|
|
69
|
+
totalTime = totalTime + timeSpent;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const unloadCallback = () => {
|
|
73
|
+
setTimeout(() =>
|
|
74
|
+
observability.event({
|
|
75
|
+
identityId: getTelemetryIdentifier(client),
|
|
76
|
+
name: `${namespace}.page.unload`,
|
|
77
|
+
properties: {
|
|
78
|
+
...BASE_TELEMETRY_PROPERTIES,
|
|
79
|
+
href: window.location.href,
|
|
80
|
+
timeSpent: totalTime,
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const errorCallback = (event: ErrorEvent) => {
|
|
87
|
+
setTimeout(() =>
|
|
88
|
+
observability.event({
|
|
89
|
+
identityId: getTelemetryIdentifier(client),
|
|
90
|
+
name: `${namespace}.window.error`,
|
|
91
|
+
properties: {
|
|
92
|
+
...BASE_TELEMETRY_PROPERTIES,
|
|
93
|
+
href: window.location.href,
|
|
94
|
+
message: event.message,
|
|
95
|
+
filename: event.filename,
|
|
96
|
+
stack: (event.error as Error).stack,
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
window.addEventListener('click', clickCallback, true);
|
|
103
|
+
window.addEventListener('focus', focusCallback);
|
|
104
|
+
window.addEventListener('blur', blurCallback);
|
|
105
|
+
window.addEventListener('beforeunload', unloadCallback);
|
|
106
|
+
window.addEventListener('error', errorCallback);
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
window.removeEventListener('click', clickCallback, true);
|
|
110
|
+
window.removeEventListener('focus', focusCallback);
|
|
111
|
+
window.removeEventListener('blur', blurCallback);
|
|
112
|
+
window.removeEventListener('beforeunload', unloadCallback);
|
|
113
|
+
window.removeEventListener('error', errorCallback);
|
|
114
|
+
};
|
|
115
|
+
};
|
package/src/index.ts
CHANGED
package/src/observability.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { isNode } from '@dxos/util';
|
|
|
14
14
|
|
|
15
15
|
import buildSecrets from './cli-observability-secrets.json';
|
|
16
16
|
import { DatadogMetrics } from './datadog';
|
|
17
|
+
import { BASE_TELEMETRY_PROPERTIES, getTelemetryIdentifier, mapSpaces } from './helpers';
|
|
17
18
|
import { SegmentTelemetry, type EventOptions, type PageOptions } from './segment';
|
|
18
19
|
import {
|
|
19
20
|
captureException as sentryCaptureException,
|
|
@@ -23,7 +24,6 @@ import {
|
|
|
23
24
|
type InitOptions,
|
|
24
25
|
setTag as sentrySetTag,
|
|
25
26
|
} from './sentry';
|
|
26
|
-
import { mapSpaces } from './util';
|
|
27
27
|
|
|
28
28
|
const SPACE_METRICS_MIN_INTERVAL = 1000 * 60;
|
|
29
29
|
// const DATADOG_IDLE_INTERVAL = 1000 * 60 * 5;
|
|
@@ -62,8 +62,8 @@ export type ObservabilityOptions = {
|
|
|
62
62
|
|
|
63
63
|
errorLog?: {
|
|
64
64
|
sentryInitOptions?: InitOptions;
|
|
65
|
+
logProcessor?: boolean;
|
|
65
66
|
};
|
|
66
|
-
logProcessor?: boolean;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
/*
|
|
@@ -90,7 +90,7 @@ export class Observability {
|
|
|
90
90
|
private _tags = new Map<string, string>();
|
|
91
91
|
|
|
92
92
|
// TODO(nf): make platform a required extension?
|
|
93
|
-
constructor({ namespace, config, secrets, group, mode, telemetry, errorLog
|
|
93
|
+
constructor({ namespace, config, secrets, group, mode, telemetry, errorLog }: ObservabilityOptions) {
|
|
94
94
|
this._namespace = namespace;
|
|
95
95
|
this._config = config;
|
|
96
96
|
this._mode = mode ?? 'disabled';
|
|
@@ -98,7 +98,7 @@ export class Observability {
|
|
|
98
98
|
this._secrets = this._loadSecrets(config, secrets);
|
|
99
99
|
this._telemetryBatchSize = telemetry?.batchSize ?? 30;
|
|
100
100
|
this._errorReportingOptions = errorLog?.sentryInitOptions;
|
|
101
|
-
this._errorLogProcessor = logProcessor ?? false;
|
|
101
|
+
this._errorLogProcessor = errorLog?.logProcessor ?? false;
|
|
102
102
|
|
|
103
103
|
if (this._group) {
|
|
104
104
|
this.setTag('group', this._group);
|
|
@@ -168,7 +168,7 @@ export class Observability {
|
|
|
168
168
|
this._tags.set(key, value);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
// TODO(
|
|
171
|
+
// TODO(wittjosiah): Improve privacy of telemetry identifiers. See `getTelemetryIdentifier`.
|
|
172
172
|
async setIdentityTags(client: Client) {
|
|
173
173
|
client.services.services.IdentityService!.queryIdentity().subscribe((idqr) => {
|
|
174
174
|
if (!idqr?.identity?.identityKey) {
|
|
@@ -176,16 +176,9 @@ export class Observability {
|
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
// TODO(nf): cardinality
|
|
181
|
-
this.setTag('identityKey', idqr?.identity?.identityKey.truncate());
|
|
182
|
-
if (idqr?.identity?.profile?.displayName) {
|
|
183
|
-
this.setTag('username', idqr?.identity?.profile?.displayName);
|
|
184
|
-
}
|
|
179
|
+
this.setTag('identityKey', idqr.identity.identityKey.truncate());
|
|
185
180
|
});
|
|
186
|
-
}
|
|
187
181
|
|
|
188
|
-
async setDeviceTags(client: Client) {
|
|
189
182
|
client.services.services.DevicesService!.queryDevices().subscribe((dqr) => {
|
|
190
183
|
if (!dqr || !dqr.devices || dqr.devices.length === 0) {
|
|
191
184
|
log('empty response from device service', { device: dqr });
|
|
@@ -283,19 +276,30 @@ export class Observability {
|
|
|
283
276
|
// scheduleTaskInterval(ctx, async () => updateSignalMetrics.emit(), DATADOG_IDLE_INTERVAL);
|
|
284
277
|
}
|
|
285
278
|
|
|
286
|
-
startSpacesMetrics(client: Client) {
|
|
287
|
-
|
|
279
|
+
startSpacesMetrics(client: Client, namespace: string) {
|
|
280
|
+
const spaces = client.spaces.get();
|
|
288
281
|
const subscriptions = new Map<string, { unsubscribe: () => void }>();
|
|
289
282
|
this._ctx.onDispose(() => subscriptions.forEach((subscription) => subscription.unsubscribe()));
|
|
290
283
|
|
|
291
284
|
const updateSpaceMetrics = new Event<Space>().debounce(SPACE_METRICS_MIN_INTERVAL);
|
|
292
|
-
updateSpaceMetrics.on(this._ctx, async (
|
|
285
|
+
updateSpaceMetrics.on(this._ctx, async () => {
|
|
293
286
|
log('send space update');
|
|
294
|
-
for (const
|
|
295
|
-
|
|
296
|
-
this.gauge('dxos.client.space.
|
|
297
|
-
this.gauge('dxos.client.space.
|
|
298
|
-
this.gauge('dxos.client.space.
|
|
287
|
+
for (const data of mapSpaces(spaces, { truncateKeys: true })) {
|
|
288
|
+
// Metrics
|
|
289
|
+
this.gauge('dxos.client.space.members', data.members, { key: data.key });
|
|
290
|
+
this.gauge('dxos.client.space.objects', data.objects, { key: data.key });
|
|
291
|
+
this.gauge('dxos.client.space.epoch', data.epoch, { key: data.key });
|
|
292
|
+
this.gauge('dxos.client.space.currentDataMutations', data.currentDataMutations, { key: data.key });
|
|
293
|
+
|
|
294
|
+
// Telemetry
|
|
295
|
+
this.event({
|
|
296
|
+
identityId: getTelemetryIdentifier(client),
|
|
297
|
+
name: `${namespace}.space.update`,
|
|
298
|
+
properties: {
|
|
299
|
+
...BASE_TELEMETRY_PROPERTIES,
|
|
300
|
+
...data,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
299
303
|
}
|
|
300
304
|
});
|
|
301
305
|
|
|
@@ -311,9 +315,7 @@ export class Observability {
|
|
|
311
315
|
});
|
|
312
316
|
|
|
313
317
|
client.spaces.subscribe({
|
|
314
|
-
next: async () => {
|
|
315
|
-
spaces = client.spaces.get();
|
|
316
|
-
// spaces = await this.getSpaces(this._agent.client);
|
|
318
|
+
next: async (spaces) => {
|
|
317
319
|
spaces
|
|
318
320
|
.filter((space) => !subscriptions.has(space.key.toHex()))
|
|
319
321
|
.forEach((space) => {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,SAAS,WAAY,KAAK,EAAE,YAAW,gBAAgB;;;;;;;;;;;;GAqCnE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;AASK,MAAM,SAAS,GAAG,CAAC,MAAe,EAAE,UAA4B,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;IAChH,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;;QAC1B,4BAA4B;QAC5B,oEAAoE;QACpE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,mCAAI,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAElE,kGAAkG;QAClG,uDAAuD;QACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC9C,MAAM,kBAAkB,GAAG,MAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,YAAY,0CAAE,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,EAAE,mCAAI,CAAC,CAAC;QACpG,MAAM,KAAK,GAAG,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,YAAY,0CAAE,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC;QAC/D,yEAAyE;QACzE,MAAM,oBAAoB,GAAG,MAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,oBAAoB,0CAAE,aAAa,EAAE,mCAAI,CAAC,CAAC;QAClF,MAAM,kBAAkB,GAAG,MAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,mBAAmB,0CAAE,aAAa,EAAE,mCAAI,CAAC,CAAC;QAE/E,OAAO;YACL,kCAAkC;YAClC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;YACzB,IAAI,EAAE,KAAK,CAAC,MAAM;YAClB,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI;YAC3B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM;YACnC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,MAAM;YACxC,OAAO;YACP,KAAK;YACL,gBAAgB;YAChB,kBAAkB;YAClB,oBAAoB;YACpB,kBAAkB;YAElB,0BAA0B;YAC1B,QAAQ,EAAE,CACR,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,oBAAoB,GAAG,kBAAkB,CAAC,GAAG,CAAC,kBAAkB,GAAG,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC9G,GAAG,CACJ,CAAC,OAAO,CAAC,CAAC,CAAC;SACb,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AArCW,QAAA,SAAS,aAqCpB"}
|