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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_http = require('./http-BUHnkhrC.cjs');
2
+ const require_http = require('./http-bOYC2_Z0.cjs');
3
3
  const require_listen = require('./listen-DGzVi7DE.cjs');
4
4
  let node_http = require("node:http");
5
5
  let node_fs = require("node:fs");
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-yIS667nX.js";
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-BSIS3Qgy.cjs";
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-BLqTs00O.js";
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
- const root = existing.spans.find((s) => !s.parentSpanId);
430
- if (root) {
431
- existing.rootSpan = root;
432
- const rootService = root.attributes?.["service.name"];
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.find((s) => !s.parentSpanId) || sorted[0];
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
- const root = existing.spans.find((s) => !s.parentSpanId);
458
- if (root) {
459
- existing.rootSpan = root;
460
- const rootService = root.attributes?.["service.name"];
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 = sorted.find((s) => !s.parentSpanId) || sorted[0];
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-BUHnkhrC.cjs');
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-BSIS3Qgy.cjs";
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-bZ-prq97.cjs";
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-BLqTs00O.js";
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-BrgYNNoC.js";
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-yIS667nX.js";
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";
@@ -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-BSIS3Qgy.cjs";
1
+ import { t as DevtoolsSpanExporter } from "../exporter-CEKKJTci.cjs";
2
2
  export { DevtoolsSpanExporter };
@@ -1,2 +1,2 @@
1
- import { t as DevtoolsSpanExporter } from "../exporter-BLqTs00O.js";
1
+ import { t as DevtoolsSpanExporter } from "../exporter-BJwufQwg.js";
2
2
  export { DevtoolsSpanExporter };
@@ -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
  /**
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_http = require('../http-BUHnkhrC.cjs');
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');
@@ -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-BSIS3Qgy.cjs";
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-bZ-prq97.cjs";
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
@@ -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-BLqTs00O.js";
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-BrgYNNoC.js";
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
@@ -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-yIS667nX.js";
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 };