@dxos/tracing 0.1.56-next.a63ce79 → 0.1.56

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 (36) hide show
  1. package/dist/lib/browser/index.mjs +292 -20
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +296 -20
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/api.d.ts +1 -0
  8. package/dist/types/src/api.d.ts.map +1 -1
  9. package/dist/types/src/index.d.ts +1 -0
  10. package/dist/types/src/index.d.ts.map +1 -1
  11. package/dist/types/src/metrics/base.d.ts +7 -0
  12. package/dist/types/src/metrics/base.d.ts.map +1 -0
  13. package/dist/types/src/metrics/index.d.ts +5 -0
  14. package/dist/types/src/metrics/index.d.ts.map +1 -0
  15. package/dist/types/src/metrics/time-series-counter.d.ts +15 -0
  16. package/dist/types/src/metrics/time-series-counter.d.ts.map +1 -0
  17. package/dist/types/src/metrics/time-usage-counter.d.ts +15 -0
  18. package/dist/types/src/metrics/time-usage-counter.d.ts.map +1 -0
  19. package/dist/types/src/metrics/unary-counter.d.ts +12 -0
  20. package/dist/types/src/metrics/unary-counter.d.ts.map +1 -0
  21. package/dist/types/src/symbols.d.ts +1 -0
  22. package/dist/types/src/symbols.d.ts.map +1 -1
  23. package/dist/types/src/trace-processor.d.ts +10 -1
  24. package/dist/types/src/trace-processor.d.ts.map +1 -1
  25. package/dist/types/src/trace-sender.d.ts.map +1 -1
  26. package/package.json +10 -9
  27. package/src/api.ts +14 -0
  28. package/src/index.ts +1 -0
  29. package/src/metrics/base.ts +26 -0
  30. package/src/metrics/index.ts +8 -0
  31. package/src/metrics/time-series-counter.ts +52 -0
  32. package/src/metrics/time-usage-counter.ts +62 -0
  33. package/src/metrics/unary-counter.ts +31 -0
  34. package/src/symbols.ts +4 -2
  35. package/src/trace-processor.ts +158 -2
  36. package/src/trace-sender.ts +28 -18
@@ -0,0 +1,5 @@
1
+ export * from './base';
2
+ export * from './unary-counter';
3
+ export * from './time-series-counter';
4
+ export * from './time-usage-counter';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/metrics/index.ts"],"names":[],"mappings":"AAIA,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
2
+ import { BaseCounter } from './base';
3
+ export declare class TimeSeriesCounter extends BaseCounter {
4
+ private _currentValue;
5
+ private _totalValue;
6
+ private _buckets;
7
+ units?: string;
8
+ constructor({ units }?: {
9
+ units?: string;
10
+ });
11
+ inc(by?: number): void;
12
+ _tick(time: number): void;
13
+ getData(): Metric;
14
+ }
15
+ //# sourceMappingURL=time-series-counter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-series-counter.d.ts","sourceRoot":"","sources":["../../../../src/metrics/time-series-counter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAIrC,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAgB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEH,EAAE,KAAK,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAK9C,GAAG,CAAC,EAAE,SAAI;IAKD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQzB,OAAO,IAAI,MAAM;CAiB3B"}
@@ -0,0 +1,15 @@
1
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
2
+ import { BaseCounter } from './base';
3
+ export declare class TimeUsageCounter extends BaseCounter {
4
+ private _currentValue;
5
+ private _totalValue;
6
+ private _buckets;
7
+ private _lastTickTime;
8
+ record(time: number): void;
9
+ beginRecording(): {
10
+ end: () => void;
11
+ };
12
+ _tick(time: number): void;
13
+ getData(): Metric;
14
+ }
15
+ //# sourceMappingURL=time-usage-counter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-usage-counter.d.ts","sourceRoot":"","sources":["../../../../src/metrics/time-usage-counter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAIrC,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAgB;IAEhC,OAAO,CAAC,aAAa,CAAqB;IAE1C,MAAM,CAAC,IAAI,EAAE,MAAM;IAKnB,cAAc,IAAI;QAAE,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE;IAU5B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAYzB,OAAO,IAAI,MAAM;CAiB3B"}
@@ -0,0 +1,12 @@
1
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
2
+ import { BaseCounter } from './base';
3
+ export declare class UnaryCounter extends BaseCounter {
4
+ value: number;
5
+ units?: string;
6
+ constructor({ units }?: {
7
+ units?: string;
8
+ });
9
+ inc(by?: number): void;
10
+ getData(): Metric;
11
+ }
12
+ //# sourceMappingURL=unary-counter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unary-counter.d.ts","sourceRoot":"","sources":["../../../../src/metrics/unary-counter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,qBAAa,YAAa,SAAQ,WAAW;IAC3C,KAAK,SAAK;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEH,EAAE,KAAK,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO;IAK9C,GAAG,CAAC,EAAE,SAAI;IAIV,OAAO,IAAI,MAAM;CASlB"}
@@ -1,6 +1,7 @@
1
1
  export declare const symbolTracingContext: unique symbol;
2
2
  export type TracingContext = {
3
3
  infoProperties: Record<string, {}>;
4
+ metricsProperties: Record<string, {}>;
4
5
  };
5
6
  export declare const getTracingContext: (target: any) => TracingContext;
6
7
  export declare const TRACE_SPAN_ATTRIBUTE = "dxos.trace-span";
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../../../src/symbols.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,GAAG,KAAG,cAI/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,oBAAoB,CAAC"}
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../../../src/symbols.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;CACvC,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAY,GAAG,KAAG,cAK/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,oBAAoB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { Context } from '@dxos/context';
2
+ import { LogEntry } from '@dxos/protocols/proto/dxos/client/services';
2
3
  import { Error as SerializedError } from '@dxos/protocols/proto/dxos/error';
3
- import { Resource, Span } from '@dxos/protocols/proto/dxos/tracing';
4
+ import { Metric, Resource, Span } from '@dxos/protocols/proto/dxos/tracing';
4
5
  import type { AddLinkOptions } from './api';
5
6
  import { TraceSender } from './trace-sender';
6
7
  export type TraceResourceConstructorParams = {
@@ -19,8 +20,10 @@ export type ResourceEntry = {
19
20
  instance: WeakRef<any>;
20
21
  };
21
22
  export type TraceSubscription = {
23
+ flush: () => void;
22
24
  dirtyResources: Set<number>;
23
25
  dirtySpans: Set<number>;
26
+ newLogs: LogEntry[];
24
27
  };
25
28
  export declare class TraceProcessor {
26
29
  resources: Map<number, ResourceEntry>;
@@ -28,17 +31,23 @@ export declare class TraceProcessor {
28
31
  resourceIdList: number[];
29
32
  spans: Map<number, Span>;
30
33
  spanIdList: number[];
34
+ logs: LogEntry[];
31
35
  subscriptions: Set<TraceSubscription>;
36
+ constructor();
32
37
  traceResourceConstructor(params: TraceResourceConstructorParams): void;
33
38
  getResourceInfo(instance: any): Record<string, any>;
39
+ getResourceMetrics(instance: any): Metric[];
34
40
  traceSpan(params: TraceSpanParams): TracingSpan;
35
41
  addLink(parent: any, child: any, opts: AddLinkOptions): void;
36
42
  getResourceId(instance: any): number | null;
37
43
  createTraceSender(): TraceSender;
44
+ refresh(): void;
38
45
  private _markResourceDirty;
39
46
  private _markSpanDirty;
40
47
  private _clearResources;
41
48
  private _clearSpans;
49
+ private _pushLog;
50
+ private _logProcessor;
42
51
  }
43
52
  export declare class TracingSpan {
44
53
  private _traceProcessor;
@@ -1 +1 @@
1
- {"version":3,"file":"trace-processor.d.ts","sourceRoot":"","sources":["../../../src/trace-processor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,IAAI,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,MAAM,8BAA8B,GAAG;IAC3C,WAAW,EAAE;QAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC;IAC1C,QAAQ,EAAE,GAAG,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,GAAG,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB,CAAC;AAKF,qBAAa,cAAc;IACzB,SAAS,6BAAoC;IAC7C,qBAAqB,8BAAqC;IAC1D,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,KAAK,oBAA2B;IAChC,UAAU,EAAE,MAAM,EAAE,CAAM;IAE1B,aAAa,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAa;IAElD,wBAAwB,CAAC,MAAM,EAAE,8BAA8B;IAqB/D,eAAe,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAenD,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW;IAM/C,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc;IAErD,aAAa,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI;IAK3C,iBAAiB;IAiBjB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,WAAW;CAMpB;AAED,qBAAa,WAAW;IAaV,OAAO,CAAC,eAAe;IAZnC,MAAM,CAAC,MAAM,SAAK;IAElB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5B,KAAK,EAAE,eAAe,GAAG,IAAI,CAAQ;IAErC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;gBAEzB,eAAe,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe;IAmB5E,IAAI,GAAG,IAAI,OAAO,GAAG,IAAI,CAExB;IAED,WAAW;IAKX,SAAS,CAAC,GAAG,EAAE,OAAO;IAMtB,SAAS,IAAI,IAAI;CAWlB;AAeD,eAAO,MAAM,eAAe,EAAE,cAA+E,CAAC"}
1
+ {"version":3,"file":"trace-processor.d.ts","sourceRoot":"","sources":["../../../src/trace-processor.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"trace-sender.d.ts","sourceRoot":"","sources":["../../../src/trace-sender.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AAItE,qBAAa,WAAY,YAAW,cAAc;IACpC,OAAO,CAAC,eAAe;gBAAf,eAAe,EAAE,cAAc;IAEnD,WAAW,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,CAAC,gBAAgB,CAAC;CA+DrD"}
1
+ {"version":3,"file":"trace-sender.d.ts","sourceRoot":"","sources":["../../../src/trace-sender.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AAEtE,qBAAa,WAAY,YAAW,cAAc;IACpC,OAAO,CAAC,eAAe;gBAAf,eAAe,EAAE,cAAc;IAEnD,WAAW,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,CAAC,gBAAgB,CAAC;CA0ErD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/tracing",
3
- "version": "0.1.56-next.a63ce79",
3
+ "version": "0.1.56",
4
4
  "description": "Async utilities.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,14 +16,15 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@dxos/codec-protobuf": "0.1.56-next.a63ce79",
20
- "@dxos/context": "0.1.56-next.a63ce79",
21
- "@dxos/debug": "0.1.56-next.a63ce79",
22
- "@dxos/invariant": "0.1.56-next.a63ce79",
23
- "@dxos/log": "0.1.56-next.a63ce79",
24
- "@dxos/node-std": "0.1.56-next.a63ce79",
25
- "@dxos/protocols": "0.1.56-next.a63ce79",
26
- "@dxos/util": "0.1.56-next.a63ce79"
19
+ "@dxos/async": "0.1.56",
20
+ "@dxos/codec-protobuf": "0.1.56",
21
+ "@dxos/context": "0.1.56",
22
+ "@dxos/debug": "0.1.56",
23
+ "@dxos/invariant": "0.1.56",
24
+ "@dxos/log": "0.1.56",
25
+ "@dxos/node-std": "0.1.56",
26
+ "@dxos/protocols": "0.1.56",
27
+ "@dxos/util": "0.1.56"
27
28
  },
28
29
  "devDependencies": {},
29
30
  "publishConfig": {
package/src/api.ts CHANGED
@@ -7,6 +7,9 @@ import { Context } from '@dxos/context';
7
7
  import { getTracingContext } from './symbols';
8
8
  import { TRACE_PROCESSOR } from './trace-processor';
9
9
 
10
+ /**
11
+ * Annotates a class as a tracked resource.
12
+ */
10
13
  const resource =
11
14
  () =>
12
15
  <T extends { new (...args: any[]): {} }>(constructor: T) => {
@@ -20,6 +23,9 @@ const resource =
20
23
  return klass;
21
24
  };
22
25
 
26
+ /**
27
+ * Marks a property or a method to be included in the resource info section.
28
+ */
23
29
  const info = () => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => {
24
30
  getTracingContext(target).infoProperties[propertyKey] = {};
25
31
  };
@@ -43,6 +49,13 @@ const span = () => (target: any, propertyKey: string, descriptor: TypedPropertyD
43
49
  };
44
50
  };
45
51
 
52
+ /**
53
+ * Attaches metrics counter to the resource.
54
+ */
55
+ const metricsCounter = () => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => {
56
+ getTracingContext(target).metricsProperties[propertyKey] = {};
57
+ };
58
+
46
59
  export type AddLinkOptions = {};
47
60
 
48
61
  const addLink = (parent: any, child: any, opts: AddLinkOptions = {}) => {
@@ -53,6 +66,7 @@ export const trace = {
53
66
  resource,
54
67
  info,
55
68
  span,
69
+ metricsCounter,
56
70
 
57
71
  addLink,
58
72
  };
package/src/index.ts CHANGED
@@ -6,3 +6,4 @@ export * from './api';
6
6
  export * from './symbols';
7
7
  export * from './trace-processor';
8
8
  export * from './trace-sender';
9
+ export * from './metrics';
@@ -0,0 +1,26 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
6
+
7
+ export abstract class BaseCounter {
8
+ /**
9
+ * @internal
10
+ */
11
+ _instance: any;
12
+
13
+ name?: string;
14
+
15
+ /**
16
+ * @internal
17
+ */
18
+ _assign(instance: any, name: string) {
19
+ this._instance = instance;
20
+ this.name = name;
21
+ }
22
+
23
+ abstract getData(): Metric;
24
+
25
+ _tick(time: number): void {}
26
+ }
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export * from './base';
6
+ export * from './unary-counter';
7
+ export * from './time-series-counter';
8
+ export * from './time-usage-counter';
@@ -0,0 +1,52 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
6
+
7
+ import { BaseCounter } from './base';
8
+
9
+ const MAX_BUCKETS = 60;
10
+
11
+ export class TimeSeriesCounter extends BaseCounter {
12
+ private _currentValue = 0;
13
+ private _totalValue = 0;
14
+ private _buckets: number[] = [];
15
+ units?: string;
16
+
17
+ constructor({ units }: { units?: string } = {}) {
18
+ super();
19
+ this.units = units;
20
+ }
21
+
22
+ inc(by = 1) {
23
+ this._currentValue += by;
24
+ this._totalValue += by;
25
+ }
26
+
27
+ override _tick(time: number): void {
28
+ this._buckets.push(this._currentValue);
29
+ if (this._buckets.length > MAX_BUCKETS) {
30
+ this._buckets.shift();
31
+ }
32
+ this._currentValue = 0;
33
+ }
34
+
35
+ override getData(): Metric {
36
+ return {
37
+ name: this.name!,
38
+ timeSeries: {
39
+ tracks: [
40
+ {
41
+ name: this.name!,
42
+ units: this.units,
43
+ points: this._buckets.map((value, index) => ({
44
+ value,
45
+ })),
46
+ total: this._totalValue,
47
+ },
48
+ ],
49
+ },
50
+ };
51
+ }
52
+ }
@@ -0,0 +1,62 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
6
+
7
+ import { BaseCounter } from './base';
8
+
9
+ const MAX_BUCKETS = 60;
10
+
11
+ export class TimeUsageCounter extends BaseCounter {
12
+ private _currentValue = 0;
13
+ private _totalValue = 0;
14
+ private _buckets: number[] = [];
15
+
16
+ private _lastTickTime = performance.now();
17
+
18
+ record(time: number) {
19
+ this._currentValue += time;
20
+ this._totalValue += time;
21
+ }
22
+
23
+ beginRecording(): { end: () => void } {
24
+ const start = performance.now();
25
+ return {
26
+ end: () => {
27
+ const end = performance.now();
28
+ this.record(end - start);
29
+ },
30
+ };
31
+ }
32
+
33
+ override _tick(time: number): void {
34
+ const delta = time - this._lastTickTime;
35
+ this._lastTickTime = time;
36
+
37
+ const percentage = (this._currentValue / delta) * 100;
38
+ this._buckets.push(percentage);
39
+ if (this._buckets.length > MAX_BUCKETS) {
40
+ this._buckets.shift();
41
+ }
42
+ this._currentValue = 0;
43
+ }
44
+
45
+ override getData(): Metric {
46
+ return {
47
+ name: this.name!,
48
+ timeSeries: {
49
+ tracks: [
50
+ {
51
+ name: this.name!,
52
+ units: '%',
53
+ points: this._buckets.map((value, index) => ({
54
+ value,
55
+ })),
56
+ total: this._totalValue,
57
+ },
58
+ ],
59
+ },
60
+ };
61
+ }
62
+ }
@@ -0,0 +1,31 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { Metric } from '@dxos/protocols/proto/dxos/tracing';
6
+
7
+ import { BaseCounter } from './base';
8
+
9
+ export class UnaryCounter extends BaseCounter {
10
+ value = 0;
11
+ units?: string;
12
+
13
+ constructor({ units }: { units?: string } = {}) {
14
+ super();
15
+ this.units = units;
16
+ }
17
+
18
+ inc(by = 1) {
19
+ this.value += by;
20
+ }
21
+
22
+ getData(): Metric {
23
+ return {
24
+ name: this.name!,
25
+ counter: {
26
+ value: this.value,
27
+ units: this.units,
28
+ },
29
+ };
30
+ }
31
+ }
package/src/symbols.ts CHANGED
@@ -2,15 +2,17 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export const symbolTracingContext = Symbol('dxos.tracing-context');
5
+ export const symbolTracingContext = Symbol('dxos.tracing.context');
6
6
 
7
7
  export type TracingContext = {
8
8
  infoProperties: Record<string, {}>;
9
+ metricsProperties: Record<string, {}>;
9
10
  };
10
11
 
11
12
  export const getTracingContext = (target: any): TracingContext => {
12
- return (target[symbolTracingContext] ??= {
13
+ return ((target[symbolTracingContext] as TracingContext | undefined) ??= {
13
14
  infoProperties: {},
15
+ metricsProperties: {},
14
16
  });
15
17
  };
16
18
 
@@ -2,12 +2,16 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { unrefTimeout } from '@dxos/async';
5
6
  import { Context } from '@dxos/context';
7
+ import { LogLevel, LogProcessor, getContextFromEntry, log } from '@dxos/log';
8
+ import { LogEntry } from '@dxos/protocols/proto/dxos/client/services';
6
9
  import { Error as SerializedError } from '@dxos/protocols/proto/dxos/error';
7
- import { Resource, Span } from '@dxos/protocols/proto/dxos/tracing';
10
+ import { Metric, Resource, Span } from '@dxos/protocols/proto/dxos/tracing';
8
11
  import { getPrototypeSpecificInstanceId } from '@dxos/util';
9
12
 
10
13
  import type { AddLinkOptions } from './api';
14
+ import { BaseCounter } from './metrics';
11
15
  import { TRACE_SPAN_ATTRIBUTE, getTracingContext } from './symbols';
12
16
  import { TraceSender } from './trace-sender';
13
17
 
@@ -28,12 +32,18 @@ export type ResourceEntry = {
28
32
  };
29
33
 
30
34
  export type TraceSubscription = {
35
+ flush: () => void;
36
+
31
37
  dirtyResources: Set<number>;
32
38
  dirtySpans: Set<number>;
39
+ newLogs: LogEntry[];
33
40
  };
34
41
 
35
42
  const MAX_RESOURCE_RECORDS = 500;
36
43
  const MAX_SPAN_RECORDS = 1_000;
44
+ const MAX_LOG_RECORDS = 1_000;
45
+
46
+ const REFRESH_INTERVAL = 1_000;
37
47
 
38
48
  export class TraceProcessor {
39
49
  resources = new Map<number, ResourceEntry>();
@@ -43,10 +53,26 @@ export class TraceProcessor {
43
53
  spans = new Map<number, Span>();
44
54
  spanIdList: number[] = [];
45
55
 
56
+ logs: LogEntry[] = [];
57
+
46
58
  subscriptions: Set<TraceSubscription> = new Set();
47
59
 
60
+ constructor() {
61
+ log.addProcessor(this._logProcessor.bind(this));
62
+
63
+ const refreshInterval = setInterval(this.refresh.bind(this), REFRESH_INTERVAL);
64
+ unrefTimeout(refreshInterval);
65
+ }
66
+
48
67
  traceResourceConstructor(params: TraceResourceConstructorParams) {
49
68
  const id = this.resources.size;
69
+
70
+ // init metrics counters.
71
+ const tracingContext = getTracingContext(Object.getPrototypeOf(params.instance));
72
+ for (const key of Object.keys(tracingContext.metricsProperties)) {
73
+ (params.instance[key] as BaseCounter)._assign(params.instance, key);
74
+ }
75
+
50
76
  const entry: ResourceEntry = {
51
77
  data: {
52
78
  id,
@@ -54,6 +80,7 @@ export class TraceProcessor {
54
80
  instanceId: getPrototypeSpecificInstanceId(params.instance),
55
81
  info: this.getResourceInfo(params.instance),
56
82
  links: [],
83
+ metrics: this.getResourceMetrics(params.instance),
57
84
  },
58
85
  instance: new WeakRef(params.instance),
59
86
  };
@@ -72,7 +99,7 @@ export class TraceProcessor {
72
99
 
73
100
  for (const [key, _opts] of Object.entries(tracingContext.infoProperties)) {
74
101
  try {
75
- res[key] = typeof instance[key] === 'function' ? instance[key]() : instance[key];
102
+ res[key] = sanitizeValue(typeof instance[key] === 'function' ? instance[key]() : instance[key]);
76
103
  } catch (err: any) {
77
104
  res[key] = err.message;
78
105
  }
@@ -81,6 +108,17 @@ export class TraceProcessor {
81
108
  return res;
82
109
  }
83
110
 
111
+ getResourceMetrics(instance: any): Metric[] {
112
+ const res: Metric[] = [];
113
+ const tracingContext = getTracingContext(Object.getPrototypeOf(instance));
114
+
115
+ for (const [key, _opts] of Object.entries(tracingContext.metricsProperties)) {
116
+ res.push(instance[key].getData());
117
+ }
118
+
119
+ return res;
120
+ }
121
+
84
122
  traceSpan(params: TraceSpanParams): TracingSpan {
85
123
  const span = new TracingSpan(this, params);
86
124
  this._flushSpan(span);
@@ -98,6 +136,40 @@ export class TraceProcessor {
98
136
  return new TraceSender(this);
99
137
  }
100
138
 
139
+ refresh() {
140
+ for (const resource of this.resources.values()) {
141
+ const instance = resource.instance.deref();
142
+ if (!instance) {
143
+ continue;
144
+ }
145
+
146
+ const tracingContext = getTracingContext(Object.getPrototypeOf(instance));
147
+ const time = performance.now();
148
+ for (const key of Object.keys(tracingContext.metricsProperties)) {
149
+ (instance[key] as BaseCounter)._tick?.(time);
150
+ }
151
+
152
+ let _changed = false;
153
+
154
+ const oldInfo = resource.data.info;
155
+ resource.data.info = this.getResourceInfo(instance);
156
+ _changed ||= !areEqualShallow(oldInfo, resource.data.info);
157
+
158
+ const oldMetrics = resource.data.metrics;
159
+ resource.data.metrics = this.getResourceMetrics(instance);
160
+ _changed ||= !areEqualShallow(oldMetrics, resource.data.metrics);
161
+
162
+ // TODO(dmaretskyi): Test if works and enable.
163
+ // if (changed) {
164
+ this._markResourceDirty(resource.data.id);
165
+ // }
166
+ }
167
+
168
+ for (const subscription of this.subscriptions) {
169
+ subscription.flush();
170
+ }
171
+ }
172
+
101
173
  /**
102
174
  * @internal
103
175
  */
@@ -137,6 +209,52 @@ export class TraceProcessor {
137
209
  this.spans.delete(id);
138
210
  }
139
211
  }
212
+
213
+ private _pushLog(log: LogEntry) {
214
+ this.logs.push(log);
215
+ if (this.logs.length > MAX_LOG_RECORDS) {
216
+ this.logs.shift();
217
+ }
218
+
219
+ for (const subscription of this.subscriptions) {
220
+ subscription.newLogs.push(log);
221
+ }
222
+ }
223
+
224
+ private _logProcessor: LogProcessor = (config, entry) => {
225
+ switch (entry.level) {
226
+ case LogLevel.ERROR:
227
+ case LogLevel.WARN:
228
+ case LogLevel.TRACE: {
229
+ const scope = entry.meta?.S;
230
+ const resource = this.resourceInstanceIndex.get(scope);
231
+ if (!resource) {
232
+ return;
233
+ }
234
+
235
+ const context = getContextFromEntry(entry) ?? {};
236
+
237
+ for (const key of Object.keys(context)) {
238
+ context[key] = sanitizeValue(context[key]);
239
+ }
240
+
241
+ const entryToPush: LogEntry = {
242
+ level: entry.level,
243
+ message: entry.message,
244
+ context,
245
+ timestamp: new Date(),
246
+ meta: {
247
+ file: entry.meta?.F ?? '',
248
+ line: entry.meta?.L ?? 0,
249
+ resourceId: resource.data.id,
250
+ },
251
+ };
252
+ this._pushLog(entryToPush);
253
+ break;
254
+ }
255
+ default:
256
+ }
257
+ };
140
258
  }
141
259
 
142
260
  export class TracingSpan {
@@ -213,3 +331,41 @@ const serializeError = (err: unknown): SerializedError => {
213
331
  };
214
332
 
215
333
  export const TRACE_PROCESSOR: TraceProcessor = ((globalThis as any).TRACE_PROCESSOR ??= new TraceProcessor());
334
+
335
+ const sanitizeValue = (value: any) => {
336
+ switch (typeof value) {
337
+ case 'string':
338
+ case 'number':
339
+ case 'boolean':
340
+ case 'undefined':
341
+ return value;
342
+ break;
343
+ case 'object':
344
+ case 'function':
345
+ if (value === null) {
346
+ return value;
347
+ break;
348
+ }
349
+
350
+ // TODO(dmaretskyi): Expose trait.
351
+ if (typeof value.truncate === 'function') {
352
+ return value.truncate();
353
+ }
354
+
355
+ return value.toString();
356
+ }
357
+ };
358
+
359
+ const areEqualShallow = (a: any, b: any) => {
360
+ for (const key in a) {
361
+ if (!(key in b) || a[key] !== b[key]) {
362
+ return false;
363
+ }
364
+ }
365
+ for (const key in b) {
366
+ if (!(key in a) || a[key] !== b[key]) {
367
+ return false;
368
+ }
369
+ }
370
+ return true;
371
+ };