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