@dxos/tracing 0.5.3-main.6f2dfea → 0.5.3-main.77c09ab

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { type MaybePromise } from '@dxos/util';
1
2
  export type InfoOptions = {
2
3
  /**
3
4
  * Value is of enum type and should be converted to string.
@@ -23,16 +24,36 @@ export type SpanOptions = {
23
24
  showInBrowserTimeline?: boolean;
24
25
  };
25
26
  export type AddLinkOptions = {};
27
+ export type TraceDiagnosticParams<T> = {
28
+ /**
29
+ * Unique ID.
30
+ */
31
+ id: string;
32
+ /**
33
+ * Human-readable name.
34
+ * @defaults Defaults to `id`
35
+ */
36
+ name?: string;
37
+ /**
38
+ * Function that will be called to fetch the diagnostic data.
39
+ */
40
+ fetch: () => MaybePromise<T>;
41
+ };
42
+ export interface TraceDiagnostic {
43
+ id: string;
44
+ unregister(): void;
45
+ }
26
46
  export declare const trace: {
47
+ addLink: (parent: any, child: any, opts?: AddLinkOptions) => void;
48
+ diagnostic: <T>(params: TraceDiagnosticParams<T>) => TraceDiagnostic;
49
+ info: (opts?: InfoOptions) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
50
+ mark: (name: string) => void;
51
+ metricsCounter: () => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
27
52
  resource: (options?: {
28
53
  annotation?: symbol;
29
- }) => <T extends new (...args: any[]) => {}>(constructor: T) => {
54
+ }) => <T_1 extends new (...args: any[]) => {}>(constructor: T_1) => {
30
55
  new (...rest: any[]): {};
31
- } & T;
32
- info: (opts?: InfoOptions) => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
33
- mark: (name: string) => void;
56
+ } & T_1;
34
57
  span: ({ showInBrowserTimeline }?: SpanOptions) => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any) => any>) => void;
35
- metricsCounter: () => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => void;
36
- addLink: (parent: any, child: any, opts?: AddLinkOptions) => void;
37
58
  };
38
59
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/api.ts"],"names":[],"mappings":"AA2BA,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAeF,MAAM,MAAM,WAAW,GAAG;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAmCF,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC;AAMhC,eAAO,MAAM,KAAK;yBA7FL;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,8BACP,GAAG,EAAE,KAAG,EAAE;sBAIV,GAAG,EAAE;;kBAoCzB,WAAW,cACT,GAAG,eAAe,MAAM,eAAe,kBAAkB;iBAIhD,MAAM;uCASY,WAAW,cACtC,GAAG,eAAe,MAAM,gDAAgD,GAAG,KAAK,GAAG;mCA2BxD,GAAG,eAAe,MAAM,eAAe,kBAAkB;sBAMtE,GAAG,SAAS,GAAG,SAAQ,cAAc;CAY7D,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/api.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAuB/C,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE3B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAeF,MAAM,MAAM,WAAW,GAAG;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAmCF,MAAM,MAAM,cAAc,GAAG,EAAE,CAAC;AAMhC,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,IAAI,IAAI,CAAC;CACpB;AASD,eAAO,MAAM,KAAK;sBAlCO,GAAG,SAAS,GAAG,SAAQ,cAAc;4BA8B/B,sBAAsB,CAAC,CAAC,KAAG,eAAe;kBA9EhE,WAAW,cACT,GAAG,eAAe,MAAM,eAAe,kBAAkB;iBAIhD,MAAM;mCAqCY,GAAG,eAAe,MAAM,eAAe,kBAAkB;yBAnFlF;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,gCACP,GAAG,EAAE,KAAG,EAAE;sBAIV,GAAG,EAAE;;uCAkDI,WAAW,cACtC,GAAG,eAAe,MAAM,cAAc,wBAAwB,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;CA2E9F,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { type TraceDiagnosticParams, type TraceDiagnostic } from './api';
2
+ export declare const DIAGNOSTICS_TIMEOUT = 10000;
3
+ export type DiagnosticMetadata = {
4
+ id: string;
5
+ instanceId: string;
6
+ instanceTag: string | null;
7
+ name: string;
8
+ };
9
+ export type DiagnosticsRequest = {
10
+ id: string;
11
+ instanceId: string;
12
+ };
13
+ export type DiagnosticsData = {
14
+ id: string;
15
+ instanceId: string;
16
+ data: any;
17
+ error?: string;
18
+ };
19
+ export declare class TraceDiagnosticImpl implements TraceDiagnostic {
20
+ id: string;
21
+ fetch: () => any;
22
+ name: string;
23
+ private readonly _onUnregister;
24
+ constructor(id: string, fetch: () => any, name: string, _onUnregister: () => void);
25
+ unregister(): void;
26
+ }
27
+ export declare class DiagnosticsManager {
28
+ readonly instanceId: string;
29
+ readonly registry: Map<string, TraceDiagnosticImpl>;
30
+ private _instanceTag;
31
+ setInstanceTag(tag: string): void;
32
+ registerDiagnostic(params: TraceDiagnosticParams<any>): TraceDiagnostic;
33
+ list(): DiagnosticMetadata[];
34
+ fetch(request: DiagnosticsRequest): Promise<DiagnosticsData>;
35
+ }
36
+ //# sourceMappingURL=diagnostic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic.d.ts","sourceRoot":"","sources":["../../../src/diagnostic.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,OAAO,CAAC;AAGzE,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAE1C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,qBAAa,mBAAoB,YAAW,eAAe;IAEhD,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,MAAM,GAAG;IAChB,IAAI,EAAE,MAAM;IACnB,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAHvB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GAAG,EAChB,IAAI,EAAE,MAAM,EACF,aAAa,EAAE,MAAM,IAAI;IAG5C,UAAU,IAAI,IAAI;CAGnB;AAED,qBAAa,kBAAkB;IAC7B,QAAQ,CAAC,UAAU,SAAc;IAEjC,QAAQ,CAAC,QAAQ,mCAA0C;IAE3D,OAAO,CAAC,YAAY,CAAuB;IAE3C,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIjC,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,CAAC,GAAG,eAAe;IAUvE,IAAI,IAAI,kBAAkB,EAAE;IAStB,KAAK,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC;CAqBnE"}
@@ -0,0 +1,33 @@
1
+ import { type DiagnosticMetadata, type DiagnosticsData, type DiagnosticsManager, type DiagnosticsRequest } from './diagnostic';
2
+ export type DiagnosticChannelMessage = {
3
+ type: 'DIAGNOSTICS_DISCOVER';
4
+ } | {
5
+ type: 'DIAGNOSTICS_ANNOUNCE';
6
+ diagnostics: DiagnosticMetadata[];
7
+ } | {
8
+ type: 'DIAGNOSTICS_FETCH';
9
+ requestId: string;
10
+ request: DiagnosticsRequest;
11
+ } | {
12
+ type: 'DIAGNOSTICS_RESPONSE';
13
+ requestId: string;
14
+ data: DiagnosticsData;
15
+ };
16
+ export declare class DiagnosticsChannel {
17
+ private readonly _channelName;
18
+ private _ctx;
19
+ private readonly _serveChannel;
20
+ private readonly _clientChannel;
21
+ constructor(_channelName?: string);
22
+ destroy(): void;
23
+ /**
24
+ * In node.js, the channel will keep the process alive.
25
+ * This method allows the process to exit.
26
+ * Noop in the browser.
27
+ */
28
+ unref(): void;
29
+ serve(manager: DiagnosticsManager): void;
30
+ discover(): Promise<DiagnosticMetadata[]>;
31
+ fetch(request: DiagnosticsRequest): Promise<DiagnosticsData>;
32
+ }
33
+ //# sourceMappingURL=diagnostics-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics-channel.d.ts","sourceRoot":"","sources":["../../../src/diagnostics-channel.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AAOtB,MAAM,MAAM,wBAAwB,GAChC;IACE,IAAI,EAAE,sBAAsB,CAAC;CAC9B,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC,GACD;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,kBAAkB,CAAC;CAC7B,GACD;IACE,IAAI,EAAE,sBAAsB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;CACvB,CAAC;AAEN,qBAAa,kBAAkB;IAOjB,OAAO,CAAC,QAAQ,CAAC,YAAY;IANzC,OAAO,CAAC,IAAI,CAAiB;IAG7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;gBAErB,YAAY,GAAE,MAA6B;IAKxE,OAAO;IAMP;;;;OAIG;IACH,KAAK;IAOL,KAAK,CAAC,OAAO,EAAE,kBAAkB;IAgC3B,QAAQ,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAgCzC,KAAK,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC;CA2BnE"}
@@ -3,4 +3,5 @@ export * from './symbols';
3
3
  export * from './trace-processor';
4
4
  export * from './trace-sender';
5
5
  export * from './metrics';
6
+ export * from './diagnostic';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC"}
@@ -3,6 +3,8 @@ import { type LogEntry } from '@dxos/protocols/proto/dxos/client/services';
3
3
  import { type Error as SerializedError } from '@dxos/protocols/proto/dxos/error';
4
4
  import { type Metric, type Resource, type Span } from '@dxos/protocols/proto/dxos/tracing';
5
5
  import type { AddLinkOptions } from './api';
6
+ import { DiagnosticsManager } from './diagnostic';
7
+ import { DiagnosticsChannel } from './diagnostics-channel';
6
8
  import { TraceSender } from './trace-sender';
7
9
  export type Diagnostics = {
8
10
  resources: Record<string, Resource>;
@@ -42,6 +44,8 @@ export type TraceSubscription = {
42
44
  newLogs: LogEntry[];
43
45
  };
44
46
  export declare class TraceProcessor {
47
+ readonly diagnostics: DiagnosticsManager;
48
+ readonly diagnosticsChannel: DiagnosticsChannel;
45
49
  readonly subscriptions: Set<TraceSubscription>;
46
50
  readonly resources: Map<number, ResourceEntry>;
47
51
  readonly resourceInstanceIndex: WeakMap<any, ResourceEntry>;
@@ -49,7 +53,9 @@ export declare class TraceProcessor {
49
53
  readonly spans: Map<number, Span>;
50
54
  readonly spanIdList: number[];
51
55
  readonly logs: LogEntry[];
56
+ private _instanceTag;
52
57
  constructor();
58
+ setInstanceTag(tag: string): void;
53
59
  createTraceSender(): TraceSender;
54
60
  traceSpan(params: TraceSpanParams): TracingSpan;
55
61
  addLink(parent: any, child: any, opts: AddLinkOptions): void;
@@ -1 +1 @@
1
- {"version":3,"file":"trace-processor.d.ts","sourceRoot":"","sources":["../../../src/trace-processor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trace-processor.d.ts","sourceRoot":"","sources":["../../../src/trace-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const createId: () => string;
2
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/util.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,cAA4C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/tracing",
3
- "version": "0.5.3-main.6f2dfea",
3
+ "version": "0.5.3-main.77c09ab",
4
4
  "description": "Async utilities.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,18 +16,18 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@dxos/async": "0.5.3-main.6f2dfea",
20
- "@dxos/codec-protobuf": "0.5.3-main.6f2dfea",
21
- "@dxos/context": "0.5.3-main.6f2dfea",
22
- "@dxos/debug": "0.5.3-main.6f2dfea",
23
- "@dxos/invariant": "0.5.3-main.6f2dfea",
24
- "@dxos/log": "0.5.3-main.6f2dfea",
25
- "@dxos/node-std": "0.5.3-main.6f2dfea",
26
- "@dxos/protocols": "0.5.3-main.6f2dfea",
27
- "@dxos/util": "0.5.3-main.6f2dfea"
19
+ "@dxos/async": "0.5.3-main.77c09ab",
20
+ "@dxos/codec-protobuf": "0.5.3-main.77c09ab",
21
+ "@dxos/context": "0.5.3-main.77c09ab",
22
+ "@dxos/debug": "0.5.3-main.77c09ab",
23
+ "@dxos/invariant": "0.5.3-main.77c09ab",
24
+ "@dxos/log": "0.5.3-main.77c09ab",
25
+ "@dxos/protocols": "0.5.3-main.77c09ab",
26
+ "@dxos/node-std": "0.5.3-main.77c09ab",
27
+ "@dxos/util": "0.5.3-main.77c09ab"
28
28
  },
29
29
  "devDependencies": {
30
- "@dxos/test": "0.5.3-main.6f2dfea"
30
+ "@dxos/test": "0.5.3-main.77c09ab"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public"
package/src/api.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Context } from '@dxos/context';
6
+ import { type MaybePromise } from '@dxos/util';
6
7
 
7
8
  import { getTracingContext } from './symbols';
8
9
  import { TRACE_PROCESSOR } from './trace-processor';
@@ -104,12 +105,42 @@ const addLink = (parent: any, child: any, opts: AddLinkOptions = {}) => {
104
105
  TRACE_PROCESSOR.addLink(parent, child, opts);
105
106
  };
106
107
 
108
+ export type TraceDiagnosticParams<T> = {
109
+ /**
110
+ * Unique ID.
111
+ */
112
+ id: string;
113
+
114
+ /**
115
+ * Human-readable name.
116
+ * @defaults Defaults to `id`
117
+ */
118
+ name?: string;
119
+
120
+ /**
121
+ * Function that will be called to fetch the diagnostic data.
122
+ */
123
+ fetch: () => MaybePromise<T>;
124
+ };
125
+
126
+ export interface TraceDiagnostic {
127
+ id: string;
128
+ unregister(): void;
129
+ }
130
+
131
+ /**
132
+ * Register a diagnostic that could be queried.
133
+ */
134
+ const diagnostic = <T>(params: TraceDiagnosticParams<T>): TraceDiagnostic => {
135
+ return TRACE_PROCESSOR.diagnostics.registerDiagnostic(params);
136
+ };
137
+
107
138
  export const trace = {
108
- resource,
139
+ addLink,
140
+ diagnostic,
109
141
  info,
110
142
  mark,
111
- span,
112
143
  metricsCounter,
113
-
114
- addLink,
144
+ resource,
145
+ span,
115
146
  };
@@ -0,0 +1,96 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { asyncTimeout } from '@dxos/async';
6
+ import { invariant } from '@dxos/invariant';
7
+
8
+ import { type TraceDiagnosticParams, type TraceDiagnostic } from './api';
9
+ import { createId } from './util';
10
+
11
+ export const DIAGNOSTICS_TIMEOUT = 10_000;
12
+
13
+ export type DiagnosticMetadata = {
14
+ id: string;
15
+ instanceId: string;
16
+ instanceTag: string | null;
17
+ name: string;
18
+ };
19
+
20
+ export type DiagnosticsRequest = {
21
+ id: string;
22
+ instanceId: string;
23
+ };
24
+
25
+ export type DiagnosticsData = {
26
+ id: string;
27
+ instanceId: string;
28
+ data: any;
29
+ error?: string;
30
+ };
31
+
32
+ export class TraceDiagnosticImpl implements TraceDiagnostic {
33
+ constructor(
34
+ public id: string,
35
+ public fetch: () => any,
36
+ public name: string,
37
+ private readonly _onUnregister: () => void,
38
+ ) {}
39
+
40
+ unregister(): void {
41
+ this._onUnregister();
42
+ }
43
+ }
44
+
45
+ export class DiagnosticsManager {
46
+ readonly instanceId = createId();
47
+
48
+ readonly registry = new Map<string, TraceDiagnosticImpl>();
49
+
50
+ private _instanceTag: string | null = null;
51
+
52
+ setInstanceTag(tag: string): void {
53
+ this._instanceTag = tag;
54
+ }
55
+
56
+ registerDiagnostic(params: TraceDiagnosticParams<any>): TraceDiagnostic {
57
+ const impl = new TraceDiagnosticImpl(params.id, params.fetch, params.name ?? params.id, () => {
58
+ if (this.registry.get(params.id) === impl) {
59
+ this.registry.delete(params.id);
60
+ }
61
+ });
62
+ this.registry.set(params.id, impl);
63
+ return impl;
64
+ }
65
+
66
+ list(): DiagnosticMetadata[] {
67
+ return Array.from(this.registry.values()).map((diagnostic) => ({
68
+ id: diagnostic.id,
69
+ instanceId: this.instanceId,
70
+ instanceTag: this._instanceTag,
71
+ name: diagnostic.name,
72
+ }));
73
+ }
74
+
75
+ async fetch(request: DiagnosticsRequest): Promise<DiagnosticsData> {
76
+ invariant(request.instanceId === this.instanceId, 'Invalid instance id');
77
+ const { id } = request;
78
+ const diagnostic = this.registry.get(id);
79
+ invariant(diagnostic, 'Diagnostic not found');
80
+ try {
81
+ const data = await asyncTimeout(diagnostic.fetch(), DIAGNOSTICS_TIMEOUT);
82
+ return {
83
+ id,
84
+ instanceId: this.instanceId,
85
+ data,
86
+ };
87
+ } catch (err: any) {
88
+ return {
89
+ id,
90
+ instanceId: this.instanceId,
91
+ data: null,
92
+ error: err.stack,
93
+ };
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,161 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { Trigger, sleep } from '@dxos/async';
6
+ import { Context } from '@dxos/context';
7
+
8
+ import {
9
+ DIAGNOSTICS_TIMEOUT,
10
+ type DiagnosticMetadata,
11
+ type DiagnosticsData,
12
+ type DiagnosticsManager,
13
+ type DiagnosticsRequest,
14
+ } from './diagnostic';
15
+ import { createId } from './util';
16
+
17
+ const DEFAULT_CHANNEL_NAME = 'dxos-diagnostics';
18
+
19
+ const DISCOVER_TIME = 500;
20
+
21
+ export type DiagnosticChannelMessage =
22
+ | {
23
+ type: 'DIAGNOSTICS_DISCOVER';
24
+ }
25
+ | {
26
+ type: 'DIAGNOSTICS_ANNOUNCE';
27
+ diagnostics: DiagnosticMetadata[];
28
+ }
29
+ | {
30
+ type: 'DIAGNOSTICS_FETCH';
31
+ requestId: string;
32
+ request: DiagnosticsRequest;
33
+ }
34
+ | {
35
+ type: 'DIAGNOSTICS_RESPONSE';
36
+ requestId: string;
37
+ data: DiagnosticsData;
38
+ };
39
+
40
+ export class DiagnosticsChannel {
41
+ private _ctx = new Context();
42
+
43
+ // Separate channels becauase the client and server may be in the same process.
44
+ private readonly _serveChannel: BroadcastChannel;
45
+ private readonly _clientChannel: BroadcastChannel;
46
+
47
+ constructor(private readonly _channelName: string = DEFAULT_CHANNEL_NAME) {
48
+ this._serveChannel = new BroadcastChannel(_channelName);
49
+ this._clientChannel = new BroadcastChannel(_channelName);
50
+ }
51
+
52
+ destroy() {
53
+ void this._ctx.dispose();
54
+ this._serveChannel.close();
55
+ this._clientChannel.close();
56
+ }
57
+
58
+ /**
59
+ * In node.js, the channel will keep the process alive.
60
+ * This method allows the process to exit.
61
+ * Noop in the browser.
62
+ */
63
+ unref() {
64
+ if (typeof (this._serveChannel as any).unref === 'function') {
65
+ (this._serveChannel as any).unref();
66
+ (this._clientChannel as any).unref();
67
+ }
68
+ }
69
+
70
+ serve(manager: DiagnosticsManager) {
71
+ const listener = async (event: MessageEvent) => {
72
+ switch (event.data.type) {
73
+ case 'DIAGNOSTICS_DISCOVER': {
74
+ const diagnostics = manager.list();
75
+ this._serveChannel.postMessage({
76
+ type: 'DIAGNOSTICS_ANNOUNCE',
77
+ diagnostics,
78
+ } satisfies DiagnosticChannelMessage);
79
+ break;
80
+ }
81
+ case 'DIAGNOSTICS_FETCH': {
82
+ const { requestId, request } = event.data;
83
+ if (request.instanceId !== manager.instanceId) {
84
+ break;
85
+ }
86
+
87
+ const data = await manager.fetch(request);
88
+ this._serveChannel.postMessage({
89
+ type: 'DIAGNOSTICS_RESPONSE',
90
+ requestId,
91
+ data,
92
+ } satisfies DiagnosticChannelMessage);
93
+ break;
94
+ }
95
+ }
96
+ };
97
+
98
+ this._serveChannel.addEventListener('message', listener);
99
+ this._ctx.onDispose(() => this._serveChannel.removeEventListener('message', listener));
100
+ }
101
+
102
+ async discover(): Promise<DiagnosticMetadata[]> {
103
+ const diagnostics: DiagnosticMetadata[] = [];
104
+
105
+ const collector = (event: MessageEvent) => {
106
+ const data = event.data as DiagnosticChannelMessage;
107
+ switch (data.type) {
108
+ case 'DIAGNOSTICS_ANNOUNCE':
109
+ diagnostics.push(...data.diagnostics);
110
+ break;
111
+ }
112
+ };
113
+
114
+ try {
115
+ this._clientChannel.addEventListener('message', collector);
116
+ this._clientChannel.postMessage({ type: 'DIAGNOSTICS_DISCOVER' } satisfies DiagnosticChannelMessage);
117
+
118
+ await sleep(DISCOVER_TIME);
119
+
120
+ // Dedup.
121
+ const result: DiagnosticMetadata[] = [];
122
+ for (const diagnostic of diagnostics) {
123
+ if (!result.some((d) => d.id === diagnostic.id && d.instanceId === diagnostic.instanceId)) {
124
+ result.push(diagnostic);
125
+ }
126
+ }
127
+
128
+ return diagnostics;
129
+ } finally {
130
+ this._clientChannel.removeEventListener('message', collector);
131
+ }
132
+ }
133
+
134
+ async fetch(request: DiagnosticsRequest): Promise<DiagnosticsData> {
135
+ const requestId = createId();
136
+
137
+ const trigger = new Trigger<DiagnosticsData>();
138
+ const listener = (event: MessageEvent) => {
139
+ const data = event.data as DiagnosticChannelMessage;
140
+ if (data.type === 'DIAGNOSTICS_RESPONSE' && data.requestId === requestId) {
141
+ trigger.wake(data.data);
142
+ }
143
+ };
144
+
145
+ try {
146
+ this._clientChannel.addEventListener('message', listener);
147
+ this._clientChannel.postMessage({
148
+ type: 'DIAGNOSTICS_FETCH',
149
+ requestId,
150
+ request,
151
+ } satisfies DiagnosticChannelMessage);
152
+
153
+ // NOTE: Must have await keyword in this block.
154
+ const result = await trigger.wait({ timeout: DIAGNOSTICS_TIMEOUT });
155
+
156
+ return result;
157
+ } finally {
158
+ this._clientChannel.removeEventListener('message', listener);
159
+ }
160
+ }
161
+ }
package/src/index.ts CHANGED
@@ -2,8 +2,24 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { trace } from './api';
6
+
5
7
  export * from './api';
6
8
  export * from './symbols';
7
9
  export * from './trace-processor';
8
10
  export * from './trace-sender';
9
11
  export * from './metrics';
12
+ export * from './diagnostic';
13
+
14
+ trace.diagnostic({
15
+ id: 'process-info',
16
+ name: 'Process Info',
17
+ fetch: async () => {
18
+ return {
19
+ platform: globalThis.process?.platform,
20
+ arch: globalThis.process?.arch,
21
+ versions: globalThis.process?.versions,
22
+ href: globalThis.location?.href,
23
+ };
24
+ },
25
+ });
@@ -11,6 +11,8 @@ import { type Metric, type Resource, type Span } from '@dxos/protocols/proto/dxo
11
11
  import { getPrototypeSpecificInstanceId } from '@dxos/util';
12
12
 
13
13
  import type { AddLinkOptions } from './api';
14
+ import { DiagnosticsManager } from './diagnostic';
15
+ import { DiagnosticsChannel } from './diagnostics-channel';
14
16
  import { type BaseCounter } from './metrics';
15
17
  import { TRACE_SPAN_ATTRIBUTE, getTracingContext } from './symbols';
16
18
  import { TraceSender } from './trace-sender';
@@ -72,6 +74,9 @@ const REFRESH_INTERVAL = 1_000;
72
74
  const MAX_INFO_OBJECT_DEPTH = 8;
73
75
 
74
76
  export class TraceProcessor {
77
+ public readonly diagnostics = new DiagnosticsManager();
78
+ public readonly diagnosticsChannel = new DiagnosticsChannel();
79
+
75
80
  readonly subscriptions: Set<TraceSubscription> = new Set();
76
81
 
77
82
  readonly resources = new Map<number, ResourceEntry>();
@@ -83,11 +88,21 @@ export class TraceProcessor {
83
88
 
84
89
  readonly logs: LogEntry[] = [];
85
90
 
91
+ private _instanceTag: string | null = null;
92
+
86
93
  constructor() {
87
94
  log.addProcessor(this._logProcessor.bind(this));
88
95
 
89
96
  const refreshInterval = setInterval(this.refresh.bind(this), REFRESH_INTERVAL);
90
97
  unrefTimeout(refreshInterval);
98
+
99
+ this.diagnosticsChannel.serve(this.diagnostics);
100
+ this.diagnosticsChannel.unref();
101
+ }
102
+
103
+ setInstanceTag(tag: string) {
104
+ this._instanceTag = tag;
105
+ this.diagnostics.setInstanceTag(tag);
91
106
  }
92
107
 
93
108
  /**
package/src/util.ts ADDED
@@ -0,0 +1,6 @@
1
+ // TODO(dmaretskyi): Use UUID.
2
+ //
3
+ // Copyright 2024 DXOS.org
4
+ //
5
+
6
+ export const createId = () => Math.random().toString(36).slice(2);