@dxos/tracing 0.1.56-main.ad054df
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/LICENSE +8 -0
- package/README.md +3 -0
- package/dist/lib/browser/index.mjs +308 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/node/index.cjs +342 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/types/src/api.d.ts +10 -0
- package/dist/types/src/api.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/symbols.d.ts +7 -0
- package/dist/types/src/symbols.d.ts.map +1 -0
- package/dist/types/src/trace-processor.d.ts +61 -0
- package/dist/types/src/trace-processor.d.ts.map +1 -0
- package/dist/types/src/trace-sender.d.ts +9 -0
- package/dist/types/src/trace-sender.d.ts.map +1 -0
- package/dist/types/src/tracing.test.d.ts +2 -0
- package/dist/types/src/tracing.test.d.ts.map +1 -0
- package/package.json +32 -0
- package/src/api.ts +56 -0
- package/src/index.ts +8 -0
- package/src/symbols.ts +17 -0
- package/src/trace-processor.ts +215 -0
- package/src/trace-sender.ts +78 -0
- package/src/tracing.test.ts +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
Copyright (c) 2022 DXOS
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5
|
+
|
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
7
|
+
|
|
8
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
// packages/common/tracing/src/api.ts
|
|
2
|
+
import { Context } from "@dxos/context";
|
|
3
|
+
|
|
4
|
+
// packages/common/tracing/src/symbols.ts
|
|
5
|
+
var symbolTracingContext = Symbol("dxos.tracing-context");
|
|
6
|
+
var getTracingContext = (target) => {
|
|
7
|
+
var _a2;
|
|
8
|
+
return (_a2 = target[symbolTracingContext]) != null ? _a2 : target[symbolTracingContext] = {
|
|
9
|
+
infoProperties: {}
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
var TRACE_SPAN_ATTRIBUTE = "dxos.trace-span";
|
|
13
|
+
|
|
14
|
+
// packages/common/tracing/src/trace-processor.ts
|
|
15
|
+
import { getPrototypeSpecificInstanceId } from "@dxos/util";
|
|
16
|
+
|
|
17
|
+
// packages/common/tracing/src/trace-sender.ts
|
|
18
|
+
import { Stream } from "@dxos/codec-protobuf";
|
|
19
|
+
var FLUSH_INTERVAL = 1e3;
|
|
20
|
+
var TraceSender = class {
|
|
21
|
+
constructor(_traceProcessor) {
|
|
22
|
+
this._traceProcessor = _traceProcessor;
|
|
23
|
+
}
|
|
24
|
+
streamTrace(request) {
|
|
25
|
+
return new Stream(({ ctx, next }) => {
|
|
26
|
+
const subscription = {
|
|
27
|
+
dirtyResources: /* @__PURE__ */ new Set(),
|
|
28
|
+
dirtySpans: /* @__PURE__ */ new Set()
|
|
29
|
+
};
|
|
30
|
+
this._traceProcessor.subscriptions.add(subscription);
|
|
31
|
+
ctx.onDispose(() => {
|
|
32
|
+
this._traceProcessor.subscriptions.delete(subscription);
|
|
33
|
+
});
|
|
34
|
+
const flushEvents = (resources, spans) => {
|
|
35
|
+
const event = {
|
|
36
|
+
resourceAdded: [],
|
|
37
|
+
resourceRemoved: [],
|
|
38
|
+
spanAdded: []
|
|
39
|
+
};
|
|
40
|
+
if (resources) {
|
|
41
|
+
for (const id of resources) {
|
|
42
|
+
const entry = this._traceProcessor.resources.get(id);
|
|
43
|
+
if (entry) {
|
|
44
|
+
event.resourceAdded.push({
|
|
45
|
+
resource: entry.data
|
|
46
|
+
});
|
|
47
|
+
} else {
|
|
48
|
+
event.resourceRemoved.push({
|
|
49
|
+
id
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
for (const entry of this._traceProcessor.resources.values()) {
|
|
55
|
+
event.resourceAdded.push({
|
|
56
|
+
resource: entry.data
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (spans) {
|
|
61
|
+
for (const id of spans) {
|
|
62
|
+
const span2 = this._traceProcessor.spans.get(id);
|
|
63
|
+
if (span2) {
|
|
64
|
+
event.spanAdded.push({
|
|
65
|
+
span: span2
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
for (const span2 of this._traceProcessor.spans.values()) {
|
|
71
|
+
event.spanAdded.push({
|
|
72
|
+
span: span2
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (event.resourceAdded.length > 0 || event.resourceRemoved.length > 0 || event.spanAdded.length > 0) {
|
|
77
|
+
next(event);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
flushEvents(null, null);
|
|
81
|
+
const timer = setInterval(() => {
|
|
82
|
+
flushEvents(subscription.dirtyResources, subscription.dirtySpans);
|
|
83
|
+
subscription.dirtyResources.clear();
|
|
84
|
+
subscription.dirtySpans.clear();
|
|
85
|
+
}, FLUSH_INTERVAL);
|
|
86
|
+
ctx.onDispose(() => {
|
|
87
|
+
clearInterval(timer);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// packages/common/tracing/src/trace-processor.ts
|
|
94
|
+
var MAX_RESOURCE_RECORDS = 500;
|
|
95
|
+
var MAX_SPAN_RECORDS = 1e3;
|
|
96
|
+
var TraceProcessor = class {
|
|
97
|
+
constructor() {
|
|
98
|
+
this.resources = /* @__PURE__ */ new Map();
|
|
99
|
+
this.resourceInstanceIndex = /* @__PURE__ */ new WeakMap();
|
|
100
|
+
this.resourceIdList = [];
|
|
101
|
+
this.spans = /* @__PURE__ */ new Map();
|
|
102
|
+
this.spanIdList = [];
|
|
103
|
+
this.subscriptions = /* @__PURE__ */ new Set();
|
|
104
|
+
}
|
|
105
|
+
traceResourceConstructor(params) {
|
|
106
|
+
const id = this.resources.size;
|
|
107
|
+
const entry = {
|
|
108
|
+
data: {
|
|
109
|
+
id,
|
|
110
|
+
className: params.constructor.name,
|
|
111
|
+
instanceId: getPrototypeSpecificInstanceId(params.instance),
|
|
112
|
+
info: this.getResourceInfo(params.instance),
|
|
113
|
+
links: []
|
|
114
|
+
},
|
|
115
|
+
instance: new WeakRef(params.instance)
|
|
116
|
+
};
|
|
117
|
+
this.resources.set(id, entry);
|
|
118
|
+
this.resourceInstanceIndex.set(params.instance, entry);
|
|
119
|
+
this.resourceIdList.push(id);
|
|
120
|
+
if (this.resourceIdList.length > MAX_RESOURCE_RECORDS) {
|
|
121
|
+
this._clearResources();
|
|
122
|
+
}
|
|
123
|
+
this._markResourceDirty(id);
|
|
124
|
+
}
|
|
125
|
+
getResourceInfo(instance) {
|
|
126
|
+
const res = {};
|
|
127
|
+
const tracingContext = getTracingContext(Object.getPrototypeOf(instance));
|
|
128
|
+
for (const [key, _opts] of Object.entries(tracingContext.infoProperties)) {
|
|
129
|
+
try {
|
|
130
|
+
res[key] = typeof instance[key] === "function" ? instance[key]() : instance[key];
|
|
131
|
+
} catch (err) {
|
|
132
|
+
res[key] = err.message;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return res;
|
|
136
|
+
}
|
|
137
|
+
traceSpan(params) {
|
|
138
|
+
const span2 = new TracingSpan(this, params);
|
|
139
|
+
this._flushSpan(span2);
|
|
140
|
+
return span2;
|
|
141
|
+
}
|
|
142
|
+
addLink(parent, child, opts) {
|
|
143
|
+
}
|
|
144
|
+
getResourceId(instance) {
|
|
145
|
+
const entry = this.resourceInstanceIndex.get(instance);
|
|
146
|
+
return entry ? entry.data.id : null;
|
|
147
|
+
}
|
|
148
|
+
createTraceSender() {
|
|
149
|
+
return new TraceSender(this);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
_flushSpan(runtimeSpan) {
|
|
155
|
+
const span2 = runtimeSpan.serialize();
|
|
156
|
+
this.spans.set(span2.id, span2);
|
|
157
|
+
this.spanIdList.push(span2.id);
|
|
158
|
+
if (this.spanIdList.length > MAX_SPAN_RECORDS) {
|
|
159
|
+
this._clearSpans();
|
|
160
|
+
}
|
|
161
|
+
this._markSpanDirty(span2.id);
|
|
162
|
+
}
|
|
163
|
+
_markResourceDirty(id) {
|
|
164
|
+
for (const subscription of this.subscriptions) {
|
|
165
|
+
subscription.dirtyResources.add(id);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
_markSpanDirty(id) {
|
|
169
|
+
for (const subscription of this.subscriptions) {
|
|
170
|
+
subscription.dirtySpans.add(id);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
_clearResources() {
|
|
174
|
+
while (this.resourceIdList.length > MAX_RESOURCE_RECORDS) {
|
|
175
|
+
const id = this.resourceIdList.shift();
|
|
176
|
+
this.resources.delete(id);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
_clearSpans() {
|
|
180
|
+
while (this.spanIdList.length > MAX_SPAN_RECORDS) {
|
|
181
|
+
const id = this.spanIdList.shift();
|
|
182
|
+
this.spans.delete(id);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
var _TracingSpan = class {
|
|
187
|
+
constructor(_traceProcessor, params) {
|
|
188
|
+
this._traceProcessor = _traceProcessor;
|
|
189
|
+
this.parentId = null;
|
|
190
|
+
this.resourceId = null;
|
|
191
|
+
this.endTs = null;
|
|
192
|
+
this.error = null;
|
|
193
|
+
this._ctx = null;
|
|
194
|
+
this.id = _TracingSpan.nextId++;
|
|
195
|
+
this.methodName = params.methodName;
|
|
196
|
+
this.resourceId = _traceProcessor.getResourceId(params.instance);
|
|
197
|
+
this.startTs = performance.now();
|
|
198
|
+
if (params.parentCtx) {
|
|
199
|
+
this._ctx = params.parentCtx.derive({
|
|
200
|
+
attributes: {
|
|
201
|
+
[TRACE_SPAN_ATTRIBUTE]: this.id
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
const parentId = params.parentCtx.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
205
|
+
if (typeof parentId === "number") {
|
|
206
|
+
this.parentId = parentId;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
get ctx() {
|
|
211
|
+
return this._ctx;
|
|
212
|
+
}
|
|
213
|
+
markSuccess() {
|
|
214
|
+
this.endTs = performance.now();
|
|
215
|
+
this._traceProcessor._flushSpan(this);
|
|
216
|
+
}
|
|
217
|
+
markError(err) {
|
|
218
|
+
this.endTs = performance.now();
|
|
219
|
+
this.error = serializeError(err);
|
|
220
|
+
this._traceProcessor._flushSpan(this);
|
|
221
|
+
}
|
|
222
|
+
serialize() {
|
|
223
|
+
var _a2, _b, _c, _d, _e;
|
|
224
|
+
return {
|
|
225
|
+
id: this.id,
|
|
226
|
+
resourceId: (_a2 = this.resourceId) != null ? _a2 : void 0,
|
|
227
|
+
methodName: this.methodName,
|
|
228
|
+
parentId: (_b = this.parentId) != null ? _b : void 0,
|
|
229
|
+
startTs: this.startTs.toFixed(3),
|
|
230
|
+
endTs: (_d = (_c = this.endTs) == null ? void 0 : _c.toFixed(3)) != null ? _d : void 0,
|
|
231
|
+
error: (_e = this.error) != null ? _e : void 0
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
var TracingSpan = _TracingSpan;
|
|
236
|
+
TracingSpan.nextId = 0;
|
|
237
|
+
var serializeError = (err) => {
|
|
238
|
+
if (err instanceof Error) {
|
|
239
|
+
return {
|
|
240
|
+
name: err.name,
|
|
241
|
+
message: err.message
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
message: String(err)
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
var _a;
|
|
249
|
+
var TRACE_PROCESSOR = (_a = globalThis.TRACE_PROCESSOR) != null ? _a : globalThis.TRACE_PROCESSOR = new TraceProcessor();
|
|
250
|
+
|
|
251
|
+
// packages/common/tracing/src/api.ts
|
|
252
|
+
var resource = () => (constructor) => {
|
|
253
|
+
return class extends constructor {
|
|
254
|
+
constructor(...rest) {
|
|
255
|
+
super(...rest);
|
|
256
|
+
TRACE_PROCESSOR.traceResourceConstructor({
|
|
257
|
+
constructor,
|
|
258
|
+
instance: this
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
var info = () => (target, propertyKey, descriptor) => {
|
|
264
|
+
getTracingContext(target).infoProperties[propertyKey] = {};
|
|
265
|
+
};
|
|
266
|
+
var span = () => (target, propertyKey, descriptor) => {
|
|
267
|
+
const method = descriptor.value;
|
|
268
|
+
descriptor.value = async function(...args) {
|
|
269
|
+
const parentCtx = args[0] instanceof Context ? args[0] : null;
|
|
270
|
+
const span2 = TRACE_PROCESSOR.traceSpan({
|
|
271
|
+
parentCtx,
|
|
272
|
+
methodName: propertyKey,
|
|
273
|
+
instance: this
|
|
274
|
+
});
|
|
275
|
+
const callArgs = span2.ctx ? [
|
|
276
|
+
span2.ctx,
|
|
277
|
+
...args.slice(1)
|
|
278
|
+
] : args;
|
|
279
|
+
try {
|
|
280
|
+
return await method.apply(this, callArgs);
|
|
281
|
+
} catch (err) {
|
|
282
|
+
span2.markError(err);
|
|
283
|
+
throw err;
|
|
284
|
+
} finally {
|
|
285
|
+
span2.markSuccess();
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
var addLink = (parent, child, opts = {}) => {
|
|
290
|
+
TRACE_PROCESSOR.addLink(parent, child, opts);
|
|
291
|
+
};
|
|
292
|
+
var trace = {
|
|
293
|
+
resource,
|
|
294
|
+
info,
|
|
295
|
+
span,
|
|
296
|
+
addLink
|
|
297
|
+
};
|
|
298
|
+
export {
|
|
299
|
+
TRACE_PROCESSOR,
|
|
300
|
+
TRACE_SPAN_ATTRIBUTE,
|
|
301
|
+
TraceProcessor,
|
|
302
|
+
TraceSender,
|
|
303
|
+
TracingSpan,
|
|
304
|
+
getTracingContext,
|
|
305
|
+
symbolTracingContext,
|
|
306
|
+
trace
|
|
307
|
+
};
|
|
308
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/api.ts", "../../../src/symbols.ts", "../../../src/trace-processor.ts", "../../../src/trace-sender.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Context } from '@dxos/context';\n\nimport { getTracingContext } from './symbols';\nimport { TRACE_PROCESSOR } from './trace-processor';\n\nconst resource =\n () =>\n <T extends { new (...args: any[]): {} }>(constructor: T) => {\n return class extends constructor {\n constructor(...rest: any[]) {\n super(...rest);\n TRACE_PROCESSOR.traceResourceConstructor({ constructor, instance: this });\n }\n };\n };\n\nconst info = () => (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => {\n getTracingContext(target).infoProperties[propertyKey] = {};\n};\n\nconst span = () => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any) => any>) => {\n const method = descriptor.value!;\n\n descriptor.value = async function (this: any, ...args: any) {\n const parentCtx = args[0] instanceof Context ? args[0] : null;\n const span = TRACE_PROCESSOR.traceSpan({ parentCtx, methodName: propertyKey, instance: this });\n\n const callArgs = span.ctx ? [span.ctx, ...args.slice(1)] : args;\n try {\n return await method.apply(this, callArgs);\n } catch (err) {\n span.markError(err);\n throw err;\n } finally {\n span.markSuccess();\n }\n };\n};\n\nexport type AddLinkOptions = {};\n\nconst addLink = (parent: any, child: any, opts: AddLinkOptions = {}) => {\n TRACE_PROCESSOR.addLink(parent, child, opts);\n};\n\nexport const trace = {\n resource,\n info,\n span,\n\n addLink,\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const symbolTracingContext = Symbol('dxos.tracing-context');\n\nexport type TracingContext = {\n infoProperties: Record<string, {}>;\n};\n\nexport const getTracingContext = (target: any): TracingContext => {\n return (target[symbolTracingContext] ??= {\n infoProperties: {},\n });\n};\n\nexport const TRACE_SPAN_ATTRIBUTE = 'dxos.trace-span';\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { Context } from '@dxos/context';\nimport { Error as SerializedError } from '@dxos/protocols/proto/dxos/error';\nimport { Resource, Span } from '@dxos/protocols/proto/dxos/tracing';\nimport { getPrototypeSpecificInstanceId } from '@dxos/util';\n\nimport type { AddLinkOptions } from './api';\nimport { TRACE_SPAN_ATTRIBUTE, getTracingContext } from './symbols';\nimport { TraceSender } from './trace-sender';\n\nexport type TraceResourceConstructorParams = {\n constructor: { new (...args: any[]): {} };\n instance: any;\n};\n\nexport type TraceSpanParams = {\n instance: any;\n methodName: string;\n parentCtx: Context | null;\n};\n\nexport type ResourceEntry = {\n data: Resource;\n instance: WeakRef<any>;\n};\n\nexport type TraceSubscription = {\n dirtyResources: Set<number>;\n dirtySpans: Set<number>;\n};\n\nconst MAX_RESOURCE_RECORDS = 500;\nconst MAX_SPAN_RECORDS = 1_000;\n\nexport class TraceProcessor {\n resources = new Map<number, ResourceEntry>();\n resourceInstanceIndex = new WeakMap<any, ResourceEntry>();\n resourceIdList: number[] = [];\n\n spans = new Map<number, Span>();\n spanIdList: number[] = [];\n\n subscriptions: Set<TraceSubscription> = new Set();\n\n traceResourceConstructor(params: TraceResourceConstructorParams) {\n const id = this.resources.size;\n const entry: ResourceEntry = {\n data: {\n id,\n className: params.constructor.name,\n instanceId: getPrototypeSpecificInstanceId(params.instance),\n info: this.getResourceInfo(params.instance),\n links: [],\n },\n instance: new WeakRef(params.instance),\n };\n this.resources.set(id, entry);\n this.resourceInstanceIndex.set(params.instance, entry);\n this.resourceIdList.push(id);\n if (this.resourceIdList.length > MAX_RESOURCE_RECORDS) {\n this._clearResources();\n }\n this._markResourceDirty(id);\n }\n\n getResourceInfo(instance: any): Record<string, any> {\n const res: Record<string, any> = {};\n const tracingContext = getTracingContext(Object.getPrototypeOf(instance));\n\n for (const [key, _opts] of Object.entries(tracingContext.infoProperties)) {\n try {\n res[key] = typeof instance[key] === 'function' ? instance[key]() : instance[key];\n } catch (err: any) {\n res[key] = err.message;\n }\n }\n\n return res;\n }\n\n traceSpan(params: TraceSpanParams): TracingSpan {\n const span = new TracingSpan(this, params);\n this._flushSpan(span);\n return span;\n }\n\n addLink(parent: any, child: any, opts: AddLinkOptions) {}\n\n getResourceId(instance: any): number | null {\n const entry = this.resourceInstanceIndex.get(instance);\n return entry ? entry.data.id : null;\n }\n\n createTraceSender() {\n return new TraceSender(this);\n }\n\n /**\n * @internal\n */\n _flushSpan(runtimeSpan: TracingSpan) {\n const span = runtimeSpan.serialize();\n this.spans.set(span.id, span);\n this.spanIdList.push(span.id);\n if (this.spanIdList.length > MAX_SPAN_RECORDS) {\n this._clearSpans();\n }\n this._markSpanDirty(span.id);\n }\n\n private _markResourceDirty(id: number) {\n for (const subscription of this.subscriptions) {\n subscription.dirtyResources.add(id);\n }\n }\n\n private _markSpanDirty(id: number) {\n for (const subscription of this.subscriptions) {\n subscription.dirtySpans.add(id);\n }\n }\n\n private _clearResources() {\n // TODO(dmaretskyi): Use FinalizationRegistry to delete finalized resources first.\n while (this.resourceIdList.length > MAX_RESOURCE_RECORDS) {\n const id = this.resourceIdList.shift()!;\n this.resources.delete(id);\n }\n }\n\n private _clearSpans() {\n while (this.spanIdList.length > MAX_SPAN_RECORDS) {\n const id = this.spanIdList.shift()!;\n this.spans.delete(id);\n }\n }\n}\n\nexport class TracingSpan {\n static nextId = 0;\n\n readonly id: number;\n readonly parentId: number | null = null;\n readonly methodName: string;\n readonly resourceId: number | null = null;\n startTs: number;\n endTs: number | null = null;\n error: SerializedError | null = null;\n\n private readonly _ctx: Context | null = null;\n\n constructor(private _traceProcessor: TraceProcessor, params: TraceSpanParams) {\n this.id = TracingSpan.nextId++;\n this.methodName = params.methodName;\n this.resourceId = _traceProcessor.getResourceId(params.instance);\n this.startTs = performance.now();\n\n if (params.parentCtx) {\n this._ctx = params.parentCtx.derive({\n attributes: {\n [TRACE_SPAN_ATTRIBUTE]: this.id,\n },\n });\n const parentId = params.parentCtx.getAttribute(TRACE_SPAN_ATTRIBUTE);\n if (typeof parentId === 'number') {\n this.parentId = parentId;\n }\n }\n }\n\n get ctx(): Context | null {\n return this._ctx;\n }\n\n markSuccess() {\n this.endTs = performance.now();\n this._traceProcessor._flushSpan(this);\n }\n\n markError(err: unknown) {\n this.endTs = performance.now();\n this.error = serializeError(err);\n this._traceProcessor._flushSpan(this);\n }\n\n serialize(): Span {\n return {\n id: this.id,\n resourceId: this.resourceId ?? undefined,\n methodName: this.methodName,\n parentId: this.parentId ?? undefined,\n startTs: this.startTs.toFixed(3),\n endTs: this.endTs?.toFixed(3) ?? undefined,\n error: this.error ?? undefined,\n };\n }\n}\n\nconst serializeError = (err: unknown): SerializedError => {\n if (err instanceof Error) {\n return {\n name: err.name,\n message: err.message,\n };\n }\n\n return {\n message: String(err),\n };\n};\n\nexport const TRACE_PROCESSOR: TraceProcessor = ((globalThis as any).TRACE_PROCESSOR ??= new TraceProcessor());\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { Stream } from '@dxos/codec-protobuf';\nimport { StreamTraceEvent, TracingService } from '@dxos/protocols/proto/dxos/tracing';\n\nimport { TraceProcessor, TraceSubscription } from './trace-processor';\n\nconst FLUSH_INTERVAL = 1_000;\n\nexport class TraceSender implements TracingService {\n constructor(private _traceProcessor: TraceProcessor) {}\n\n streamTrace(request: void): Stream<StreamTraceEvent> {\n return new Stream(({ ctx, next }) => {\n const subscription: TraceSubscription = {\n dirtyResources: new Set(),\n dirtySpans: new Set(),\n };\n this._traceProcessor.subscriptions.add(subscription);\n ctx.onDispose(() => {\n this._traceProcessor.subscriptions.delete(subscription);\n });\n\n const flushEvents = (resources: Set<number> | null, spans: Set<number> | null) => {\n const event: StreamTraceEvent = {\n resourceAdded: [],\n resourceRemoved: [],\n spanAdded: [],\n };\n\n if (resources) {\n for (const id of resources) {\n const entry = this._traceProcessor.resources.get(id);\n if (entry) {\n event.resourceAdded!.push({ resource: entry.data });\n } else {\n event.resourceRemoved!.push({ id });\n }\n }\n } else {\n for (const entry of this._traceProcessor.resources.values()) {\n event.resourceAdded!.push({ resource: entry.data });\n }\n }\n\n if (spans) {\n for (const id of spans) {\n const span = this._traceProcessor.spans.get(id);\n if (span) {\n event.spanAdded!.push({ span });\n }\n }\n } else {\n for (const span of this._traceProcessor.spans.values()) {\n event.spanAdded!.push({ span });\n }\n }\n\n if (event.resourceAdded!.length > 0 || event.resourceRemoved!.length > 0 || event.spanAdded!.length > 0) {\n next(event);\n }\n };\n\n flushEvents(null, null);\n\n const timer = setInterval(() => {\n flushEvents(subscription.dirtyResources, subscription.dirtySpans);\n subscription.dirtyResources.clear();\n subscription.dirtySpans.clear();\n }, FLUSH_INTERVAL);\n ctx.onDispose(() => {\n clearInterval(timer);\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Context", "symbolTracingContext", "Symbol", "getTracingContext", "target", "_a", "infoProperties", "TRACE_SPAN_ATTRIBUTE", "getPrototypeSpecificInstanceId", "Stream", "FLUSH_INTERVAL", "TraceSender", "constructor", "_traceProcessor", "streamTrace", "request", "Stream", "ctx", "next", "subscription", "dirtyResources", "Set", "dirtySpans", "subscriptions", "add", "onDispose", "delete", "flushEvents", "resources", "spans", "event", "resourceAdded", "resourceRemoved", "spanAdded", "id", "entry", "get", "push", "resource", "data", "values", "span", "length", "timer", "setInterval", "clear", "clearInterval", "MAX_RESOURCE_RECORDS", "MAX_SPAN_RECORDS", "TraceProcessor", "resources", "Map", "resourceInstanceIndex", "WeakMap", "resourceIdList", "spans", "spanIdList", "subscriptions", "Set", "traceResourceConstructor", "params", "id", "size", "entry", "data", "className", "constructor", "name", "instanceId", "getPrototypeSpecificInstanceId", "instance", "info", "getResourceInfo", "links", "WeakRef", "set", "push", "length", "_clearResources", "_markResourceDirty", "res", "tracingContext", "getTracingContext", "Object", "getPrototypeOf", "key", "_opts", "entries", "infoProperties", "err", "message", "traceSpan", "span", "TracingSpan", "_flushSpan", "addLink", "parent", "child", "opts", "getResourceId", "get", "createTraceSender", "TraceSender", "runtimeSpan", "serialize", "_clearSpans", "_markSpanDirty", "subscription", "dirtyResources", "add", "dirtySpans", "shift", "delete", "_traceProcessor", "parentId", "resourceId", "endTs", "error", "_ctx", "nextId", "methodName", "startTs", "performance", "now", "parentCtx", "derive", "attributes", "TRACE_SPAN_ATTRIBUTE", "getAttribute", "ctx", "markSuccess", "markError", "serializeError", "_a", "undefined", "toFixed", "Error", "String", "TRACE_PROCESSOR", "globalThis", "resource", "constructor", "rest", "TRACE_PROCESSOR", "traceResourceConstructor", "instance", "info", "target", "propertyKey", "descriptor", "getTracingContext", "infoProperties", "span", "method", "value", "args", "parentCtx", "Context", "traceSpan", "methodName", "callArgs", "ctx", "slice", "apply", "err", "markError", "markSuccess", "addLink", "parent", "child", "opts", "trace"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"inputs":{"packages/common/tracing/src/symbols.ts":{"bytes":1464,"imports":[]},"packages/common/tracing/src/trace-sender.ts":{"bytes":9080,"imports":[{"path":"@dxos/codec-protobuf","kind":"import-statement","external":true}]},"packages/common/tracing/src/trace-processor.ts":{"bytes":20068,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/tracing/src/symbols.ts","kind":"import-statement","original":"./symbols"},{"path":"packages/common/tracing/src/trace-sender.ts","kind":"import-statement","original":"./trace-sender"}]},"packages/common/tracing/src/api.ts":{"bytes":5722,"imports":[{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"packages/common/tracing/src/symbols.ts","kind":"import-statement","original":"./symbols"},{"path":"packages/common/tracing/src/trace-processor.ts","kind":"import-statement","original":"./trace-processor"}]},"packages/common/tracing/src/index.ts":{"bytes":744,"imports":[{"path":"packages/common/tracing/src/api.ts","kind":"import-statement","original":"./api"},{"path":"packages/common/tracing/src/symbols.ts","kind":"import-statement","original":"./symbols"},{"path":"packages/common/tracing/src/trace-processor.ts","kind":"import-statement","original":"./trace-processor"},{"path":"packages/common/tracing/src/trace-sender.ts","kind":"import-statement","original":"./trace-sender"}]}},"outputs":{"packages/common/tracing/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18452},"packages/common/tracing/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/context","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/codec-protobuf","kind":"import-statement","external":true}],"exports":["TRACE_PROCESSOR","TRACE_SPAN_ATTRIBUTE","TraceProcessor","TraceSender","TracingSpan","getTracingContext","symbolTracingContext","trace"],"entryPoint":"packages/common/tracing/src/index.ts","inputs":{"packages/common/tracing/src/api.ts":{"bytesInOutput":1155},"packages/common/tracing/src/symbols.ts":{"bytesInOutput":280},"packages/common/tracing/src/trace-processor.ts":{"bytesInOutput":4530},"packages/common/tracing/src/trace-sender.ts":{"bytesInOutput":2229},"packages/common/tracing/src/index.ts":{"bytesInOutput":0}},"bytes":8655}}}
|