@dxos/tracing 0.8.4-main.fffef41 → 0.8.4-staging.ac66bdf99f
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 +328 -339
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +328 -339
- 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 +36 -17
- 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 +2 -2
- package/dist/types/src/diagnostic.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/remote/index.d.ts +0 -1
- package/dist/types/src/remote/index.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 +16 -52
- 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 +13 -9
- package/src/api.ts +237 -35
- package/src/buffering-backend.ts +112 -0
- package/src/diagnostic.ts +2 -2
- package/src/index.ts +1 -2
- package/src/remote/index.ts +0 -1
- package/src/symbols.ts +0 -2
- package/src/trace-processor.ts +58 -258
- package/src/tracing-types.ts +77 -0
- package/src/tracing.test.ts +513 -4
- package/dist/types/src/remote/tracing.d.ts +0 -23
- 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 -53
- package/src/trace-sender.ts +0 -88
|
@@ -1,23 +1,107 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
3
|
// src/api.ts
|
|
4
|
-
import { Context as Context2 } from "@dxos/context";
|
|
4
|
+
import { Context as Context2, LifecycleState, Resource, TRACE_SPAN_ATTRIBUTE } from "@dxos/context";
|
|
5
5
|
|
|
6
6
|
// src/symbols.ts
|
|
7
|
-
var symbolTracingContext = Symbol("dxos.tracing.context");
|
|
7
|
+
var symbolTracingContext = /* @__PURE__ */ Symbol("dxos.tracing.context");
|
|
8
8
|
var getTracingContext = (target) => {
|
|
9
9
|
return target[symbolTracingContext] ??= {
|
|
10
10
|
infoProperties: {},
|
|
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 { LogLevel, getContextFromEntry, log } from "@dxos/log";
|
|
16
|
+
import { LogLevel, log } from "@dxos/log";
|
|
19
17
|
import { getPrototypeSpecificInstanceId } from "@dxos/util";
|
|
20
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
|
+
|
|
21
105
|
// src/diagnostic.ts
|
|
22
106
|
import { asyncTimeout } from "@dxos/async";
|
|
23
107
|
import { invariant } from "@dxos/invariant";
|
|
@@ -284,124 +368,6 @@ var RemoteMetrics = class {
|
|
|
284
368
|
}
|
|
285
369
|
};
|
|
286
370
|
|
|
287
|
-
// src/remote/tracing.ts
|
|
288
|
-
var RemoteTracing = class {
|
|
289
|
-
_tracing;
|
|
290
|
-
_spanMap = /* @__PURE__ */ new Map();
|
|
291
|
-
registerProcessor(processor) {
|
|
292
|
-
this._tracing = processor;
|
|
293
|
-
}
|
|
294
|
-
flushSpan(span2) {
|
|
295
|
-
if (!this._tracing) {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
if (!span2.endTs) {
|
|
299
|
-
const remoteSpan = this._tracing.startSpan({
|
|
300
|
-
name: span2.methodName,
|
|
301
|
-
op: span2.op ?? "function",
|
|
302
|
-
attributes: span2.attributes
|
|
303
|
-
});
|
|
304
|
-
this._spanMap.set(span2, remoteSpan);
|
|
305
|
-
} else {
|
|
306
|
-
const remoteSpan = this._spanMap.get(span2);
|
|
307
|
-
if (remoteSpan) {
|
|
308
|
-
remoteSpan.end();
|
|
309
|
-
this._spanMap.delete(span2);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
// src/trace-sender.ts
|
|
316
|
-
import { Stream } from "@dxos/codec-protobuf/stream";
|
|
317
|
-
var TraceSender = class {
|
|
318
|
-
_traceProcessor;
|
|
319
|
-
constructor(_traceProcessor) {
|
|
320
|
-
this._traceProcessor = _traceProcessor;
|
|
321
|
-
}
|
|
322
|
-
streamTrace(request) {
|
|
323
|
-
return new Stream(({ ctx, next }) => {
|
|
324
|
-
const flushEvents = (resources, spans2, logs) => {
|
|
325
|
-
const event = {
|
|
326
|
-
resourceAdded: [],
|
|
327
|
-
resourceRemoved: [],
|
|
328
|
-
spanAdded: [],
|
|
329
|
-
logAdded: []
|
|
330
|
-
};
|
|
331
|
-
if (resources) {
|
|
332
|
-
for (const id of resources) {
|
|
333
|
-
const entry = this._traceProcessor.resources.get(id);
|
|
334
|
-
if (entry) {
|
|
335
|
-
event.resourceAdded.push({
|
|
336
|
-
resource: entry.data
|
|
337
|
-
});
|
|
338
|
-
} else {
|
|
339
|
-
event.resourceRemoved.push({
|
|
340
|
-
id
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
} else {
|
|
345
|
-
for (const entry of this._traceProcessor.resources.values()) {
|
|
346
|
-
event.resourceAdded.push({
|
|
347
|
-
resource: entry.data
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
if (spans2) {
|
|
352
|
-
for (const id of spans2) {
|
|
353
|
-
const span2 = this._traceProcessor.spans.get(id);
|
|
354
|
-
if (span2) {
|
|
355
|
-
event.spanAdded.push({
|
|
356
|
-
span: span2
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
} else {
|
|
361
|
-
for (const span2 of this._traceProcessor.spans.values()) {
|
|
362
|
-
event.spanAdded.push({
|
|
363
|
-
span: span2
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
if (logs) {
|
|
368
|
-
for (const log2 of logs) {
|
|
369
|
-
event.logAdded.push({
|
|
370
|
-
log: log2
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
} else {
|
|
374
|
-
for (const log2 of this._traceProcessor.logs) {
|
|
375
|
-
event.logAdded.push({
|
|
376
|
-
log: log2
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
if (event.resourceAdded.length > 0 || event.resourceRemoved.length > 0 || event.spanAdded.length > 0) {
|
|
381
|
-
next(event);
|
|
382
|
-
}
|
|
383
|
-
};
|
|
384
|
-
const flush = () => {
|
|
385
|
-
flushEvents(subscription.dirtyResources, subscription.dirtySpans, subscription.newLogs);
|
|
386
|
-
subscription.dirtyResources.clear();
|
|
387
|
-
subscription.dirtySpans.clear();
|
|
388
|
-
subscription.newLogs.length = 0;
|
|
389
|
-
};
|
|
390
|
-
const subscription = {
|
|
391
|
-
flush,
|
|
392
|
-
dirtyResources: /* @__PURE__ */ new Set(),
|
|
393
|
-
dirtySpans: /* @__PURE__ */ new Set(),
|
|
394
|
-
newLogs: []
|
|
395
|
-
};
|
|
396
|
-
this._traceProcessor.subscriptions.add(subscription);
|
|
397
|
-
ctx.onDispose(() => {
|
|
398
|
-
this._traceProcessor.subscriptions.delete(subscription);
|
|
399
|
-
});
|
|
400
|
-
flushEvents(null, null, null);
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
};
|
|
404
|
-
|
|
405
371
|
// src/weak-ref.ts
|
|
406
372
|
var WeakRefMock = class {
|
|
407
373
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
|
@@ -436,35 +402,61 @@ var ResourceEntry = class {
|
|
|
436
402
|
}
|
|
437
403
|
};
|
|
438
404
|
var MAX_RESOURCE_RECORDS = 2e3;
|
|
439
|
-
var MAX_SPAN_RECORDS = 1e3;
|
|
440
405
|
var MAX_LOG_RECORDS = 1e3;
|
|
441
|
-
var REFRESH_INTERVAL = 1e3;
|
|
442
406
|
var MAX_INFO_OBJECT_DEPTH = 8;
|
|
443
|
-
var IS_CLOUDFLARE_WORKERS = !!globalThis?.navigator?.userAgent?.includes("Cloudflare-Workers");
|
|
444
407
|
var TraceProcessor = class {
|
|
445
408
|
diagnostics = new DiagnosticsManager();
|
|
446
409
|
diagnosticsChannel = new DiagnosticsChannel();
|
|
447
410
|
remoteMetrics = new RemoteMetrics();
|
|
448
|
-
|
|
449
|
-
|
|
411
|
+
#bufferingBackend = new BufferingTracingBackend();
|
|
412
|
+
#activeBackend = this.#bufferingBackend;
|
|
413
|
+
/**
|
|
414
|
+
* Tracing backend. Initially a buffering backend that records spans;
|
|
415
|
+
* once the observability package sets a real backend, the buffer is drained
|
|
416
|
+
* and a thin translating wrapper is installed that resolves stale buffered
|
|
417
|
+
* parent IDs still held by in-flight {@link Context} objects.
|
|
418
|
+
*
|
|
419
|
+
* The wrapper only allocates when a `buffered-*` parent is actually encountered;
|
|
420
|
+
* the common path is a single `startsWith` check and direct passthrough.
|
|
421
|
+
*/
|
|
422
|
+
get tracingBackend() {
|
|
423
|
+
return this.#activeBackend;
|
|
424
|
+
}
|
|
425
|
+
set tracingBackend(backend) {
|
|
426
|
+
if (!backend || backend === this.#bufferingBackend) {
|
|
427
|
+
this.#bufferingBackend.clear();
|
|
428
|
+
this.#activeBackend = this.#bufferingBackend;
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
const idMap = this.#bufferingBackend.drain(backend);
|
|
432
|
+
this.#activeBackend = {
|
|
433
|
+
startSpan: (options) => {
|
|
434
|
+
const parent = options.parentContext;
|
|
435
|
+
if (parent?.traceparent.startsWith(BUFFERED_PREFIX)) {
|
|
436
|
+
const translated = idMap.get(parent.traceparent);
|
|
437
|
+
if (translated) {
|
|
438
|
+
return backend.startSpan({
|
|
439
|
+
...options,
|
|
440
|
+
parentContext: translated
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return backend.startSpan(options);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}
|
|
450
448
|
resources = /* @__PURE__ */ new Map();
|
|
451
449
|
resourceInstanceIndex = /* @__PURE__ */ new WeakMap();
|
|
452
450
|
resourceIdList = [];
|
|
453
|
-
spans = /* @__PURE__ */ new Map();
|
|
454
|
-
spanIdList = [];
|
|
455
451
|
logs = [];
|
|
456
452
|
_instanceTag = null;
|
|
457
453
|
constructor() {
|
|
458
454
|
log.addProcessor(this._logProcessor.bind(this), void 0, {
|
|
459
455
|
F: __dxlog_file3,
|
|
460
|
-
L:
|
|
456
|
+
L: 108,
|
|
461
457
|
S: this,
|
|
462
458
|
C: (f, a) => f(...a)
|
|
463
459
|
});
|
|
464
|
-
if (!IS_CLOUDFLARE_WORKERS) {
|
|
465
|
-
const refreshInterval = setInterval(this.refresh.bind(this), REFRESH_INTERVAL);
|
|
466
|
-
unrefTimeout(refreshInterval);
|
|
467
|
-
}
|
|
468
460
|
if (DiagnosticsChannel.supported) {
|
|
469
461
|
this.diagnosticsChannel.serve(this.diagnostics);
|
|
470
462
|
}
|
|
@@ -474,10 +466,7 @@ var TraceProcessor = class {
|
|
|
474
466
|
this._instanceTag = tag;
|
|
475
467
|
this.diagnostics.setInstanceTag(tag);
|
|
476
468
|
}
|
|
477
|
-
/**
|
|
478
|
-
* @internal
|
|
479
|
-
*/
|
|
480
|
-
// TODO(burdon): Comment.
|
|
469
|
+
/** @internal */
|
|
481
470
|
createTraceResource(params) {
|
|
482
471
|
const id = this.resources.size;
|
|
483
472
|
const tracingContext = getTracingContext(Object.getPrototypeOf(params.instance));
|
|
@@ -498,24 +487,10 @@ var TraceProcessor = class {
|
|
|
498
487
|
if (this.resourceIdList.length > MAX_RESOURCE_RECORDS) {
|
|
499
488
|
this._clearResources();
|
|
500
489
|
}
|
|
501
|
-
this._markResourceDirty(id);
|
|
502
|
-
}
|
|
503
|
-
createTraceSender() {
|
|
504
|
-
return new TraceSender(this);
|
|
505
|
-
}
|
|
506
|
-
traceSpan(params) {
|
|
507
|
-
const span2 = new TracingSpan(this, params);
|
|
508
|
-
this._flushSpan(span2);
|
|
509
|
-
return span2;
|
|
510
490
|
}
|
|
511
491
|
// TODO(burdon): Not implemented.
|
|
512
492
|
addLink(parent, child, opts) {
|
|
513
493
|
}
|
|
514
|
-
//
|
|
515
|
-
// Getters
|
|
516
|
-
//
|
|
517
|
-
// TODO(burdon): Define type.
|
|
518
|
-
// TODO(burdon): Reconcile with system service.
|
|
519
494
|
getDiagnostics() {
|
|
520
495
|
this.refresh();
|
|
521
496
|
return {
|
|
@@ -523,7 +498,6 @@ var TraceProcessor = class {
|
|
|
523
498
|
`${entry.sanitizedClassName}#${entry.data.instanceId}`,
|
|
524
499
|
entry.data
|
|
525
500
|
])),
|
|
526
|
-
spans: Array.from(this.spans.values()),
|
|
527
501
|
logs: this.logs.filter((log2) => log2.level >= LogLevel.INFO)
|
|
528
502
|
};
|
|
529
503
|
}
|
|
@@ -578,43 +552,8 @@ var TraceProcessor = class {
|
|
|
578
552
|
for (const key of Object.keys(tracingContext.metricsProperties)) {
|
|
579
553
|
instance[key]._tick?.(time);
|
|
580
554
|
}
|
|
581
|
-
let _changed = false;
|
|
582
|
-
const oldInfo = resource2.data.info;
|
|
583
555
|
resource2.data.info = this.getResourceInfo(instance);
|
|
584
|
-
_changed ||= !areEqualShallow(oldInfo, resource2.data.info);
|
|
585
|
-
const oldMetrics = resource2.data.metrics;
|
|
586
556
|
resource2.data.metrics = this.getResourceMetrics(instance);
|
|
587
|
-
_changed ||= !areEqualShallow(oldMetrics, resource2.data.metrics);
|
|
588
|
-
this._markResourceDirty(resource2.data.id);
|
|
589
|
-
}
|
|
590
|
-
for (const subscription of this.subscriptions) {
|
|
591
|
-
subscription.flush();
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
//
|
|
595
|
-
// Implementation
|
|
596
|
-
//
|
|
597
|
-
/**
|
|
598
|
-
* @internal
|
|
599
|
-
*/
|
|
600
|
-
_flushSpan(runtimeSpan) {
|
|
601
|
-
const span2 = runtimeSpan.serialize();
|
|
602
|
-
this.spans.set(span2.id, span2);
|
|
603
|
-
this.spanIdList.push(span2.id);
|
|
604
|
-
if (this.spanIdList.length > MAX_SPAN_RECORDS) {
|
|
605
|
-
this._clearSpans();
|
|
606
|
-
}
|
|
607
|
-
this._markSpanDirty(span2.id);
|
|
608
|
-
this.remoteTracing.flushSpan(runtimeSpan);
|
|
609
|
-
}
|
|
610
|
-
_markResourceDirty(id) {
|
|
611
|
-
for (const subscription of this.subscriptions) {
|
|
612
|
-
subscription.dirtyResources.add(id);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
_markSpanDirty(id) {
|
|
616
|
-
for (const subscription of this.subscriptions) {
|
|
617
|
-
subscription.dirtySpans.add(id);
|
|
618
557
|
}
|
|
619
558
|
}
|
|
620
559
|
_clearResources() {
|
|
@@ -623,20 +562,11 @@ var TraceProcessor = class {
|
|
|
623
562
|
this.resources.delete(id);
|
|
624
563
|
}
|
|
625
564
|
}
|
|
626
|
-
_clearSpans() {
|
|
627
|
-
while (this.spanIdList.length > MAX_SPAN_RECORDS) {
|
|
628
|
-
const id = this.spanIdList.shift();
|
|
629
|
-
this.spans.delete(id);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
565
|
_pushLog(log2) {
|
|
633
566
|
this.logs.push(log2);
|
|
634
567
|
if (this.logs.length > MAX_LOG_RECORDS) {
|
|
635
568
|
this.logs.shift();
|
|
636
569
|
}
|
|
637
|
-
for (const subscription of this.subscriptions) {
|
|
638
|
-
subscription.newLogs.push(log2);
|
|
639
|
-
}
|
|
640
570
|
}
|
|
641
571
|
_logProcessor = (config, entry) => {
|
|
642
572
|
switch (entry.level) {
|
|
@@ -648,18 +578,21 @@ var TraceProcessor = class {
|
|
|
648
578
|
if (!resource2) {
|
|
649
579
|
return;
|
|
650
580
|
}
|
|
651
|
-
const context =
|
|
652
|
-
|
|
653
|
-
|
|
581
|
+
const context = {
|
|
582
|
+
...entry.computedContext
|
|
583
|
+
};
|
|
584
|
+
if (entry.computedError !== void 0) {
|
|
585
|
+
context.error = entry.computedError;
|
|
654
586
|
}
|
|
587
|
+
const { filename, line } = entry.computedMeta;
|
|
655
588
|
const entryToPush = {
|
|
656
589
|
level: entry.level,
|
|
657
|
-
message: entry.message ??
|
|
590
|
+
message: entry.message ?? entry.computedError ?? "",
|
|
658
591
|
context,
|
|
659
|
-
timestamp:
|
|
592
|
+
timestamp: new Date(entry.timestamp),
|
|
660
593
|
meta: {
|
|
661
|
-
file:
|
|
662
|
-
line:
|
|
594
|
+
file: filename ?? "",
|
|
595
|
+
line: line ?? 0,
|
|
663
596
|
resourceId: resource2.data.id
|
|
664
597
|
}
|
|
665
598
|
};
|
|
@@ -670,94 +603,6 @@ var TraceProcessor = class {
|
|
|
670
603
|
}
|
|
671
604
|
};
|
|
672
605
|
};
|
|
673
|
-
var TracingSpan = class _TracingSpan {
|
|
674
|
-
_traceProcessor;
|
|
675
|
-
static nextId = 0;
|
|
676
|
-
id;
|
|
677
|
-
parentId = null;
|
|
678
|
-
methodName;
|
|
679
|
-
resourceId = null;
|
|
680
|
-
op;
|
|
681
|
-
attributes;
|
|
682
|
-
startTs;
|
|
683
|
-
endTs = null;
|
|
684
|
-
error = null;
|
|
685
|
-
_showInBrowserTimeline;
|
|
686
|
-
_ctx = null;
|
|
687
|
-
constructor(_traceProcessor, params) {
|
|
688
|
-
this._traceProcessor = _traceProcessor;
|
|
689
|
-
this.id = _TracingSpan.nextId++;
|
|
690
|
-
this.methodName = params.methodName;
|
|
691
|
-
this.resourceId = _traceProcessor.getResourceId(params.instance);
|
|
692
|
-
this.startTs = performance.now();
|
|
693
|
-
this._showInBrowserTimeline = params.showInBrowserTimeline;
|
|
694
|
-
this.op = params.op;
|
|
695
|
-
this.attributes = params.attributes ?? {};
|
|
696
|
-
if (params.parentCtx) {
|
|
697
|
-
this._ctx = params.parentCtx.derive({
|
|
698
|
-
attributes: {
|
|
699
|
-
[TRACE_SPAN_ATTRIBUTE]: this.id
|
|
700
|
-
}
|
|
701
|
-
});
|
|
702
|
-
const parentId = params.parentCtx.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
703
|
-
if (typeof parentId === "number") {
|
|
704
|
-
this.parentId = parentId;
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
get name() {
|
|
709
|
-
const resource2 = this._traceProcessor.resources.get(this.resourceId);
|
|
710
|
-
return resource2 ? `${resource2.sanitizedClassName}#${resource2.data.instanceId}.${this.methodName}` : this.methodName;
|
|
711
|
-
}
|
|
712
|
-
get ctx() {
|
|
713
|
-
return this._ctx;
|
|
714
|
-
}
|
|
715
|
-
markSuccess() {
|
|
716
|
-
this.endTs = performance.now();
|
|
717
|
-
this._traceProcessor._flushSpan(this);
|
|
718
|
-
if (this._showInBrowserTimeline) {
|
|
719
|
-
this._markInBrowserTimeline();
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
markError(err) {
|
|
723
|
-
this.endTs = performance.now();
|
|
724
|
-
this.error = serializeError(err);
|
|
725
|
-
this._traceProcessor._flushSpan(this);
|
|
726
|
-
if (this._showInBrowserTimeline) {
|
|
727
|
-
this._markInBrowserTimeline();
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
serialize() {
|
|
731
|
-
return {
|
|
732
|
-
id: this.id,
|
|
733
|
-
resourceId: this.resourceId ?? void 0,
|
|
734
|
-
methodName: this.methodName,
|
|
735
|
-
parentId: this.parentId ?? void 0,
|
|
736
|
-
startTs: this.startTs.toFixed(3),
|
|
737
|
-
endTs: this.endTs?.toFixed(3) ?? void 0,
|
|
738
|
-
error: this.error ?? void 0
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
_markInBrowserTimeline() {
|
|
742
|
-
if (typeof globalThis?.performance?.measure === "function") {
|
|
743
|
-
performance.measure(this.name, {
|
|
744
|
-
start: this.startTs,
|
|
745
|
-
end: this.endTs
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
var serializeError = (err) => {
|
|
751
|
-
if (err instanceof Error) {
|
|
752
|
-
return {
|
|
753
|
-
name: err.name,
|
|
754
|
-
message: err.message
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
return {
|
|
758
|
-
message: String(err)
|
|
759
|
-
};
|
|
760
|
-
};
|
|
761
606
|
var TRACE_PROCESSOR = globalThis.TRACE_PROCESSOR ??= new TraceProcessor();
|
|
762
607
|
var sanitizeValue = (value, depth, traceProcessor) => {
|
|
763
608
|
switch (typeof value) {
|
|
@@ -804,33 +649,46 @@ var sanitizeValue = (value, depth, traceProcessor) => {
|
|
|
804
649
|
return value.toString();
|
|
805
650
|
}
|
|
806
651
|
};
|
|
807
|
-
var areEqualShallow = (a, b) => {
|
|
808
|
-
for (const key in a) {
|
|
809
|
-
if (!(key in b) || a[key] !== b[key]) {
|
|
810
|
-
return false;
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
for (const key in b) {
|
|
814
|
-
if (!(key in a) || a[key] !== b[key]) {
|
|
815
|
-
return false;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
return true;
|
|
819
|
-
};
|
|
820
652
|
var sanitizeClassName = (className) => {
|
|
653
|
+
let name = className.replace(/^_+/, "");
|
|
821
654
|
const SANITIZE_REGEX = /[^_](\d+)$/;
|
|
822
|
-
const m =
|
|
823
|
-
if (
|
|
824
|
-
|
|
825
|
-
} else {
|
|
826
|
-
return className.slice(0, -m[1].length);
|
|
655
|
+
const m = name.match(SANITIZE_REGEX);
|
|
656
|
+
if (m) {
|
|
657
|
+
name = name.slice(0, -m[1].length);
|
|
827
658
|
}
|
|
659
|
+
return name;
|
|
828
660
|
};
|
|
829
661
|
var isSetLike = (value) => value instanceof Set || typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ComplexSet";
|
|
830
662
|
var isMapLike = (value) => value instanceof Map || typeof value === "object" && value !== null && Object.getPrototypeOf(value).constructor.name === "ComplexMap";
|
|
831
663
|
|
|
832
664
|
// src/api.ts
|
|
665
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/common/tracing/src/api.ts";
|
|
666
|
+
var LIFECYCLE_SPAN = /* @__PURE__ */ Symbol("dxos.tracing.lifecycle-span");
|
|
667
|
+
var TRACE_ALL_KEY = "dxos.debug.traceAll";
|
|
668
|
+
var collectSpanAttributes = (instance, spanAttributes) => {
|
|
669
|
+
const proto = Object.getPrototypeOf(instance);
|
|
670
|
+
if (!proto) {
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
const tracingContext = getTracingContext(proto);
|
|
674
|
+
for (const [key, { options }] of Object.entries(tracingContext.infoProperties)) {
|
|
675
|
+
if (!options.spanAttribute) {
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
try {
|
|
679
|
+
const value = typeof instance[key] === "function" ? instance[key]() : instance[key];
|
|
680
|
+
if (value != null) {
|
|
681
|
+
const resolved = options.enum ? options.enum[value] : String(value);
|
|
682
|
+
spanAttributes[`ctx.${key}`] = resolved;
|
|
683
|
+
}
|
|
684
|
+
} catch {
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
};
|
|
833
688
|
var resource = (options) => (constructor) => {
|
|
689
|
+
if (options?.lifecycle && !(constructor.prototype instanceof Resource)) {
|
|
690
|
+
throw new Error(`@trace.resource({ lifecycle: true }) requires ${constructor.name} to extend Resource`);
|
|
691
|
+
}
|
|
834
692
|
const klass = /* @__PURE__ */ (() => class extends constructor {
|
|
835
693
|
constructor(...rest) {
|
|
836
694
|
super(...rest);
|
|
@@ -841,6 +699,68 @@ var resource = (options) => (constructor) => {
|
|
|
841
699
|
});
|
|
842
700
|
}
|
|
843
701
|
})();
|
|
702
|
+
if (options?.lifecycle) {
|
|
703
|
+
const sanitizedName = sanitizeClassName(constructor.name);
|
|
704
|
+
const proto = klass.prototype;
|
|
705
|
+
const originalOpen = proto.open;
|
|
706
|
+
const originalClose = proto.close;
|
|
707
|
+
proto.open = async function(ctx) {
|
|
708
|
+
const self = this;
|
|
709
|
+
if (self._lifecycleState !== LifecycleState.CLOSED) {
|
|
710
|
+
return originalOpen.call(this, ctx);
|
|
711
|
+
}
|
|
712
|
+
const parentSpanContext = ctx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
713
|
+
const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(this);
|
|
714
|
+
const spanAttributes = {};
|
|
715
|
+
if (resourceEntry) {
|
|
716
|
+
spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
|
|
717
|
+
}
|
|
718
|
+
const remoteSpan = TRACE_PROCESSOR.tracingBackend?.startSpan({
|
|
719
|
+
name: `${sanitizedName}.lifecycle`,
|
|
720
|
+
op: "lifecycle",
|
|
721
|
+
attributes: spanAttributes,
|
|
722
|
+
parentContext: parentSpanContext
|
|
723
|
+
});
|
|
724
|
+
self[LIFECYCLE_SPAN] = remoteSpan;
|
|
725
|
+
let openCtx = ctx;
|
|
726
|
+
if (remoteSpan?.spanContext != null) {
|
|
727
|
+
const traceAttrs = {
|
|
728
|
+
[TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext
|
|
729
|
+
};
|
|
730
|
+
openCtx = ctx ? ctx.derive({
|
|
731
|
+
attributes: traceAttrs
|
|
732
|
+
}) : new Context2({
|
|
733
|
+
attributes: traceAttrs
|
|
734
|
+
}, {
|
|
735
|
+
F: __dxlog_file4,
|
|
736
|
+
L: 104
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
try {
|
|
740
|
+
return await originalOpen.call(this, openCtx);
|
|
741
|
+
} catch (err) {
|
|
742
|
+
remoteSpan?.setError?.(err);
|
|
743
|
+
remoteSpan?.end();
|
|
744
|
+
self[LIFECYCLE_SPAN] = void 0;
|
|
745
|
+
throw err;
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
proto.close = async function(ctx) {
|
|
749
|
+
const self = this;
|
|
750
|
+
const remoteSpan = self[LIFECYCLE_SPAN];
|
|
751
|
+
try {
|
|
752
|
+
return await originalClose.call(this, ctx);
|
|
753
|
+
} catch (err) {
|
|
754
|
+
remoteSpan?.setError?.(err);
|
|
755
|
+
throw err;
|
|
756
|
+
} finally {
|
|
757
|
+
if (remoteSpan) {
|
|
758
|
+
remoteSpan.end();
|
|
759
|
+
self[LIFECYCLE_SPAN] = void 0;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
}
|
|
844
764
|
Object.defineProperty(klass, "name", {
|
|
845
765
|
value: constructor.name
|
|
846
766
|
});
|
|
@@ -854,45 +774,117 @@ var info = (opts = {}) => (target, propertyKey, descriptor) => {
|
|
|
854
774
|
var mark = (name) => {
|
|
855
775
|
performance.mark(name);
|
|
856
776
|
};
|
|
857
|
-
var span = ({ showInBrowserTimeline = false, op, attributes } = {}) => (target, propertyKey, descriptor) => {
|
|
777
|
+
var span = ({ showInBrowserTimeline = false, showInRemoteTracing = true, op, attributes } = {}) => (target, propertyKey, descriptor) => {
|
|
858
778
|
const method = descriptor.value;
|
|
859
779
|
descriptor.value = async function(...args) {
|
|
860
780
|
const parentCtx = args[0] instanceof Context2 ? args[0] : null;
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
781
|
+
const startTs = performance.now();
|
|
782
|
+
const parentSpanContext = parentCtx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
783
|
+
const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(this);
|
|
784
|
+
const className = resourceEntry?.sanitizedClassName ?? sanitizeClassName(target.constructor?.name ?? "unknown");
|
|
785
|
+
const spanName = `${className}.${propertyKey}`;
|
|
786
|
+
const spanAttributes = {};
|
|
787
|
+
if (resourceEntry) {
|
|
788
|
+
spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
|
|
789
|
+
}
|
|
790
|
+
collectSpanAttributes(this, spanAttributes);
|
|
791
|
+
if (attributes) {
|
|
792
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
793
|
+
spanAttributes[key.startsWith("ctx.") ? key : `ctx.${key}`] = value;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
const remoteSpan = showInRemoteTracing ? TRACE_PROCESSOR.tracingBackend?.startSpan({
|
|
797
|
+
name: spanName,
|
|
798
|
+
op: op ?? "function",
|
|
799
|
+
attributes: spanAttributes,
|
|
800
|
+
parentContext: parentSpanContext
|
|
801
|
+
}) : void 0;
|
|
802
|
+
let callArgs = args;
|
|
803
|
+
if (parentCtx) {
|
|
804
|
+
const childCtx = remoteSpan?.spanContext != null ? parentCtx.derive({
|
|
805
|
+
attributes: {
|
|
806
|
+
[TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext
|
|
807
|
+
}
|
|
808
|
+
}) : parentCtx.derive();
|
|
809
|
+
callArgs = [
|
|
810
|
+
childCtx,
|
|
811
|
+
...args.slice(1)
|
|
812
|
+
];
|
|
813
|
+
}
|
|
873
814
|
try {
|
|
874
815
|
return await method.apply(this, callArgs);
|
|
875
816
|
} catch (err) {
|
|
876
|
-
|
|
817
|
+
remoteSpan?.setError?.(err);
|
|
877
818
|
throw err;
|
|
878
819
|
} finally {
|
|
879
|
-
|
|
820
|
+
remoteSpan?.end();
|
|
821
|
+
if (showInBrowserTimeline && typeof globalThis?.performance?.measure === "function") {
|
|
822
|
+
performance.measure(spanName, {
|
|
823
|
+
start: startTs,
|
|
824
|
+
end: performance.now()
|
|
825
|
+
});
|
|
826
|
+
}
|
|
880
827
|
}
|
|
881
828
|
};
|
|
882
829
|
};
|
|
883
|
-
var
|
|
830
|
+
var manualSpans = /* @__PURE__ */ new Map();
|
|
831
|
+
var manualSpanTimestamps = /* @__PURE__ */ new Map();
|
|
884
832
|
var spanStart = (params) => {
|
|
885
|
-
if (
|
|
886
|
-
return;
|
|
833
|
+
if (manualSpans.has(params.id) || manualSpanTimestamps.has(params.id)) {
|
|
834
|
+
return params.parentCtx;
|
|
835
|
+
}
|
|
836
|
+
const resourceEntry = TRACE_PROCESSOR.resourceInstanceIndex.get(params.instance);
|
|
837
|
+
const className = resourceEntry?.sanitizedClassName ?? "unknown";
|
|
838
|
+
const spanName = `${className}.${params.methodName}`;
|
|
839
|
+
if (params.showInBrowserTimeline) {
|
|
840
|
+
manualSpanTimestamps.set(params.id, {
|
|
841
|
+
name: spanName,
|
|
842
|
+
startTs: performance.now()
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
if (params.showInRemoteTracing === false || !TRACE_PROCESSOR.tracingBackend) {
|
|
846
|
+
return params.parentCtx;
|
|
847
|
+
}
|
|
848
|
+
const parentSpanContext = params.parentCtx?.getAttribute(TRACE_SPAN_ATTRIBUTE);
|
|
849
|
+
const spanAttributes = {};
|
|
850
|
+
if (resourceEntry) {
|
|
851
|
+
spanAttributes.entryPoint = resourceEntry.sanitizedClassName;
|
|
852
|
+
}
|
|
853
|
+
collectSpanAttributes(params.instance, spanAttributes);
|
|
854
|
+
if (params.attributes) {
|
|
855
|
+
for (const [key, value] of Object.entries(params.attributes)) {
|
|
856
|
+
spanAttributes[key.startsWith("ctx.") ? key : `ctx.${key}`] = value;
|
|
857
|
+
}
|
|
887
858
|
}
|
|
888
|
-
const
|
|
889
|
-
|
|
859
|
+
const remoteSpan = TRACE_PROCESSOR.tracingBackend.startSpan({
|
|
860
|
+
name: spanName,
|
|
861
|
+
op: params.op ?? "function",
|
|
862
|
+
attributes: spanAttributes,
|
|
863
|
+
parentContext: parentSpanContext
|
|
864
|
+
});
|
|
865
|
+
manualSpans.set(params.id, remoteSpan);
|
|
866
|
+
if (params.parentCtx && remoteSpan.spanContext != null) {
|
|
867
|
+
return params.parentCtx.derive({
|
|
868
|
+
attributes: {
|
|
869
|
+
[TRACE_SPAN_ATTRIBUTE]: remoteSpan.spanContext
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
return params.parentCtx;
|
|
890
874
|
};
|
|
891
875
|
var spanEnd = (id) => {
|
|
892
|
-
const
|
|
893
|
-
if (
|
|
894
|
-
|
|
895
|
-
|
|
876
|
+
const remoteSpan = manualSpans.get(id);
|
|
877
|
+
if (remoteSpan) {
|
|
878
|
+
remoteSpan.end();
|
|
879
|
+
manualSpans.delete(id);
|
|
880
|
+
}
|
|
881
|
+
const timestamps = manualSpanTimestamps.get(id);
|
|
882
|
+
if (timestamps && typeof globalThis?.performance?.measure === "function") {
|
|
883
|
+
performance.measure(timestamps.name, {
|
|
884
|
+
start: timestamps.startTs,
|
|
885
|
+
end: performance.now()
|
|
886
|
+
});
|
|
887
|
+
manualSpanTimestamps.delete(id);
|
|
896
888
|
}
|
|
897
889
|
};
|
|
898
890
|
var metricsCounter = () => (target, propertyKey, descriptor) => {
|
|
@@ -1110,16 +1102,13 @@ export {
|
|
|
1110
1102
|
DiagnosticsManager,
|
|
1111
1103
|
MapCounter,
|
|
1112
1104
|
RemoteMetrics,
|
|
1113
|
-
RemoteTracing,
|
|
1114
1105
|
ResourceEntry,
|
|
1106
|
+
TRACE_ALL_KEY,
|
|
1115
1107
|
TRACE_PROCESSOR,
|
|
1116
|
-
TRACE_SPAN_ATTRIBUTE,
|
|
1117
1108
|
TimeSeriesCounter,
|
|
1118
1109
|
TimeUsageCounter,
|
|
1119
1110
|
TraceDiagnosticImpl,
|
|
1120
1111
|
TraceProcessor,
|
|
1121
|
-
TraceSender,
|
|
1122
|
-
TracingSpan,
|
|
1123
1112
|
UnaryCounter,
|
|
1124
1113
|
getTracingContext,
|
|
1125
1114
|
sanitizeClassName,
|