autotel-devtools 17.0.0 → 17.1.1
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/cli.cjs +1 -1
- package/dist/cli.js +1 -1
- package/dist/{error-aggregator-bZ-prq97.d.cts → error-aggregator-CGgWr2OH.d.cts} +1 -1
- package/dist/{error-aggregator-BrgYNNoC.d.ts → error-aggregator-DufjI2IG.d.ts} +1 -1
- package/dist/{exporter-BLqTs00O.d.ts → exporter-BJwufQwg.d.ts} +9 -0
- package/dist/{exporter-BSIS3Qgy.d.cts → exporter-CEKKJTci.d.cts} +9 -0
- package/dist/{http-yIS667nX.js → http-BLmWVZP0.js} +11 -6
- package/dist/{http-BUHnkhrC.cjs → http-bOYC2_Z0.cjs} +11 -6
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/server/exporter.cjs +4 -2
- package/dist/server/exporter.d.cts +1 -1
- package/dist/server/exporter.d.ts +1 -1
- package/dist/server/exporter.js +5 -2
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +1 -1
- package/dist/trace-root-BMa667jK.cjs +36 -0
- package/dist/trace-root-EHnvuA7f.js +30 -0
- package/dist/widget.global.js +12 -11
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { d as DevtoolsServer, i as probePortHolder, p as hostHeaderIsLoopback, t as attachDevtoolsRoutes } from "./http-
|
|
2
|
+
import { d as DevtoolsServer, i as probePortHolder, p as hostHeaderIsLoopback, t as attachDevtoolsRoutes } from "./http-BLmWVZP0.js";
|
|
3
3
|
import { t as listenLoopbackDualStack } from "./listen-NVMbBWHw.js";
|
|
4
4
|
import { createServer } from "node:http";
|
|
5
5
|
import { readFileSync } from "node:fs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-
|
|
1
|
+
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-CEKKJTci.cjs";
|
|
2
2
|
//#region src/server/error-aggregator.d.ts
|
|
3
3
|
interface ErrorAggregatorOptions {
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-
|
|
1
|
+
import { a as ErrorGroup, o as ErrorOccurrence, u as TraceData } from "./exporter-BJwufQwg.js";
|
|
2
2
|
//#region src/server/error-aggregator.d.ts
|
|
3
3
|
interface ErrorAggregatorOptions {
|
|
4
4
|
/**
|
|
@@ -42,6 +42,15 @@ interface TraceData {
|
|
|
42
42
|
duration: number;
|
|
43
43
|
status: 'OK' | 'ERROR' | 'UNSET';
|
|
44
44
|
service: string;
|
|
45
|
+
/**
|
|
46
|
+
* True when no span in this trace is a true root: every span received has a
|
|
47
|
+
* parent that did not arrive. The trace is a fragment, normally because
|
|
48
|
+
* sampling kept only part of it or because the rest is still in flight.
|
|
49
|
+
* `rootSpan` is then the earliest span whose parent is absent rather than the
|
|
50
|
+
* real root, and the duration covers only the part present. Recomputed as
|
|
51
|
+
* spans merge, so it clears once the real root arrives.
|
|
52
|
+
*/
|
|
53
|
+
partial?: boolean;
|
|
45
54
|
}
|
|
46
55
|
interface LogData {
|
|
47
56
|
id: string;
|
|
@@ -42,6 +42,15 @@ interface TraceData {
|
|
|
42
42
|
duration: number;
|
|
43
43
|
status: 'OK' | 'ERROR' | 'UNSET';
|
|
44
44
|
service: string;
|
|
45
|
+
/**
|
|
46
|
+
* True when no span in this trace is a true root: every span received has a
|
|
47
|
+
* parent that did not arrive. The trace is a fragment, normally because
|
|
48
|
+
* sampling kept only part of it or because the rest is still in flight.
|
|
49
|
+
* `rootSpan` is then the earliest span whose parent is absent rather than the
|
|
50
|
+
* real root, and the duration covers only the part present. Recomputed as
|
|
51
|
+
* spans merge, so it clears once the real root arrives.
|
|
52
|
+
*/
|
|
53
|
+
partial?: boolean;
|
|
45
54
|
}
|
|
46
55
|
interface LogData {
|
|
47
56
|
id: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as pickRoot } from "./trace-root-EHnvuA7f.js";
|
|
1
2
|
import { t as getResourceName } from "./resource-utils-B4UVvfnH.js";
|
|
2
3
|
import { createServer } from "node:http";
|
|
3
4
|
import { WebSocket, WebSocketServer } from "ws";
|
|
@@ -426,10 +427,13 @@ var DevtoolsServer = class {
|
|
|
426
427
|
existing.endTime = Math.max(existing.endTime, trace.endTime);
|
|
427
428
|
existing.duration = existing.endTime - existing.startTime;
|
|
428
429
|
if (trace.status === "ERROR") existing.status = "ERROR";
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
430
|
+
existing.spans.sort((a, b) => a.startTime - b.startTime);
|
|
431
|
+
const { rootSpan, partial } = pickRoot(existing.spans);
|
|
432
|
+
existing.rootSpan = rootSpan;
|
|
433
|
+
if (partial) existing.partial = true;
|
|
434
|
+
else {
|
|
435
|
+
delete existing.partial;
|
|
436
|
+
const rootService = rootSpan.attributes?.["service.name"];
|
|
433
437
|
if (typeof rootService === "string" && rootService.length > 0) existing.service = rootService;
|
|
434
438
|
}
|
|
435
439
|
} else this.traces = appendWithLimit(this.traces, trace, this.limits.maxTraceCount);
|
|
@@ -635,7 +639,7 @@ function parseOtlpTraces(payload) {
|
|
|
635
639
|
const traces = [];
|
|
636
640
|
for (const [traceId, { spans, service }] of traceMap) {
|
|
637
641
|
const sorted = spans.sort((a, b) => a.startTime - b.startTime);
|
|
638
|
-
const rootSpan = sorted
|
|
642
|
+
const { rootSpan, partial } = pickRoot(sorted);
|
|
639
643
|
const startTime = Math.min(...sorted.map((s) => s.startTime));
|
|
640
644
|
const endTime = Math.max(...sorted.map((s) => s.endTime));
|
|
641
645
|
const hasError = sorted.some((s) => s.status.code === "ERROR");
|
|
@@ -648,7 +652,8 @@ function parseOtlpTraces(payload) {
|
|
|
648
652
|
endTime,
|
|
649
653
|
duration: endTime - startTime,
|
|
650
654
|
status: hasError ? "ERROR" : "OK",
|
|
651
|
-
service
|
|
655
|
+
service,
|
|
656
|
+
...partial ? { partial: true } : {}
|
|
652
657
|
});
|
|
653
658
|
}
|
|
654
659
|
return traces;
|
|
@@ -25,6 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
27
|
//#endregion
|
|
28
|
+
const require_trace_root = require('./trace-root-BMa667jK.cjs');
|
|
28
29
|
const require_resource_utils = require('./resource-utils-DjHJB6uc.cjs');
|
|
29
30
|
let node_http = require("node:http");
|
|
30
31
|
let ws = require("ws");
|
|
@@ -454,10 +455,13 @@ var DevtoolsServer = class {
|
|
|
454
455
|
existing.endTime = Math.max(existing.endTime, trace.endTime);
|
|
455
456
|
existing.duration = existing.endTime - existing.startTime;
|
|
456
457
|
if (trace.status === "ERROR") existing.status = "ERROR";
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
458
|
+
existing.spans.sort((a, b) => a.startTime - b.startTime);
|
|
459
|
+
const { rootSpan, partial } = require_trace_root.pickRoot(existing.spans);
|
|
460
|
+
existing.rootSpan = rootSpan;
|
|
461
|
+
if (partial) existing.partial = true;
|
|
462
|
+
else {
|
|
463
|
+
delete existing.partial;
|
|
464
|
+
const rootService = rootSpan.attributes?.["service.name"];
|
|
461
465
|
if (typeof rootService === "string" && rootService.length > 0) existing.service = rootService;
|
|
462
466
|
}
|
|
463
467
|
} else this.traces = appendWithLimit(this.traces, trace, this.limits.maxTraceCount);
|
|
@@ -663,7 +667,7 @@ function parseOtlpTraces(payload) {
|
|
|
663
667
|
const traces = [];
|
|
664
668
|
for (const [traceId, { spans, service }] of traceMap) {
|
|
665
669
|
const sorted = spans.sort((a, b) => a.startTime - b.startTime);
|
|
666
|
-
const rootSpan =
|
|
670
|
+
const { rootSpan, partial } = require_trace_root.pickRoot(sorted);
|
|
667
671
|
const startTime = Math.min(...sorted.map((s) => s.startTime));
|
|
668
672
|
const endTime = Math.max(...sorted.map((s) => s.endTime));
|
|
669
673
|
const hasError = sorted.some((s) => s.status.code === "ERROR");
|
|
@@ -676,7 +680,8 @@ function parseOtlpTraces(payload) {
|
|
|
676
680
|
endTime,
|
|
677
681
|
duration: endTime - startTime,
|
|
678
682
|
status: hasError ? "ERROR" : "OK",
|
|
679
|
-
service
|
|
683
|
+
service,
|
|
684
|
+
...partial ? { partial: true } : {}
|
|
680
685
|
});
|
|
681
686
|
}
|
|
682
687
|
return traces;
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_http = require('./http-
|
|
2
|
+
const require_http = require('./http-bOYC2_Z0.cjs');
|
|
3
3
|
const require_listen = require('./listen-DGzVi7DE.cjs');
|
|
4
4
|
const require_server_exporter = require('./server/exporter.cjs');
|
|
5
5
|
const require_server_log_exporter = require('./server/log-exporter.cjs');
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "./exporter-
|
|
1
|
+
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "./exporter-CEKKJTci.cjs";
|
|
2
2
|
import { DevtoolsLogExporter } from "./server/log-exporter.cjs";
|
|
3
3
|
import { DevtoolsRemoteExporter } from "./server/remote-exporter.cjs";
|
|
4
|
-
import { t as ErrorAggregator } from "./error-aggregator-
|
|
4
|
+
import { t as ErrorAggregator } from "./error-aggregator-CGgWr2OH.cjs";
|
|
5
5
|
import { Server } from "node:http";
|
|
6
6
|
//#region src/index.d.ts
|
|
7
7
|
interface CreateDevtoolsOptions {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "./exporter-
|
|
1
|
+
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "./exporter-BJwufQwg.js";
|
|
2
2
|
import { DevtoolsLogExporter } from "./server/log-exporter.js";
|
|
3
3
|
import { DevtoolsRemoteExporter } from "./server/remote-exporter.js";
|
|
4
|
-
import { t as ErrorAggregator } from "./error-aggregator-
|
|
4
|
+
import { t as ErrorAggregator } from "./error-aggregator-DufjI2IG.js";
|
|
5
5
|
import { Server } from "node:http";
|
|
6
6
|
//#region src/index.d.ts
|
|
7
7
|
interface CreateDevtoolsOptions {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as ErrorAggregator, d as DevtoolsServer, p as hostHeaderIsLoopback, t as attachDevtoolsRoutes } from "./http-
|
|
1
|
+
import { b as ErrorAggregator, d as DevtoolsServer, p as hostHeaderIsLoopback, t as attachDevtoolsRoutes } from "./http-BLmWVZP0.js";
|
|
2
2
|
import { t as listenLoopbackDualStack } from "./listen-NVMbBWHw.js";
|
|
3
3
|
import { DevtoolsSpanExporter } from "./server/exporter.js";
|
|
4
4
|
import { DevtoolsLogExporter } from "./server/log-exporter.js";
|
package/dist/server/exporter.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_trace_root = require('../trace-root-BMa667jK.cjs');
|
|
2
3
|
|
|
3
4
|
//#region src/server/exporter.ts
|
|
4
5
|
var DevtoolsSpanExporter = class {
|
|
@@ -45,8 +46,8 @@ var DevtoolsSpanExporter = class {
|
|
|
45
46
|
*/
|
|
46
47
|
convertToTraceData(traceId, spans) {
|
|
47
48
|
const spanData = spans.map((span) => this.convertSpan(span));
|
|
48
|
-
const rootSpan = spanData.find((s) => !s.parentSpanId) || spanData[0];
|
|
49
49
|
spanData.sort((a, b) => a.startTime - b.startTime);
|
|
50
|
+
const { rootSpan, partial } = require_trace_root.pickRoot(spanData);
|
|
50
51
|
const startTime = Math.min(...spanData.map((s) => s.startTime));
|
|
51
52
|
const endTime = Math.max(...spanData.map((s) => s.endTime));
|
|
52
53
|
const status = spanData.some((s) => s.status.code === "ERROR") ? "ERROR" : "OK";
|
|
@@ -59,7 +60,8 @@ var DevtoolsSpanExporter = class {
|
|
|
59
60
|
endTime,
|
|
60
61
|
duration: endTime - startTime,
|
|
61
62
|
status,
|
|
62
|
-
service: this.serviceName
|
|
63
|
+
service: this.serviceName,
|
|
64
|
+
...partial ? { partial: true } : {}
|
|
63
65
|
};
|
|
64
66
|
}
|
|
65
67
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as DevtoolsSpanExporter } from "../exporter-
|
|
1
|
+
import { t as DevtoolsSpanExporter } from "../exporter-CEKKJTci.cjs";
|
|
2
2
|
export { DevtoolsSpanExporter };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as DevtoolsSpanExporter } from "../exporter-
|
|
1
|
+
import { t as DevtoolsSpanExporter } from "../exporter-BJwufQwg.js";
|
|
2
2
|
export { DevtoolsSpanExporter };
|
package/dist/server/exporter.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { t as pickRoot } from "../trace-root-EHnvuA7f.js";
|
|
2
|
+
|
|
1
3
|
//#region src/server/exporter.ts
|
|
2
4
|
var DevtoolsSpanExporter = class {
|
|
3
5
|
server;
|
|
@@ -43,8 +45,8 @@ var DevtoolsSpanExporter = class {
|
|
|
43
45
|
*/
|
|
44
46
|
convertToTraceData(traceId, spans) {
|
|
45
47
|
const spanData = spans.map((span) => this.convertSpan(span));
|
|
46
|
-
const rootSpan = spanData.find((s) => !s.parentSpanId) || spanData[0];
|
|
47
48
|
spanData.sort((a, b) => a.startTime - b.startTime);
|
|
49
|
+
const { rootSpan, partial } = pickRoot(spanData);
|
|
48
50
|
const startTime = Math.min(...spanData.map((s) => s.startTime));
|
|
49
51
|
const endTime = Math.max(...spanData.map((s) => s.endTime));
|
|
50
52
|
const status = spanData.some((s) => s.status.code === "ERROR") ? "ERROR" : "OK";
|
|
@@ -57,7 +59,8 @@ var DevtoolsSpanExporter = class {
|
|
|
57
59
|
endTime,
|
|
58
60
|
duration: endTime - startTime,
|
|
59
61
|
status,
|
|
60
|
-
service: this.serviceName
|
|
62
|
+
service: this.serviceName,
|
|
63
|
+
...partial ? { partial: true } : {}
|
|
61
64
|
};
|
|
62
65
|
}
|
|
63
66
|
/**
|
package/dist/server/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_http = require('../http-
|
|
2
|
+
const require_http = require('../http-bOYC2_Z0.cjs');
|
|
3
3
|
const require_server_exporter = require('./exporter.cjs');
|
|
4
4
|
const require_server_log_exporter = require('./log-exporter.cjs');
|
|
5
5
|
const require_server_remote_exporter = require('./remote-exporter.cjs');
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, o as ErrorOccurrence, r as DevtoolsServerOptions, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "../exporter-
|
|
1
|
+
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, o as ErrorOccurrence, r as DevtoolsServerOptions, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "../exporter-CEKKJTci.cjs";
|
|
2
2
|
import { DevtoolsLogExporter } from "./log-exporter.cjs";
|
|
3
3
|
import { DevtoolsRemoteExporter, DevtoolsRemoteExporterOptions } from "./remote-exporter.cjs";
|
|
4
|
-
import { t as ErrorAggregator } from "../error-aggregator-
|
|
4
|
+
import { t as ErrorAggregator } from "../error-aggregator-CGgWr2OH.cjs";
|
|
5
5
|
import { Server } from "node:http";
|
|
6
6
|
import { AgentRawEvent, OtelMetricRecord } from "autotel-agents";
|
|
7
7
|
//#region src/server/http.d.ts
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, o as ErrorOccurrence, r as DevtoolsServerOptions, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "../exporter-
|
|
1
|
+
import { a as ErrorGroup, c as MetricData, i as DevtoolsData, l as SpanData, n as DevtoolsServer, o as ErrorOccurrence, r as DevtoolsServerOptions, s as LogData, t as DevtoolsSpanExporter, u as TraceData } from "../exporter-BJwufQwg.js";
|
|
2
2
|
import { DevtoolsLogExporter } from "./log-exporter.js";
|
|
3
3
|
import { DevtoolsRemoteExporter, DevtoolsRemoteExporterOptions } from "./remote-exporter.js";
|
|
4
|
-
import { t as ErrorAggregator } from "../error-aggregator-
|
|
4
|
+
import { t as ErrorAggregator } from "../error-aggregator-DufjI2IG.js";
|
|
5
5
|
import { Server } from "node:http";
|
|
6
6
|
import { AgentRawEvent, OtelMetricRecord } from "autotel-agents";
|
|
7
7
|
//#region src/server/http.d.ts
|
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as appendWithLimit, a as decodeOtlpLogsRequest, b as ErrorAggregator, c as isProtobufContentType, d as DevtoolsServer, f as allowSensitiveRequest, g as appendManyWithLimit, h as originIsLoopback, i as probePortHolder, l as parseOtlpLogs, m as isLoopbackHostname, n as createDevtoolsHttpServer, o as decodeOtlpMetricsRequest, p as hostHeaderIsLoopback, r as DEVTOOLS_IDENTITY, s as decodeOtlpTraceRequest, t as attachDevtoolsRoutes, u as parseOtlpTraces, v as applyTelemetryLimits, y as resolveTelemetryLimits } from "../http-
|
|
1
|
+
import { _ as appendWithLimit, a as decodeOtlpLogsRequest, b as ErrorAggregator, c as isProtobufContentType, d as DevtoolsServer, f as allowSensitiveRequest, g as appendManyWithLimit, h as originIsLoopback, i as probePortHolder, l as parseOtlpLogs, m as isLoopbackHostname, n as createDevtoolsHttpServer, o as decodeOtlpMetricsRequest, p as hostHeaderIsLoopback, r as DEVTOOLS_IDENTITY, s as decodeOtlpTraceRequest, t as attachDevtoolsRoutes, u as parseOtlpTraces, v as applyTelemetryLimits, y as resolveTelemetryLimits } from "../http-BLmWVZP0.js";
|
|
2
2
|
import { DevtoolsSpanExporter } from "./exporter.js";
|
|
3
3
|
import { DevtoolsLogExporter } from "./log-exporter.js";
|
|
4
4
|
import { DevtoolsRemoteExporter } from "./remote-exporter.js";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/server/trace-root.ts
|
|
3
|
+
/**
|
|
4
|
+
* Pick the span to present as the top of a trace, and report whether the real
|
|
5
|
+
* root is missing from `spans`.
|
|
6
|
+
*
|
|
7
|
+
* A true root has no parent at all. Failing that the trace is a fragment, so
|
|
8
|
+
* fall back to the earliest span whose parent did not arrive rather than
|
|
9
|
+
* presenting an arbitrary child as though it were the root. Sampling makes this
|
|
10
|
+
* ordinary: a sender may keep a failed span and drop the routine parent above
|
|
11
|
+
* it, and a receiver that hides the difference makes a half-trace look complete.
|
|
12
|
+
*
|
|
13
|
+
* `partial` is a fact about the span set passed in, not about a batch — spans of
|
|
14
|
+
* one trace arrive across several exports, so recompute this wherever the set
|
|
15
|
+
* grows instead of caching the first answer.
|
|
16
|
+
*
|
|
17
|
+
* Pass spans sorted by start time; the fallbacks then pick the earliest
|
|
18
|
+
* candidate rather than whichever one the caller happened to receive first.
|
|
19
|
+
*/
|
|
20
|
+
function pickRoot(spans) {
|
|
21
|
+
const present = new Set(spans.map((s) => s.spanId));
|
|
22
|
+
const trueRoot = spans.find((s) => !s.parentSpanId);
|
|
23
|
+
const orphan = spans.find((s) => s.parentSpanId && !present.has(s.parentSpanId));
|
|
24
|
+
return {
|
|
25
|
+
rootSpan: trueRoot ?? orphan ?? spans[0],
|
|
26
|
+
partial: !trueRoot
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
Object.defineProperty(exports, 'pickRoot', {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return pickRoot;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/server/trace-root.ts
|
|
2
|
+
/**
|
|
3
|
+
* Pick the span to present as the top of a trace, and report whether the real
|
|
4
|
+
* root is missing from `spans`.
|
|
5
|
+
*
|
|
6
|
+
* A true root has no parent at all. Failing that the trace is a fragment, so
|
|
7
|
+
* fall back to the earliest span whose parent did not arrive rather than
|
|
8
|
+
* presenting an arbitrary child as though it were the root. Sampling makes this
|
|
9
|
+
* ordinary: a sender may keep a failed span and drop the routine parent above
|
|
10
|
+
* it, and a receiver that hides the difference makes a half-trace look complete.
|
|
11
|
+
*
|
|
12
|
+
* `partial` is a fact about the span set passed in, not about a batch — spans of
|
|
13
|
+
* one trace arrive across several exports, so recompute this wherever the set
|
|
14
|
+
* grows instead of caching the first answer.
|
|
15
|
+
*
|
|
16
|
+
* Pass spans sorted by start time; the fallbacks then pick the earliest
|
|
17
|
+
* candidate rather than whichever one the caller happened to receive first.
|
|
18
|
+
*/
|
|
19
|
+
function pickRoot(spans) {
|
|
20
|
+
const present = new Set(spans.map((s) => s.spanId));
|
|
21
|
+
const trueRoot = spans.find((s) => !s.parentSpanId);
|
|
22
|
+
const orphan = spans.find((s) => s.parentSpanId && !present.has(s.parentSpanId));
|
|
23
|
+
return {
|
|
24
|
+
rootSpan: trueRoot ?? orphan ?? spans[0],
|
|
25
|
+
partial: !trueRoot
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { pickRoot as t };
|