@dxos/tracing 0.8.4-main.9be5663bfe → 0.8.4-main.abd8ff62ef
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/index.mjs +330 -513
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +330 -513
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/api.d.ts +31 -14
- package/dist/types/src/api.d.ts.map +1 -1
- package/dist/types/src/buffering-backend.d.ts +24 -0
- package/dist/types/src/buffering-backend.d.ts.map +1 -0
- package/dist/types/src/diagnostic.d.ts.map +1 -1
- package/dist/types/src/diagnostics-channel.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/metrics/base.d.ts.map +1 -1
- package/dist/types/src/metrics/custom-counter.d.ts.map +1 -1
- package/dist/types/src/metrics/map-counter.d.ts.map +1 -1
- package/dist/types/src/metrics/time-series-counter.d.ts.map +1 -1
- package/dist/types/src/metrics/time-usage-counter.d.ts.map +1 -1
- package/dist/types/src/metrics/unary-counter.d.ts.map +1 -1
- package/dist/types/src/remote/index.d.ts +0 -1
- package/dist/types/src/remote/index.d.ts.map +1 -1
- package/dist/types/src/remote/metrics.d.ts.map +1 -1
- package/dist/types/src/symbols.d.ts +0 -1
- package/dist/types/src/symbols.d.ts.map +1 -1
- package/dist/types/src/trace-processor.d.ts +15 -56
- package/dist/types/src/trace-processor.d.ts.map +1 -1
- package/dist/types/src/tracing-types.d.ts +67 -0
- package/dist/types/src/tracing-types.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -12
- package/src/api.ts +235 -40
- package/src/buffering-backend.ts +112 -0
- package/src/index.ts +1 -2
- package/src/remote/index.ts +0 -1
- package/src/symbols.ts +0 -2
- package/src/trace-processor.ts +51 -263
- package/src/tracing-types.ts +77 -0
- package/src/tracing.test.ts +513 -4
- package/dist/types/src/remote/tracing.d.ts +0 -57
- package/dist/types/src/remote/tracing.d.ts.map +0 -1
- package/dist/types/src/trace-sender.d.ts +0 -9
- package/dist/types/src/trace-sender.d.ts.map +0 -1
- package/src/remote/tracing.ts +0 -175
- package/src/trace-sender.ts +0 -88
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
3
|
// src/api.ts
|
|
4
|
-
import { Context as
|
|
4
|
+
import { Context as Context2, LifecycleState, Resource, TRACE_SPAN_ATTRIBUTE } from "@dxos/context";
|
|
5
5
|
|
|
6
6
|
// src/symbols.ts
|
|
7
7
|
var symbolTracingContext = /* @__PURE__ */ Symbol("dxos.tracing.context");
|
|
@@ -11,14 +11,97 @@ var getTracingContext = (target) => {
|
|
|
11
11
|
metricsProperties: {}
|
|
12
12
|
};
|
|
13
13
|
};
|
|
14
|
-
var TRACE_SPAN_ATTRIBUTE = "dxos.trace-span";
|
|
15
14
|
|
|
16
15
|
// src/trace-processor.ts
|
|
17
|
-
import {
|
|
18
|
-
import { Context as Context2 } from "@dxos/context";
|
|
19
|
-
import { LogLevel, getContextFromEntry, log } from "@dxos/log";
|
|
16
|
+
import { LogLevel, log } from "@dxos/log";
|
|
20
17
|
import { getPrototypeSpecificInstanceId } from "@dxos/util";
|
|
21
18
|
|
|
19
|
+
// src/buffering-backend.ts
|
|
20
|
+
var BUFFERED_PREFIX = "buffered-";
|
|
21
|
+
var BufferedSpan = class {
|
|
22
|
+
options;
|
|
23
|
+
spanContext;
|
|
24
|
+
startTime;
|
|
25
|
+
delegate;
|
|
26
|
+
#ended = false;
|
|
27
|
+
#endTime;
|
|
28
|
+
#error;
|
|
29
|
+
#hasError = false;
|
|
30
|
+
constructor(options, id) {
|
|
31
|
+
this.options = options;
|
|
32
|
+
this.spanContext = {
|
|
33
|
+
traceparent: `${BUFFERED_PREFIX}${id}`
|
|
34
|
+
};
|
|
35
|
+
this.startTime = Date.now();
|
|
36
|
+
}
|
|
37
|
+
end(endTime) {
|
|
38
|
+
if (this.delegate) {
|
|
39
|
+
this.delegate.end(endTime);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.#endTime = endTime ?? Date.now();
|
|
43
|
+
this.#ended = true;
|
|
44
|
+
}
|
|
45
|
+
setError(err) {
|
|
46
|
+
if (this.delegate) {
|
|
47
|
+
this.delegate.setError?.(err);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.#error = err;
|
|
51
|
+
this.#hasError = true;
|
|
52
|
+
}
|
|
53
|
+
replay(real) {
|
|
54
|
+
if (this.#hasError) {
|
|
55
|
+
real.setError?.(this.#error);
|
|
56
|
+
}
|
|
57
|
+
if (this.#ended) {
|
|
58
|
+
real.end(this.#endTime);
|
|
59
|
+
} else {
|
|
60
|
+
this.delegate = real;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var BufferingTracingBackend = class {
|
|
65
|
+
#pending = [];
|
|
66
|
+
#counter = 0;
|
|
67
|
+
startSpan(options) {
|
|
68
|
+
const span2 = new BufferedSpan(options, ++this.#counter);
|
|
69
|
+
this.#pending.push(span2);
|
|
70
|
+
return span2;
|
|
71
|
+
}
|
|
72
|
+
/** Discard all buffered spans without replaying them. */
|
|
73
|
+
clear() {
|
|
74
|
+
this.#pending.length = 0;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Replay all buffered spans into {@link backend}.
|
|
78
|
+
*
|
|
79
|
+
* @returns Map from synthetic buffered traceparent to real {@link TraceContextData},
|
|
80
|
+
* used by the post-drain translating wrapper to resolve stale buffered IDs
|
|
81
|
+
* still present on in-flight {@link Context} objects.
|
|
82
|
+
*/
|
|
83
|
+
drain(backend) {
|
|
84
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
85
|
+
for (const buffered of this.#pending) {
|
|
86
|
+
let parentContext = buffered.options.parentContext;
|
|
87
|
+
if (parentContext && parentContext.traceparent.startsWith(BUFFERED_PREFIX)) {
|
|
88
|
+
parentContext = idMap.get(parentContext.traceparent) ?? parentContext;
|
|
89
|
+
}
|
|
90
|
+
const real = backend.startSpan({
|
|
91
|
+
...buffered.options,
|
|
92
|
+
parentContext,
|
|
93
|
+
startTime: buffered.startTime
|
|
94
|
+
});
|
|
95
|
+
if (real.spanContext) {
|
|
96
|
+
idMap.set(buffered.spanContext.traceparent, real.spanContext);
|
|
97
|
+
}
|
|
98
|
+
buffered.replay(real);
|
|
99
|
+
}
|
|
100
|
+
this.#pending.length = 0;
|
|
101
|
+
return idMap;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
22
105
|
// src/diagnostic.ts
|
|
23
106
|
import { asyncTimeout } from "@dxos/async";
|
|
24
107
|
import { invariant } from "@dxos/invariant";
|
|
@@ -73,27 +156,11 @@ var DiagnosticsManager = class {
|
|
|
73
156
|
}
|
|
74
157
|
async fetch(request) {
|
|
75
158
|
if (request.instanceId != null) {
|
|
76
|
-
invariant(request.instanceId === this.instanceId, "Invalid instance id", {
|
|
77
|
-
F: __dxlog_file,
|
|
78
|
-
L: 82,
|
|
79
|
-
S: this,
|
|
80
|
-
A: [
|
|
81
|
-
"request.instanceId === this.instanceId",
|
|
82
|
-
"'Invalid instance id'"
|
|
83
|
-
]
|
|
84
|
-
});
|
|
159
|
+
invariant(request.instanceId === this.instanceId, "Invalid instance id", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 52, S: this, A: ["request.instanceId === this.instanceId", "'Invalid instance id'"] });
|
|
85
160
|
}
|
|
86
161
|
const { id } = request;
|
|
87
162
|
const diagnostic2 = this.registry.get(id);
|
|
88
|
-
invariant(diagnostic2, "Diagnostic not found", {
|
|
89
|
-
F: __dxlog_file,
|
|
90
|
-
L: 86,
|
|
91
|
-
S: this,
|
|
92
|
-
A: [
|
|
93
|
-
"diagnostic",
|
|
94
|
-
"'Diagnostic not found'"
|
|
95
|
-
]
|
|
96
|
-
});
|
|
163
|
+
invariant(diagnostic2, "Diagnostic not found", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 56, S: this, A: ["diagnostic", "'Diagnostic not found'"] });
|
|
97
164
|
try {
|
|
98
165
|
const data = await asyncTimeout(diagnostic2.fetch(), DIAGNOSTICS_TIMEOUT);
|
|
99
166
|
return {
|
|
@@ -124,10 +191,7 @@ var DiagnosticsChannel = class _DiagnosticsChannel {
|
|
|
124
191
|
static get supported() {
|
|
125
192
|
return globalThis.BroadcastChannel != null;
|
|
126
193
|
}
|
|
127
|
-
_ctx = new Context(void 0, {
|
|
128
|
-
F: __dxlog_file2,
|
|
129
|
-
L: 46
|
|
130
|
-
});
|
|
194
|
+
_ctx = new Context(void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 16 });
|
|
131
195
|
// Separate channels becauase the client and server may be in the same process.
|
|
132
196
|
_serveChannel = void 0;
|
|
133
197
|
_clientChannel = void 0;
|
|
@@ -155,15 +219,7 @@ var DiagnosticsChannel = class _DiagnosticsChannel {
|
|
|
155
219
|
}
|
|
156
220
|
}
|
|
157
221
|
serve(manager) {
|
|
158
|
-
invariant2(this._serveChannel, void 0, {
|
|
159
|
-
F: __dxlog_file2,
|
|
160
|
-
L: 78,
|
|
161
|
-
S: this,
|
|
162
|
-
A: [
|
|
163
|
-
"this._serveChannel",
|
|
164
|
-
""
|
|
165
|
-
]
|
|
166
|
-
});
|
|
222
|
+
invariant2(this._serveChannel, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 43, S: this, A: ["this._serveChannel", ""] });
|
|
167
223
|
const listener = async (event) => {
|
|
168
224
|
switch (event.data.type) {
|
|
169
225
|
case "DIAGNOSTICS_DISCOVER": {
|
|
@@ -195,15 +251,7 @@ var DiagnosticsChannel = class _DiagnosticsChannel {
|
|
|
195
251
|
this._ctx.onDispose(() => this._serveChannel.removeEventListener("message", listener));
|
|
196
252
|
}
|
|
197
253
|
async discover() {
|
|
198
|
-
invariant2(this._clientChannel, void 0, {
|
|
199
|
-
F: __dxlog_file2,
|
|
200
|
-
L: 114,
|
|
201
|
-
S: this,
|
|
202
|
-
A: [
|
|
203
|
-
"this._clientChannel",
|
|
204
|
-
""
|
|
205
|
-
]
|
|
206
|
-
});
|
|
254
|
+
invariant2(this._clientChannel, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 77, S: this, A: ["this._clientChannel", ""] });
|
|
207
255
|
const diagnostics = [];
|
|
208
256
|
const collector = (event) => {
|
|
209
257
|
const data = event.data;
|
|
@@ -231,15 +279,7 @@ var DiagnosticsChannel = class _DiagnosticsChannel {
|
|
|
231
279
|
}
|
|
232
280
|
}
|
|
233
281
|
async fetch(request) {
|
|
234
|
-
invariant2(this._clientChannel, void 0, {
|
|
235
|
-
F: __dxlog_file2,
|
|
236
|
-
L: 147,
|
|
237
|
-
S: this,
|
|
238
|
-
A: [
|
|
239
|
-
"this._clientChannel",
|
|
240
|
-
""
|
|
241
|
-
]
|
|
242
|
-
});
|
|
282
|
+
invariant2(this._clientChannel, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 106, S: this, A: ["this._clientChannel", ""] });
|
|
243
283
|
const requestId = createId();
|
|
244
284
|
const trigger = new Trigger();
|
|
245
285
|
const listener = (event) => {
|
|
@@ -285,227 +325,6 @@ var RemoteMetrics = class {
|
|
|
285
325
|
}
|
|
286
326
|
};
|
|
287
327
|
|
|
288
|
-
// src/remote/tracing.ts
|
|
289
|
-
var MAX_ENDED_CONTEXTS = 1e4;
|
|
290
|
-
var RemoteTracing = class {
|
|
291
|
-
_tracing;
|
|
292
|
-
_spanMap = /* @__PURE__ */ new Map();
|
|
293
|
-
_idToSpan = /* @__PURE__ */ new Map();
|
|
294
|
-
/**
|
|
295
|
-
* Retains OTEL span contexts after spans end so that periodic/background
|
|
296
|
-
* operations referencing a completed parent (via `this._ctx`) still produce
|
|
297
|
-
* correlated child spans instead of orphaned root traces.
|
|
298
|
-
*/
|
|
299
|
-
_endedSpanContexts = /* @__PURE__ */ new Map();
|
|
300
|
-
/**
|
|
301
|
-
* Buffers flushSpan calls that arrive before a processor is registered,
|
|
302
|
-
* so early startup spans are not silently dropped.
|
|
303
|
-
*/
|
|
304
|
-
_pendingFlushes = [];
|
|
305
|
-
registerProcessor(processor) {
|
|
306
|
-
this._tracing = processor;
|
|
307
|
-
const pending = this._pendingFlushes;
|
|
308
|
-
this._pendingFlushes = null;
|
|
309
|
-
if (pending) {
|
|
310
|
-
for (const { span: span2, isEnd } of pending) {
|
|
311
|
-
this._replayFlush(span2, isEnd);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
/** Returns the opaque OTEL context for the given DXOS span ID, if one exists. */
|
|
316
|
-
getSpanContext(spanId) {
|
|
317
|
-
const tracingSpan = this._idToSpan.get(spanId);
|
|
318
|
-
if (tracingSpan) {
|
|
319
|
-
return this._spanMap.get(tracingSpan)?.spanContext;
|
|
320
|
-
}
|
|
321
|
-
return this._endedSpanContexts.get(spanId);
|
|
322
|
-
}
|
|
323
|
-
/** Wraps execution so that the remote span is active as parent context. */
|
|
324
|
-
wrapExecution(span2, fn) {
|
|
325
|
-
const remoteSpan = this._spanMap.get(span2);
|
|
326
|
-
if (remoteSpan?.wrapExecution) {
|
|
327
|
-
return remoteSpan.wrapExecution(fn);
|
|
328
|
-
}
|
|
329
|
-
return fn();
|
|
330
|
-
}
|
|
331
|
-
flushSpan(span2) {
|
|
332
|
-
if (!span2.showInRemoteTracing) {
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
if (!this._tracing) {
|
|
336
|
-
this._pendingFlushes?.push({
|
|
337
|
-
span: span2,
|
|
338
|
-
isEnd: !!span2.endTs
|
|
339
|
-
});
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
if (!span2.endTs) {
|
|
343
|
-
this._startRemoteSpan(span2);
|
|
344
|
-
} else {
|
|
345
|
-
this._endRemoteSpan(span2);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
_startRemoteSpan(span2) {
|
|
349
|
-
let parentContext;
|
|
350
|
-
if (span2.parentId != null) {
|
|
351
|
-
const parentTracingSpan = this._idToSpan.get(span2.parentId);
|
|
352
|
-
if (parentTracingSpan) {
|
|
353
|
-
parentContext = this._spanMap.get(parentTracingSpan)?.spanContext;
|
|
354
|
-
}
|
|
355
|
-
if (parentContext == null) {
|
|
356
|
-
parentContext = this._endedSpanContexts.get(span2.parentId);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
const attributes = {};
|
|
360
|
-
if (span2.sanitizedClassName) {
|
|
361
|
-
attributes.entryPoint = span2.sanitizedClassName;
|
|
362
|
-
}
|
|
363
|
-
for (const [key, value] of Object.entries(span2.attributes)) {
|
|
364
|
-
attributes[key.startsWith("ctx.") ? key : `ctx.${key}`] = value;
|
|
365
|
-
}
|
|
366
|
-
const remoteSpan = this._tracing.startSpan({
|
|
367
|
-
name: span2.name,
|
|
368
|
-
op: span2.op ?? "function",
|
|
369
|
-
attributes,
|
|
370
|
-
parentContext
|
|
371
|
-
});
|
|
372
|
-
this._spanMap.set(span2, remoteSpan);
|
|
373
|
-
this._idToSpan.set(span2.id, span2);
|
|
374
|
-
}
|
|
375
|
-
_endRemoteSpan(span2) {
|
|
376
|
-
const remoteSpan = this._spanMap.get(span2);
|
|
377
|
-
if (remoteSpan) {
|
|
378
|
-
if (remoteSpan.spanContext != null) {
|
|
379
|
-
this._endedSpanContexts.set(span2.id, remoteSpan.spanContext);
|
|
380
|
-
this._evictEndedContexts();
|
|
381
|
-
}
|
|
382
|
-
remoteSpan.end();
|
|
383
|
-
this._spanMap.delete(span2);
|
|
384
|
-
this._idToSpan.delete(span2.id);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Replays a buffered flush that was queued before the processor was registered.
|
|
389
|
-
* For spans that started AND ended before registration, replays both events.
|
|
390
|
-
*/
|
|
391
|
-
_replayFlush(span2, isEnd) {
|
|
392
|
-
if (!isEnd) {
|
|
393
|
-
this._startRemoteSpan(span2);
|
|
394
|
-
if (span2.endTs != null) {
|
|
395
|
-
this._endRemoteSpan(span2);
|
|
396
|
-
}
|
|
397
|
-
} else {
|
|
398
|
-
if (!this._spanMap.has(span2)) {
|
|
399
|
-
this._startRemoteSpan(span2);
|
|
400
|
-
}
|
|
401
|
-
this._endRemoteSpan(span2);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
_evictEndedContexts() {
|
|
405
|
-
if (this._endedSpanContexts.size <= MAX_ENDED_CONTEXTS) {
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
const iterator = this._endedSpanContexts.keys();
|
|
409
|
-
while (this._endedSpanContexts.size > MAX_ENDED_CONTEXTS) {
|
|
410
|
-
const oldest = iterator.next();
|
|
411
|
-
if (oldest.done) {
|
|
412
|
-
break;
|
|
413
|
-
}
|
|
414
|
-
this._endedSpanContexts.delete(oldest.value);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
|
|
419
|
-
// src/trace-sender.ts
|
|
420
|
-
import { Stream } from "@dxos/codec-protobuf/stream";
|
|
421
|
-
var TraceSender = class {
|
|
422
|
-
_traceProcessor;
|
|
423
|
-
constructor(_traceProcessor) {
|
|
424
|
-
this._traceProcessor = _traceProcessor;
|
|
425
|
-
}
|
|
426
|
-
streamTrace(request) {
|
|
427
|
-
return new Stream(({ ctx, next }) => {
|
|
428
|
-
const flushEvents = (resources, spans2, logs) => {
|
|
429
|
-
const event = {
|
|
430
|
-
resourceAdded: [],
|
|
431
|
-
resourceRemoved: [],
|
|
432
|
-
spanAdded: [],
|
|
433
|
-
logAdded: []
|
|
434
|
-
};
|
|
435
|
-
if (resources) {
|
|
436
|
-
for (const id of resources) {
|
|
437
|
-
const entry = this._traceProcessor.resources.get(id);
|
|
438
|
-
if (entry) {
|
|
439
|
-
event.resourceAdded.push({
|
|
440
|
-
resource: entry.data
|
|
441
|
-
});
|
|
442
|
-
} else {
|
|
443
|
-
event.resourceRemoved.push({
|
|
444
|
-
id
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
} else {
|
|
449
|
-
for (const entry of this._traceProcessor.resources.values()) {
|
|
450
|
-
event.resourceAdded.push({
|
|
451
|
-
resource: entry.data
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
if (spans2) {
|
|
456
|
-
for (const id of spans2) {
|
|
457
|
-
const span2 = this._traceProcessor.spans.get(id);
|
|
458
|
-
if (span2) {
|
|
459
|
-
event.spanAdded.push({
|
|
460
|
-
span: span2
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
} else {
|
|
465
|
-
for (const span2 of this._traceProcessor.spans.values()) {
|
|
466
|
-
event.spanAdded.push({
|
|
467
|
-
span: span2
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
if (logs) {
|
|
472
|
-
for (const log2 of logs) {
|
|
473
|
-
event.logAdded.push({
|
|
474
|
-
log: log2
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
} else {
|
|
478
|
-
for (const log2 of this._traceProcessor.logs) {
|
|
479
|
-
event.logAdded.push({
|
|
480
|
-
log: log2
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
if (event.resourceAdded.length > 0 || event.resourceRemoved.length > 0 || event.spanAdded.length > 0) {
|
|
485
|
-
next(event);
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
const flush = () => {
|
|
489
|
-
flushEvents(subscription.dirtyResources, subscription.dirtySpans, subscription.newLogs);
|
|
490
|
-
subscription.dirtyResources.clear();
|
|
491
|
-
subscription.dirtySpans.clear();
|
|
492
|
-
subscription.newLogs.length = 0;
|
|
493
|
-
};
|
|
494
|
-
const subscription = {
|
|
495
|
-
flush,
|
|
496
|
-
dirtyResources: /* @__PURE__ */ new Set(),
|
|
497
|
-
dirtySpans: /* @__PURE__ */ new Set(),
|
|
498
|
-
newLogs: []
|
|
499
|
-
};
|
|
500
|
-
this._traceProcessor.subscriptions.add(subscription);
|
|
501
|
-
ctx.onDispose(() => {
|
|
502
|
-
this._traceProcessor.subscriptions.delete(subscription);
|
|
503
|
-
});
|
|
504
|
-
flushEvents(null, null, null);
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
};
|
|
508
|
-
|
|
509
328
|
// src/weak-ref.ts
|
|
510
329
|
var WeakRefMock = class {
|
|
511
330
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
|
@@ -540,35 +359,56 @@ var ResourceEntry = class {
|
|
|
540
359
|
}
|
|
541
360
|
};
|
|
542
361
|
var MAX_RESOURCE_RECORDS = 2e3;
|
|
543
|
-
var MAX_SPAN_RECORDS = 1e3;
|
|
544
362
|
var MAX_LOG_RECORDS = 1e3;
|
|
545
|
-
var REFRESH_INTERVAL = 1e3;
|
|
546
363
|
var MAX_INFO_OBJECT_DEPTH = 8;
|
|
547
|
-
var IS_CLOUDFLARE_WORKERS = !!globalThis?.navigator?.userAgent?.includes("Cloudflare-Workers");
|
|
548
364
|
var TraceProcessor = class {
|
|
549
365
|
diagnostics = new DiagnosticsManager();
|
|
550
366
|
diagnosticsChannel = new DiagnosticsChannel();
|
|
551
367
|
remoteMetrics = new RemoteMetrics();
|
|
552
|
-
|
|
553
|
-
|
|
368
|
+
#bufferingBackend = new BufferingTracingBackend();
|
|
369
|
+
#activeBackend = this.#bufferingBackend;
|
|
370
|
+
/**
|
|
371
|
+
* Tracing backend. Initially a buffering backend that records spans;
|
|
372
|
+
* once the observability package sets a real backend, the buffer is drained
|
|
373
|
+
* and a thin translating wrapper is installed that resolves stale buffered
|
|
374
|
+
* parent IDs still held by in-flight {@link Context} objects.
|
|
375
|
+
*
|
|
376
|
+
* The wrapper only allocates when a `buffered-*` parent is actually encountered;
|
|
377
|
+
* the common path is a single `startsWith` check and direct passthrough.
|
|
378
|
+
*/
|
|
379
|
+
get tracingBackend() {
|
|
380
|
+
return this.#activeBackend;
|
|
381
|
+
}
|
|
382
|
+
set tracingBackend(backend) {
|
|
383
|
+
if (!backend || backend === this.#bufferingBackend) {
|
|
384
|
+
this.#bufferingBackend.clear();
|
|
385
|
+
this.#activeBackend = this.#bufferingBackend;
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const idMap = this.#bufferingBackend.drain(backend);
|
|
389
|
+
this.#activeBackend = {
|
|
390
|
+
startSpan: (options) => {
|
|
391
|
+
const parent = options.parentContext;
|
|
392
|
+
if (parent?.traceparent.startsWith(BUFFERED_PREFIX)) {
|
|
393
|
+
const translated = idMap.get(parent.traceparent);
|
|
394
|
+
if (translated) {
|
|
395
|
+
return backend.startSpan({
|
|
396
|
+
...options,
|
|
397
|
+
parentContext: translated
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return backend.startSpan(options);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
}
|
|
554
405
|
resources = /* @__PURE__ */ new Map();
|
|
555
406
|
resourceInstanceIndex = /* @__PURE__ */ new WeakMap();
|
|
556
407
|
resourceIdList = [];
|
|
557
|
-
spans = /* @__PURE__ */ new Map();
|
|
558
|
-
spanIdList = [];
|
|
559
408
|
logs = [];
|
|
560
409
|
_instanceTag = null;
|
|
561
410
|
constructor() {
|
|
562
|
-
log.addProcessor(this._logProcessor.bind(this), void 0, {
|
|
563
|
-
F: __dxlog_file3,
|
|
564
|
-
L: 104,
|
|
565
|
-
S: this,
|
|
566
|
-
C: (f, a) => f(...a)
|
|
567
|
-
});
|
|
568
|
-
if (!IS_CLOUDFLARE_WORKERS) {
|
|
569
|
-
const refreshInterval = setInterval(this.refresh.bind(this), REFRESH_INTERVAL);
|
|
570
|
-
unrefTimeout(refreshInterval);
|
|
571
|
-
}
|
|
411
|
+
log.addProcessor(this._logProcessor.bind(this), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 80, S: this });
|
|
572
412
|
if (DiagnosticsChannel.supported) {
|
|
573
413
|
this.diagnosticsChannel.serve(this.diagnostics);
|
|
574
414
|
}
|
|
@@ -578,10 +418,7 @@ var TraceProcessor = class {
|
|
|
578
418
|
this._instanceTag = tag;
|
|
579
419
|
this.diagnostics.setInstanceTag(tag);
|
|
580
420
|
}
|
|
581
|
-
/**
|
|
582
|
-
* @internal
|
|
583
|
-
*/
|
|
584
|
-
// TODO(burdon): Comment.
|
|
421
|
+
/** @internal */
|
|
585
422
|
createTraceResource(params) {
|
|
586
423
|
const id = this.resources.size;
|
|
587
424
|
const tracingContext = getTracingContext(Object.getPrototypeOf(params.instance));
|
|
@@ -602,24 +439,10 @@ var TraceProcessor = class {
|
|
|
602
439
|
if (this.resourceIdList.length > MAX_RESOURCE_RECORDS) {
|
|
603
440
|
this._clearResources();
|
|
604
441
|
}
|
|
605
|
-
this._markResourceDirty(id);
|
|
606
|
-
}
|
|
607
|
-
createTraceSender() {
|
|
608
|
-
return new TraceSender(this);
|
|
609
|
-
}
|
|
610
|
-
traceSpan(params) {
|
|
611
|
-
const span2 = new TracingSpan(this, params);
|
|
612
|
-
this._flushSpan(span2);
|
|
613
|
-
return span2;
|
|
614
442
|
}
|
|
615
443
|
// TODO(burdon): Not implemented.
|
|
616
444
|
addLink(parent, child, opts) {
|
|
617
445
|
}
|
|
618
|
-
//
|
|
619
|
-
// Getters
|
|
620
|
-
//
|
|
621
|
-
// TODO(burdon): Define type.
|
|
622
|
-
// TODO(burdon): Reconcile with system service.
|
|
623
446
|
getDiagnostics() {
|
|
624
447
|
this.refresh();
|
|
625
448
|
return {
|
|
@@ -627,7 +450,6 @@ var TraceProcessor = class {
|
|
|
627
450
|
`${entry.sanitizedClassName}#${entry.data.instanceId}`,
|
|
628
451
|
entry.data
|
|
629
452
|
])),
|
|
630
|
-
spans: Array.from(this.spans.values()),
|
|
631
453
|
logs: this.logs.filter((log2) => log2.level >= LogLevel.INFO)
|
|
632
454
|
};
|
|
633
455
|
}
|
|
@@ -682,43 +504,8 @@ var TraceProcessor = class {
|
|
|
682
504
|
for (const key of Object.keys(tracingContext.metricsProperties)) {
|
|
683
505
|
instance[key]._tick?.(time);
|
|
684
506
|
}
|
|
685
|
-
let _changed = false;
|
|
686
|
-
const oldInfo = resource2.data.info;
|
|
687
507
|
resource2.data.info = this.getResourceInfo(instance);
|
|
688
|
-
_changed ||= !areEqualShallow(oldInfo, resource2.data.info);
|
|
689
|
-
const oldMetrics = resource2.data.metrics;
|
|
690
508
|
resource2.data.metrics = this.getResourceMetrics(instance);
|
|
691
|
-
_changed ||= !areEqualShallow(oldMetrics, resource2.data.metrics);
|
|
692
|
-
this._markResourceDirty(resource2.data.id);
|
|
693
|
-
}
|
|
694
|
-
for (const subscription of this.subscriptions) {
|
|
695
|
-
subscription.flush();
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
//
|
|
699
|
-
// Implementation
|
|
700
|
-
//
|
|
701
|
-
/**
|
|
702
|
-
* @internal
|
|
703
|
-
*/
|
|
704
|
-
_flushSpan(runtimeSpan) {
|
|
705
|
-
const span2 = runtimeSpan.serialize();
|
|
706
|
-
this.spans.set(span2.id, span2);
|
|
707
|
-
this.spanIdList.push(span2.id);
|
|
708
|
-
if (this.spanIdList.length > MAX_SPAN_RECORDS) {
|
|
709
|
-
this._clearSpans();
|
|
710
|
-
}
|
|
711
|
-
this._markSpanDirty(span2.id);
|
|
712
|
-
this.remoteTracing.flushSpan(runtimeSpan);
|
|
713
|
-
}
|
|
714
|
-
_markResourceDirty(id) {
|
|
715
|
-
for (const subscription of this.subscriptions) {
|
|
716
|
-
subscription.dirtyResources.add(id);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
_markSpanDirty(id) {
|
|
720
|
-
for (const subscription of this.subscriptions) {
|
|
721
|
-
subscription.dirtySpans.add(id);
|
|
722
509
|
}
|
|
723
510
|
}
|
|
724
511
|
_clearResources() {
|
|
@@ -727,20 +514,11 @@ var TraceProcessor = class {
|
|
|
727
514
|
this.resources.delete(id);
|
|
728
515
|
}
|
|
729
516
|
}
|
|
730
|
-
_clearSpans() {
|
|
731
|
-
while (this.spanIdList.length > MAX_SPAN_RECORDS) {
|
|
732
|
-
const id = this.spanIdList.shift();
|
|
733
|
-
this.spans.delete(id);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
517
|
_pushLog(log2) {
|
|
737
518
|
this.logs.push(log2);
|
|
738
519
|
if (this.logs.length > MAX_LOG_RECORDS) {
|
|
739
520
|
this.logs.shift();
|
|
740
521
|
}
|
|
741
|
-
for (const subscription of this.subscriptions) {
|
|
742
|
-
subscription.newLogs.push(log2);
|
|
743
|
-
}
|
|
744
522
|
}
|
|
745
523
|
_logProcessor = (config, entry) => {
|
|
746
524
|
switch (entry.level) {
|
|
@@ -752,18 +530,21 @@ var TraceProcessor = class {
|
|
|
752
530
|
if (!resource2) {
|
|
753
531
|
return;
|
|
754
532
|
}
|
|
755
|
-
const context =
|
|
756
|
-
|
|
757
|
-
|
|
533
|
+
const context = {
|
|
534
|
+
...entry.computedContext
|
|
535
|
+
};
|
|
536
|
+
if (entry.computedError !== void 0) {
|
|
537
|
+
context.error = entry.computedError;
|
|
758
538
|
}
|
|
539
|
+
const { filename, line } = entry.computedMeta;
|
|
759
540
|
const entryToPush = {
|
|
760
541
|
level: entry.level,
|
|
761
|
-
message: entry.message ??
|
|
542
|
+
message: entry.message ?? entry.computedError ?? "",
|
|
762
543
|
context,
|
|
763
|
-
timestamp:
|
|
544
|
+
timestamp: new Date(entry.timestamp),
|
|
764
545
|
meta: {
|
|
765
|
-
file:
|
|
766
|
-
line:
|
|
546
|
+
file: filename ?? "",
|
|
547
|
+
line: line ?? 0,
|
|
767
548
|
resourceId: resource2.data.id
|
|
768
549
|
}
|
|
769
550
|
};
|
|
@@ -774,108 +555,6 @@ var TraceProcessor = class {
|
|
|
774
555
|
}
|
|
775
556
|
};
|
|
776
557
|
};
|
|
777
|
-
var TracingSpan = class _TracingSpan {
|
|
778
|
-
_traceProcessor;
|
|
779
|
-
static nextId = 0;
|
|
780
|
-
id;
|
|
781
|
-
parentId = null;
|
|
782
|
-
methodName;
|
|
783
|
-
resourceId = null;
|
|
784
|
-
op;
|
|
785
|
-
attributes;
|
|
786
|
-
startTs;
|
|
787
|
-
endTs = null;
|
|
788
|
-
error = null;
|
|
789
|
-
_showInBrowserTimeline;
|
|
790
|
-
_showInRemoteTracing;
|
|
791
|
-
_ctx;
|
|
792
|
-
constructor(_traceProcessor, params) {
|
|
793
|
-
this._traceProcessor = _traceProcessor;
|
|
794
|
-
this.id = _TracingSpan.nextId++;
|
|
795
|
-
this.methodName = params.methodName;
|
|
796
|
-
this.resourceId = _traceProcessor.getResourceId(params.instance);
|
|
797
|
-
this.startTs = performance.now();
|
|
798
|
-
this._showInBrowserTimeline = params.showInBrowserTimeline;
|
|
799
|
-
this._showInRemoteTracing = params.showInRemoteTracing ?? true;
|
|
800
|
-
this.op = params.op;
|
|
801
|
-
this.attributes = params.attributes ?? {};
|
|
802
|
-
const baseCtx = params.parentCtx ?? new Context2(void 0, {
|
|
803
|
-
F: __dxlog_file3,
|
|
804
|
-
L: 397
|
|
805
|
-
});
|
|
806
|
-
this._ctx = this._showInRemoteTracing ? baseCtx.derive({
|
|
807
|
-
attributes: {
|
|
808
|
-
[TRACE_SPAN_ATTRIBUTE]: this.id
|
|
809
|
-
}
|
|
810
|
-
}) : baseCtx.derive();
|
|
811
|
-
if (params.parentCtx) {
|
|
812
|
-
const parentId = params.parentCtx.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
813
|
-
if (typeof parentId === "number") {
|
|
814
|
-
this.parentId = parentId;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
get name() {
|
|
819
|
-
const resource2 = this._traceProcessor.resources.get(this.resourceId);
|
|
820
|
-
return resource2 ? `${resource2.sanitizedClassName}#${resource2.data.instanceId}.${this.methodName}` : this.methodName;
|
|
821
|
-
}
|
|
822
|
-
/** Sanitized class name of the owning resource, if available. */
|
|
823
|
-
get sanitizedClassName() {
|
|
824
|
-
const resource2 = this.resourceId != null ? this._traceProcessor.resources.get(this.resourceId) : void 0;
|
|
825
|
-
return resource2?.sanitizedClassName;
|
|
826
|
-
}
|
|
827
|
-
get ctx() {
|
|
828
|
-
return this._ctx;
|
|
829
|
-
}
|
|
830
|
-
get showInRemoteTracing() {
|
|
831
|
-
return this._showInRemoteTracing;
|
|
832
|
-
}
|
|
833
|
-
markSuccess() {
|
|
834
|
-
this.endTs = performance.now();
|
|
835
|
-
this._traceProcessor._flushSpan(this);
|
|
836
|
-
if (this._showInBrowserTimeline) {
|
|
837
|
-
this._markInBrowserTimeline();
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
markError(err) {
|
|
841
|
-
this.endTs = performance.now();
|
|
842
|
-
this.error = serializeError(err);
|
|
843
|
-
this._traceProcessor._flushSpan(this);
|
|
844
|
-
if (this._showInBrowserTimeline) {
|
|
845
|
-
this._markInBrowserTimeline();
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
serialize() {
|
|
849
|
-
return {
|
|
850
|
-
id: this.id,
|
|
851
|
-
resourceId: this.resourceId ?? void 0,
|
|
852
|
-
methodName: this.methodName,
|
|
853
|
-
parentId: this.parentId ?? void 0,
|
|
854
|
-
startTs: this.startTs.toFixed(3),
|
|
855
|
-
endTs: this.endTs?.toFixed(3) ?? void 0,
|
|
856
|
-
error: this.error ?? void 0
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
_markInBrowserTimeline() {
|
|
860
|
-
if (typeof globalThis?.performance?.measure === "function") {
|
|
861
|
-
performance.measure(this.name, {
|
|
862
|
-
start: this.startTs,
|
|
863
|
-
end: this.endTs
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
};
|
|
868
|
-
var serializeError = (err) => {
|
|
869
|
-
if (err instanceof Error) {
|
|
870
|
-
return {
|
|
871
|
-
name: err.name,
|
|
872
|
-
message: err.message
|
|
873
|
-
};
|
|
874
|
-
}
|
|
875
|
-
return {
|
|
876
|
-
message: String(err)
|
|
877
|
-
};
|
|
878
|
-
};
|
|
879
558
|
var TRACE_PROCESSOR = globalThis.TRACE_PROCESSOR ??= new TraceProcessor();
|
|
880
559
|
var sanitizeValue = (value, depth, traceProcessor) => {
|
|
881
560
|
switch (typeof value) {
|
|
@@ -922,19 +601,6 @@ var sanitizeValue = (value, depth, traceProcessor) => {
|
|
|
922
601
|
return value.toString();
|
|
923
602
|
}
|
|
924
603
|
};
|
|
925
|
-
var areEqualShallow = (a, b) => {
|
|
926
|
-
for (const key in a) {
|
|
927
|
-
if (!(key in b) || a[key] !== b[key]) {
|
|
928
|
-
return false;
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
for (const key in b) {
|
|
932
|
-
if (!(key in a) || a[key] !== b[key]) {
|
|
933
|
-
return false;
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
return true;
|
|
937
|
-
};
|
|
938
604
|
var sanitizeClassName = (className) => {
|
|
939
605
|
let name = className.replace(/^_+/, "");
|
|
940
606
|
const SANITIZE_REGEX = /[^_](\d+)$/;
|
|
@@ -948,7 +614,33 @@ var isSetLike = (value) => value instanceof Set || typeof value === "object" &&
|
|
|
948
614
|
var isMapLike = (value) => value instanceof Map || typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ComplexMap";
|
|
949
615
|
|
|
950
616
|
// src/api.ts
|
|
617
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/common/tracing/src/api.ts";
|
|
618
|
+
var LIFECYCLE_SPAN = /* @__PURE__ */ Symbol("dxos.tracing.lifecycle-span");
|
|
619
|
+
var TRACE_ALL_KEY = "dxos.debug.traceAll";
|
|
620
|
+
var collectSpanAttributes = (instance, spanAttributes) => {
|
|
621
|
+
const proto = Object.getPrototypeOf(instance);
|
|
622
|
+
if (!proto) {
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
const tracingContext = getTracingContext(proto);
|
|
626
|
+
for (const [key, { options }] of Object.entries(tracingContext.infoProperties)) {
|
|
627
|
+
if (!options.spanAttribute) {
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
try {
|
|
631
|
+
const value = typeof instance[key] === "function" ? instance[key]() : instance[key];
|
|
632
|
+
if (value != null) {
|
|
633
|
+
const resolved = options.enum ? options.enum[value] : String(value);
|
|
634
|
+
spanAttributes[`ctx.${key}`] = resolved;
|
|
635
|
+
}
|
|
636
|
+
} catch {
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
};
|
|
951
640
|
var resource = (options) => (constructor) => {
|
|
641
|
+
if (options?.lifecycle && !(constructor.prototype instanceof Resource)) {
|
|
642
|
+
throw new Error(`@trace.resource({ lifecycle: true }) requires ${constructor.name} to extend Resource`);
|
|
643
|
+
}
|
|
952
644
|
const klass = /* @__PURE__ */ (() => class extends constructor {
|
|
953
645
|
constructor(...rest) {
|
|
954
646
|
super(...rest);
|
|
@@ -959,6 +651,65 @@ var resource = (options) => (constructor) => {
|
|
|
959
651
|
});
|
|
960
652
|
}
|
|
961
653
|
})();
|
|
654
|
+
if (options?.lifecycle) {
|
|
655
|
+
const sanitizedName = sanitizeClassName(constructor.name);
|
|
656
|
+
const proto = klass.prototype;
|
|
657
|
+
const originalOpen = proto.open;
|
|
658
|
+
const originalClose = proto.close;
|
|
659
|
+
proto.open = async function(ctx) {
|
|
660
|
+
const self = this;
|
|
661
|
+
if (self._lifecycleState !== LifecycleState.CLOSED) {
|
|
662
|
+
return originalOpen.call(this, ctx);
|
|
663
|
+
}
|
|
664
|
+
const parentSpanContext = ctx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
665
|
+
const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(this);
|
|
666
|
+
const spanAttributes = {};
|
|
667
|
+
if (resourceEntry) {
|
|
668
|
+
spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
|
|
669
|
+
}
|
|
670
|
+
const remoteSpan = TRACE_PROCESSOR.tracingBackend?.startSpan({
|
|
671
|
+
name: `${sanitizedName}.lifecycle`,
|
|
672
|
+
op: "lifecycle",
|
|
673
|
+
attributes: spanAttributes,
|
|
674
|
+
parentContext: parentSpanContext
|
|
675
|
+
});
|
|
676
|
+
self[LIFECYCLE_SPAN] = remoteSpan;
|
|
677
|
+
let openCtx = ctx;
|
|
678
|
+
if (remoteSpan?.spanContext != null) {
|
|
679
|
+
const traceAttrs = {
|
|
680
|
+
[TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext
|
|
681
|
+
};
|
|
682
|
+
openCtx = ctx ? ctx.derive({
|
|
683
|
+
attributes: traceAttrs
|
|
684
|
+
}) : new Context2({
|
|
685
|
+
attributes: traceAttrs
|
|
686
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 79 });
|
|
687
|
+
}
|
|
688
|
+
try {
|
|
689
|
+
return await originalOpen.call(this, openCtx);
|
|
690
|
+
} catch (err) {
|
|
691
|
+
remoteSpan?.setError?.(err);
|
|
692
|
+
remoteSpan?.end();
|
|
693
|
+
self[LIFECYCLE_SPAN] = void 0;
|
|
694
|
+
throw err;
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
proto.close = async function(ctx) {
|
|
698
|
+
const self = this;
|
|
699
|
+
const remoteSpan = self[LIFECYCLE_SPAN];
|
|
700
|
+
try {
|
|
701
|
+
return await originalClose.call(this, ctx);
|
|
702
|
+
} catch (err) {
|
|
703
|
+
remoteSpan?.setError?.(err);
|
|
704
|
+
throw err;
|
|
705
|
+
} finally {
|
|
706
|
+
if (remoteSpan) {
|
|
707
|
+
remoteSpan.end();
|
|
708
|
+
self[LIFECYCLE_SPAN] = void 0;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
}
|
|
962
713
|
Object.defineProperty(klass, "name", {
|
|
963
714
|
value: constructor.name
|
|
964
715
|
});
|
|
@@ -975,45 +726,114 @@ var mark = (name) => {
|
|
|
975
726
|
var span = ({ showInBrowserTimeline = false, showInRemoteTracing = true, op, attributes } = {}) => (target, propertyKey, descriptor) => {
|
|
976
727
|
const method = descriptor.value;
|
|
977
728
|
descriptor.value = async function(...args) {
|
|
978
|
-
const
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
return TRACE_PROCESSOR.remoteTracing.wrapExecution(span2, async () => {
|
|
993
|
-
try {
|
|
994
|
-
return await method.apply(this, callArgs);
|
|
995
|
-
} catch (err) {
|
|
996
|
-
span2.markError(err);
|
|
997
|
-
throw err;
|
|
998
|
-
} finally {
|
|
999
|
-
span2.markSuccess();
|
|
729
|
+
const parentCtx = args[0] instanceof Context2 ? args[0] : null;
|
|
730
|
+
const startTs = performance.now();
|
|
731
|
+
const parentSpanContext = parentCtx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
732
|
+
const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(this);
|
|
733
|
+
const className = resourceEntry?.sanitizedClassName ?? sanitizeClassName(target.constructor?.name ?? "unknown");
|
|
734
|
+
const spanName = `${className}.${propertyKey}`;
|
|
735
|
+
const spanAttributes = {};
|
|
736
|
+
if (resourceEntry) {
|
|
737
|
+
spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
|
|
738
|
+
}
|
|
739
|
+
collectSpanAttributes(this, spanAttributes);
|
|
740
|
+
if (attributes) {
|
|
741
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
742
|
+
spanAttributes[key.startsWith("ctx.") ? key : `ctx.${key}`] = value;
|
|
1000
743
|
}
|
|
1001
|
-
}
|
|
744
|
+
}
|
|
745
|
+
const remoteSpan = showInRemoteTracing ? TRACE_PROCESSOR.tracingBackend?.startSpan({
|
|
746
|
+
name: spanName,
|
|
747
|
+
op: op ?? "function",
|
|
748
|
+
attributes: spanAttributes,
|
|
749
|
+
parentContext: parentSpanContext
|
|
750
|
+
}) : void 0;
|
|
751
|
+
let callArgs = args;
|
|
752
|
+
if (parentCtx) {
|
|
753
|
+
const childCtx = remoteSpan?.spanContext != null ? parentCtx.derive({
|
|
754
|
+
attributes: {
|
|
755
|
+
[TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext
|
|
756
|
+
}
|
|
757
|
+
}) : parentCtx.derive();
|
|
758
|
+
callArgs = [
|
|
759
|
+
childCtx,
|
|
760
|
+
...args.slice(1)
|
|
761
|
+
];
|
|
762
|
+
}
|
|
763
|
+
try {
|
|
764
|
+
return await method.apply(this, callArgs);
|
|
765
|
+
} catch (err) {
|
|
766
|
+
remoteSpan?.setError?.(err);
|
|
767
|
+
throw err;
|
|
768
|
+
} finally {
|
|
769
|
+
remoteSpan?.end();
|
|
770
|
+
if (showInBrowserTimeline && typeof globalThis?.performance?.measure === "function") {
|
|
771
|
+
performance.measure(spanName, {
|
|
772
|
+
start: startTs,
|
|
773
|
+
end: performance.now()
|
|
774
|
+
});
|
|
775
|
+
}
|
|
776
|
+
}
|
|
1002
777
|
};
|
|
1003
778
|
};
|
|
1004
|
-
var
|
|
779
|
+
var manualSpans = /* @__PURE__ */ new Map();
|
|
780
|
+
var manualSpanTimestamps = /* @__PURE__ */ new Map();
|
|
1005
781
|
var spanStart = (params) => {
|
|
1006
|
-
if (
|
|
1007
|
-
return;
|
|
782
|
+
if (manualSpans.has(params.id) || manualSpanTimestamps.has(params.id)) {
|
|
783
|
+
return params.parentCtx;
|
|
784
|
+
}
|
|
785
|
+
const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(params.instance);
|
|
786
|
+
const className = resourceEntry?.sanitizedClassName ?? "unknown";
|
|
787
|
+
const spanName = `${className}.${params.methodName}`;
|
|
788
|
+
if (params.showInBrowserTimeline) {
|
|
789
|
+
manualSpanTimestamps.set(params.id, {
|
|
790
|
+
name: spanName,
|
|
791
|
+
startTs: performance.now()
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
if (params.showInRemoteTracing === false || !TRACE_PROCESSOR.tracingBackend) {
|
|
795
|
+
return params.parentCtx;
|
|
796
|
+
}
|
|
797
|
+
const parentSpanContext = params.parentCtx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
798
|
+
const spanAttributes = {};
|
|
799
|
+
if (resourceEntry) {
|
|
800
|
+
spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
|
|
801
|
+
}
|
|
802
|
+
collectSpanAttributes(params.instance, spanAttributes);
|
|
803
|
+
if (params.attributes) {
|
|
804
|
+
for (const [key, value] of Object.entries(params.attributes)) {
|
|
805
|
+
spanAttributes[key.startsWith("ctx.") ? key : `ctx.${key}`] = value;
|
|
806
|
+
}
|
|
1008
807
|
}
|
|
1009
|
-
const
|
|
1010
|
-
|
|
808
|
+
const remoteSpan = TRACE_PROCESSOR.tracingBackend.startSpan({
|
|
809
|
+
name: spanName,
|
|
810
|
+
op: params.op ?? "function",
|
|
811
|
+
attributes: spanAttributes,
|
|
812
|
+
parentContext: parentSpanContext
|
|
813
|
+
});
|
|
814
|
+
manualSpans.set(params.id, remoteSpan);
|
|
815
|
+
if (params.parentCtx && remoteSpan.spanContext != null) {
|
|
816
|
+
return params.parentCtx.derive({
|
|
817
|
+
attributes: {
|
|
818
|
+
[TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext
|
|
819
|
+
}
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
return params.parentCtx;
|
|
1011
823
|
};
|
|
1012
824
|
var spanEnd = (id) => {
|
|
1013
|
-
const
|
|
1014
|
-
if (
|
|
1015
|
-
|
|
1016
|
-
|
|
825
|
+
const remoteSpan = manualSpans.get(id);
|
|
826
|
+
if (remoteSpan) {
|
|
827
|
+
remoteSpan.end();
|
|
828
|
+
manualSpans.delete(id);
|
|
829
|
+
}
|
|
830
|
+
const timestamps = manualSpanTimestamps.get(id);
|
|
831
|
+
if (timestamps && typeof globalThis?.performance?.measure === "function") {
|
|
832
|
+
performance.measure(timestamps.name, {
|
|
833
|
+
start: timestamps.startTs,
|
|
834
|
+
end: performance.now()
|
|
835
|
+
});
|
|
836
|
+
manualSpanTimestamps.delete(id);
|
|
1017
837
|
}
|
|
1018
838
|
};
|
|
1019
839
|
var metricsCounter = () => (target, propertyKey, descriptor) => {
|
|
@@ -1231,16 +1051,13 @@ export {
|
|
|
1231
1051
|
DiagnosticsManager,
|
|
1232
1052
|
MapCounter,
|
|
1233
1053
|
RemoteMetrics,
|
|
1234
|
-
RemoteTracing,
|
|
1235
1054
|
ResourceEntry,
|
|
1055
|
+
TRACE_ALL_KEY,
|
|
1236
1056
|
TRACE_PROCESSOR,
|
|
1237
|
-
TRACE_SPAN_ATTRIBUTE,
|
|
1238
1057
|
TimeSeriesCounter,
|
|
1239
1058
|
TimeUsageCounter,
|
|
1240
1059
|
TraceDiagnosticImpl,
|
|
1241
1060
|
TraceProcessor,
|
|
1242
|
-
TraceSender,
|
|
1243
|
-
TracingSpan,
|
|
1244
1061
|
UnaryCounter,
|
|
1245
1062
|
getTracingContext,
|
|
1246
1063
|
sanitizeClassName,
|