autotel-devtools 20.1.0 → 21.0.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 +2 -2
- package/dist/cli.js +2 -2
- package/dist/{error-aggregator-CGgWr2OH.d.cts → error-aggregator-D8VKciLY.d.ts} +12 -10
- package/dist/{error-aggregator-DufjI2IG.d.ts → error-aggregator-DCEKMOm3.d.cts} +12 -10
- package/dist/{exporter-CEKKJTci.d.cts → exporter-Dt4kx128.d.cts} +15 -7
- package/dist/{exporter-BJwufQwg.d.ts → exporter-Due9Rd4s.d.ts} +15 -7
- package/dist/genai/index.cjs +93 -107
- package/dist/genai/index.d.cts +1 -32
- package/dist/genai/index.d.ts +1 -32
- package/dist/genai/index.js +94 -107
- package/dist/{http-Ddn7gT0R.js → http-CNZMrnzv.js} +93 -57
- package/dist/{http-D44dITGS.cjs → http-CXSzX4ee.cjs} +93 -57
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -2
- package/dist/json-fields-CPjKZ2WH.js +47 -0
- package/dist/json-fields-DZFlNqT2.cjs +83 -0
- package/dist/{listen-DGzVi7DE.cjs → listen-CEJ3nYJf.cjs} +1 -1
- package/dist/{listen-NVMbBWHw.js → listen-DBfsfcdd.js} +1 -1
- package/dist/server/exporter.d.cts +1 -1
- package/dist/server/exporter.d.ts +1 -1
- 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/types-DHDvZnnn.d.cts +47 -0
- package/dist/types-DHDvZnnn.d.ts +47 -0
- package/dist/widget.global.js +15 -15
- package/package.json +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { i as asString, o as stringAttr, t as asObject } from "./json-fields-CPjKZ2WH.js";
|
|
1
2
|
import { t as pickRoot } from "./trace-root-EHnvuA7f.js";
|
|
2
3
|
import { t as getResourceName } from "./resource-utils-B4UVvfnH.js";
|
|
3
4
|
import { createServer } from "node:http";
|
|
@@ -75,9 +76,9 @@ var ErrorAggregator = class {
|
|
|
75
76
|
*/
|
|
76
77
|
extractErrorFromSpan(span, trace) {
|
|
77
78
|
const exceptionEvent = span.events?.find((e) => e.name === "exception");
|
|
78
|
-
const errorType = span.attributes
|
|
79
|
-
const errorMessage = span.status.message || span.attributes
|
|
80
|
-
const stackTrace = span.attributes
|
|
79
|
+
const errorType = stringAttr(span.attributes, "exception.type", "error.type") ?? stringAttr(exceptionEvent?.attributes, "exception.type") ?? "Error";
|
|
80
|
+
const errorMessage = span.status.message || stringAttr(span.attributes, "exception.message", "error.message") || "Unknown error";
|
|
81
|
+
const stackTrace = stringAttr(span.attributes, "exception.stacktrace", "exception.stack", "error.stack") ?? this.extractStackFromEvents(span);
|
|
81
82
|
return {
|
|
82
83
|
traceId: trace.traceId,
|
|
83
84
|
spanId: span.spanId,
|
|
@@ -87,7 +88,8 @@ var ErrorAggregator = class {
|
|
|
87
88
|
error: {
|
|
88
89
|
type: errorType,
|
|
89
90
|
message: errorMessage,
|
|
90
|
-
stackTrace
|
|
91
|
+
stackTrace,
|
|
92
|
+
fingerprint: stringAttr(span.attributes, "exception.fingerprint") ?? stringAttr(exceptionEvent?.attributes, "exception.fingerprint")
|
|
91
93
|
},
|
|
92
94
|
attributes: this.extractRelevantAttributes(span.attributes)
|
|
93
95
|
};
|
|
@@ -98,7 +100,7 @@ var ErrorAggregator = class {
|
|
|
98
100
|
extractStackFromEvents(span) {
|
|
99
101
|
if (!span.events) return void 0;
|
|
100
102
|
const exceptionEvent = span.events.find((e) => e.name === "exception");
|
|
101
|
-
if (exceptionEvent?.attributes) return exceptionEvent.attributes
|
|
103
|
+
if (exceptionEvent?.attributes) return stringAttr(exceptionEvent.attributes, "exception.stacktrace", "exception.stack");
|
|
102
104
|
}
|
|
103
105
|
/**
|
|
104
106
|
* Extract relevant attributes for error context
|
|
@@ -127,6 +129,7 @@ var ErrorAggregator = class {
|
|
|
127
129
|
* Uses error type + first N stack frames (normalized)
|
|
128
130
|
*/
|
|
129
131
|
generateFingerprint(occurrence) {
|
|
132
|
+
if (occurrence.error.fingerprint) return occurrence.error.fingerprint;
|
|
130
133
|
const parts = [occurrence.error.type];
|
|
131
134
|
if (occurrence.error.stackTrace) {
|
|
132
135
|
const frames = this.extractStackFrames(occurrence.error.stackTrace, this.options.stackFramesForFingerprint);
|
|
@@ -530,13 +533,28 @@ var DevtoolsServer = class {
|
|
|
530
533
|
}
|
|
531
534
|
};
|
|
532
535
|
|
|
536
|
+
//#endregion
|
|
537
|
+
//#region src/server/otlp-types.ts
|
|
538
|
+
/**
|
|
539
|
+
* An exporter's payload, read as the envelope it claims to be.
|
|
540
|
+
*
|
|
541
|
+
* SAFETY: this is the one place the receiver trusts the wire. Every field of
|
|
542
|
+
* every envelope above is optional, so a payload that is not what it claims
|
|
543
|
+
* reads back as empty arrays and undefined fields rather than throwing - which
|
|
544
|
+
* is what the callers below rely on when they find no spans to add.
|
|
545
|
+
*/
|
|
546
|
+
function otlpEnvelope(payload) {
|
|
547
|
+
if (typeof payload !== "object" || payload === null) return void 0;
|
|
548
|
+
return payload;
|
|
549
|
+
}
|
|
550
|
+
|
|
533
551
|
//#endregion
|
|
534
552
|
//#region src/server/otlp.ts
|
|
535
553
|
function resolveOtlpValue(v) {
|
|
536
554
|
if (!v) return void 0;
|
|
537
555
|
if (v.stringValue !== void 0) return v.stringValue;
|
|
538
556
|
if (v.boolValue !== void 0) return v.boolValue;
|
|
539
|
-
if (v.intValue !== void 0) return
|
|
557
|
+
if (v.intValue !== void 0) return Number(v.intValue);
|
|
540
558
|
if (v.doubleValue !== void 0) return v.doubleValue;
|
|
541
559
|
if (v.bytesValue !== void 0) return v.bytesValue;
|
|
542
560
|
if (v.arrayValue?.values) return v.arrayValue.values.map(resolveOtlpValue);
|
|
@@ -548,6 +566,29 @@ function flattenAttributes(attrs) {
|
|
|
548
566
|
for (const { key, value } of attrs) out[key] = resolveOtlpValue(value);
|
|
549
567
|
return out;
|
|
550
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* A log record's body: the text it carried, or the structure it carried when
|
|
571
|
+
* the sender used an OTLP kvlist or array rather than a string.
|
|
572
|
+
*/
|
|
573
|
+
function logBody(body) {
|
|
574
|
+
const text = asString(body);
|
|
575
|
+
if (text !== void 0) return text;
|
|
576
|
+
if (body === void 0 || body === null) return "";
|
|
577
|
+
const structured = asObject(body);
|
|
578
|
+
if (!structured) return String(body);
|
|
579
|
+
return structured;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Attributes handed to the agent layer, whose `Attributes` is OTel's own -
|
|
583
|
+
* scalars and arrays of scalars, nothing nested.
|
|
584
|
+
*
|
|
585
|
+
* SAFETY: a coding agent's metrics and events carry scalar attributes only,
|
|
586
|
+
* so the two shapes agree in practice. A sender that nests one anyway is
|
|
587
|
+
* rendered by the Agents tab as whatever it is rather than being dropped.
|
|
588
|
+
*/
|
|
589
|
+
function agentAttributes(attributes) {
|
|
590
|
+
return attributes;
|
|
591
|
+
}
|
|
551
592
|
function nanoToMs(nano) {
|
|
552
593
|
if (!nano) return 0;
|
|
553
594
|
const ns = BigInt(nano);
|
|
@@ -555,19 +596,19 @@ function nanoToMs(nano) {
|
|
|
555
596
|
const remNs = ns % 1000000n;
|
|
556
597
|
return Number(ms) + Number(remNs) / 1e6;
|
|
557
598
|
}
|
|
558
|
-
const SPAN_KIND_MAP =
|
|
559
|
-
0
|
|
560
|
-
1
|
|
561
|
-
2
|
|
562
|
-
3
|
|
563
|
-
4
|
|
564
|
-
5
|
|
565
|
-
SPAN_KIND_INTERNAL
|
|
566
|
-
SPAN_KIND_SERVER
|
|
567
|
-
SPAN_KIND_CLIENT
|
|
568
|
-
SPAN_KIND_PRODUCER
|
|
569
|
-
SPAN_KIND_CONSUMER
|
|
570
|
-
|
|
599
|
+
const SPAN_KIND_MAP = /* @__PURE__ */ new Map([
|
|
600
|
+
[0, "INTERNAL"],
|
|
601
|
+
[1, "INTERNAL"],
|
|
602
|
+
[2, "SERVER"],
|
|
603
|
+
[3, "CLIENT"],
|
|
604
|
+
[4, "PRODUCER"],
|
|
605
|
+
[5, "CONSUMER"],
|
|
606
|
+
["SPAN_KIND_INTERNAL", "INTERNAL"],
|
|
607
|
+
["SPAN_KIND_SERVER", "SERVER"],
|
|
608
|
+
["SPAN_KIND_CLIENT", "CLIENT"],
|
|
609
|
+
["SPAN_KIND_PRODUCER", "PRODUCER"],
|
|
610
|
+
["SPAN_KIND_CONSUMER", "CONSUMER"]
|
|
611
|
+
]);
|
|
571
612
|
function normalizeHexId(id) {
|
|
572
613
|
if (!id) return "";
|
|
573
614
|
if (/^[A-Za-z0-9+/=]+$/.test(id) && !/^[0-9a-f]+$/i.test(id) && (id.length === 12 || id.length === 24 || id.length === 28 || id.length === 44 || id.length === 48)) try {
|
|
@@ -576,15 +617,13 @@ function normalizeHexId(id) {
|
|
|
576
617
|
return id;
|
|
577
618
|
}
|
|
578
619
|
function parseOtlpTraces(payload) {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
if (!Array.isArray(resourceSpans) || resourceSpans.length === 0) return [];
|
|
620
|
+
const resourceSpans = otlpEnvelope(payload)?.resourceSpans;
|
|
621
|
+
if (!resourceSpans || resourceSpans.length === 0) return [];
|
|
582
622
|
const traceMap = /* @__PURE__ */ new Map();
|
|
583
623
|
for (const rs of resourceSpans) {
|
|
584
624
|
const resourceAttrs = flattenAttributes(rs.resource?.attributes);
|
|
585
625
|
const service = String(resourceAttrs["service.name"] || "unknown");
|
|
586
|
-
const
|
|
587
|
-
for (const ss of scopeSpans) {
|
|
626
|
+
for (const ss of rs.scopeSpans ?? []) {
|
|
588
627
|
const scope = ss.scope?.name ? {
|
|
589
628
|
name: ss.scope.name,
|
|
590
629
|
version: ss.scope.version || void 0
|
|
@@ -603,7 +642,7 @@ function parseOtlpTraces(payload) {
|
|
|
603
642
|
spanId: normalizeHexId(span.spanId),
|
|
604
643
|
parentSpanId: normalizeHexId(span.parentSpanId) || void 0,
|
|
605
644
|
name: span.name || "unknown",
|
|
606
|
-
kind: SPAN_KIND_MAP
|
|
645
|
+
kind: SPAN_KIND_MAP.get(span.kind ?? 0) ?? "INTERNAL",
|
|
607
646
|
startTime: startMs,
|
|
608
647
|
endTime: endMs,
|
|
609
648
|
duration: endMs - startMs,
|
|
@@ -615,12 +654,12 @@ function parseOtlpTraces(payload) {
|
|
|
615
654
|
code: status,
|
|
616
655
|
message: span.status?.message
|
|
617
656
|
},
|
|
618
|
-
events: (span.events
|
|
657
|
+
events: (span.events ?? []).map((e) => ({
|
|
619
658
|
name: e.name || "",
|
|
620
659
|
timestamp: nanoToMs(e.timeUnixNano),
|
|
621
660
|
attributes: flattenAttributes(e.attributes)
|
|
622
661
|
})),
|
|
623
|
-
links: (span.links
|
|
662
|
+
links: (span.links ?? []).map((l) => ({
|
|
624
663
|
traceId: normalizeHexId(l.traceId),
|
|
625
664
|
spanId: normalizeHexId(l.spanId),
|
|
626
665
|
attributes: flattenAttributes(l.attributes)
|
|
@@ -643,7 +682,7 @@ function parseOtlpTraces(payload) {
|
|
|
643
682
|
const startTime = Math.min(...sorted.map((s) => s.startTime));
|
|
644
683
|
const endTime = Math.max(...sorted.map((s) => s.endTime));
|
|
645
684
|
const hasError = sorted.some((s) => s.status.code === "ERROR");
|
|
646
|
-
|
|
685
|
+
const trace = {
|
|
647
686
|
traceId,
|
|
648
687
|
correlationId: traceId.slice(0, 16),
|
|
649
688
|
rootSpan,
|
|
@@ -652,20 +691,20 @@ function parseOtlpTraces(payload) {
|
|
|
652
691
|
endTime,
|
|
653
692
|
duration: endTime - startTime,
|
|
654
693
|
status: hasError ? "ERROR" : "OK",
|
|
655
|
-
service
|
|
656
|
-
|
|
657
|
-
|
|
694
|
+
service
|
|
695
|
+
};
|
|
696
|
+
if (partial) trace.partial = true;
|
|
697
|
+
traces.push(trace);
|
|
658
698
|
}
|
|
659
699
|
return traces;
|
|
660
700
|
}
|
|
661
701
|
function parseOtlpLogs(payload) {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (!Array.isArray(resourceLogs)) return [];
|
|
702
|
+
const resourceLogs = otlpEnvelope(payload)?.resourceLogs;
|
|
703
|
+
if (!resourceLogs) return [];
|
|
665
704
|
const logs = [];
|
|
666
705
|
for (const rl of resourceLogs) {
|
|
667
706
|
const resourceAttrs = flattenAttributes(rl.resource?.attributes);
|
|
668
|
-
for (const sl of rl.scopeLogs
|
|
707
|
+
for (const sl of rl.scopeLogs ?? []) for (const rec of sl.logRecords ?? []) {
|
|
669
708
|
const timestamp = nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano);
|
|
670
709
|
const traceId = normalizeHexId(rec.traceId) || void 0;
|
|
671
710
|
const spanId = normalizeHexId(rec.spanId) || void 0;
|
|
@@ -677,7 +716,7 @@ function parseOtlpLogs(payload) {
|
|
|
677
716
|
resourceName: getResourceName(resourceAttrs),
|
|
678
717
|
severityText: rec.severityText,
|
|
679
718
|
severityNumber: rec.severityNumber,
|
|
680
|
-
body:
|
|
719
|
+
body: logBody(body),
|
|
681
720
|
timestamp,
|
|
682
721
|
attributes: flattenAttributes(rec.attributes),
|
|
683
722
|
resource: resourceAttrs
|
|
@@ -687,11 +726,10 @@ function parseOtlpLogs(payload) {
|
|
|
687
726
|
return logs;
|
|
688
727
|
}
|
|
689
728
|
function countOtlpMetrics(payload) {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
if (!Array.isArray(resourceMetrics)) return 0;
|
|
729
|
+
const resourceMetrics = otlpEnvelope(payload)?.resourceMetrics;
|
|
730
|
+
if (!resourceMetrics) return 0;
|
|
693
731
|
let count = 0;
|
|
694
|
-
for (const rm of resourceMetrics) for (const sm of rm.scopeMetrics
|
|
732
|
+
for (const rm of resourceMetrics) for (const sm of rm.scopeMetrics ?? []) count += (sm.metrics ?? []).length;
|
|
695
733
|
return count;
|
|
696
734
|
}
|
|
697
735
|
function extractDataPoints(metric) {
|
|
@@ -701,14 +739,14 @@ function extractDataPoints(metric) {
|
|
|
701
739
|
const value = dp.asDouble !== void 0 ? Number(dp.asDouble) : dp.asInt !== void 0 ? Number(dp.asInt) : 0;
|
|
702
740
|
points.push({
|
|
703
741
|
value,
|
|
704
|
-
attributes: flattenAttributes(dp.attributes),
|
|
742
|
+
attributes: agentAttributes(flattenAttributes(dp.attributes)),
|
|
705
743
|
timestamp: nanoToMs(dp.timeUnixNano || dp.startTimeUnixNano)
|
|
706
744
|
});
|
|
707
745
|
}
|
|
708
746
|
const histPoints = metric.histogram?.dataPoints;
|
|
709
747
|
if (Array.isArray(histPoints)) for (const dp of histPoints) points.push({
|
|
710
748
|
value: dp.count !== void 0 ? Number(dp.count) : 0,
|
|
711
|
-
attributes: flattenAttributes(dp.attributes),
|
|
749
|
+
attributes: agentAttributes(flattenAttributes(dp.attributes)),
|
|
712
750
|
timestamp: nanoToMs(dp.timeUnixNano || dp.startTimeUnixNano)
|
|
713
751
|
});
|
|
714
752
|
return points;
|
|
@@ -724,19 +762,18 @@ function readTemporality(metric) {
|
|
|
724
762
|
if (raw === 1 || raw === "AGGREGATION_TEMPORALITY_DELTA") return "delta";
|
|
725
763
|
}
|
|
726
764
|
function parseOtlpMetrics(payload) {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
if (!Array.isArray(resourceMetrics)) return [];
|
|
765
|
+
const resourceMetrics = otlpEnvelope(payload)?.resourceMetrics;
|
|
766
|
+
if (!resourceMetrics) return [];
|
|
730
767
|
const records = [];
|
|
731
768
|
for (const rm of resourceMetrics) {
|
|
732
|
-
const resource = flattenAttributes(rm.resource?.attributes);
|
|
733
|
-
for (const sm of rm.scopeMetrics
|
|
769
|
+
const resource = agentAttributes(flattenAttributes(rm.resource?.attributes));
|
|
770
|
+
for (const sm of rm.scopeMetrics ?? []) {
|
|
734
771
|
const scope = sm.scope?.name ? {
|
|
735
772
|
name: sm.scope.name,
|
|
736
773
|
version: sm.scope.version || void 0
|
|
737
774
|
} : void 0;
|
|
738
|
-
for (const metric of sm.metrics
|
|
739
|
-
name: metric.name,
|
|
775
|
+
for (const metric of sm.metrics ?? []) records.push({
|
|
776
|
+
name: metric.name ?? "",
|
|
740
777
|
unit: metric.unit || void 0,
|
|
741
778
|
description: metric.description || void 0,
|
|
742
779
|
temporality: readTemporality(metric),
|
|
@@ -755,20 +792,19 @@ function parseOtlpMetrics(payload) {
|
|
|
755
792
|
* `parseOtlpLogs`, which feeds the generic Logs tab.
|
|
756
793
|
*/
|
|
757
794
|
function parseOtlpAgentEvents(payload) {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
if (!Array.isArray(resourceLogs)) return [];
|
|
795
|
+
const resourceLogs = otlpEnvelope(payload)?.resourceLogs;
|
|
796
|
+
if (!resourceLogs) return [];
|
|
761
797
|
const events = [];
|
|
762
798
|
for (const rl of resourceLogs) {
|
|
763
|
-
const resource = flattenAttributes(rl.resource?.attributes);
|
|
764
|
-
for (const sl of rl.scopeLogs
|
|
799
|
+
const resource = agentAttributes(flattenAttributes(rl.resource?.attributes));
|
|
800
|
+
for (const sl of rl.scopeLogs ?? []) {
|
|
765
801
|
const scope = sl.scope?.name ? {
|
|
766
802
|
name: sl.scope.name,
|
|
767
803
|
version: sl.scope.version || void 0
|
|
768
804
|
} : void 0;
|
|
769
|
-
for (const rec of sl.logRecords
|
|
770
|
-
const attributes = flattenAttributes(rec.attributes);
|
|
771
|
-
const eventName =
|
|
805
|
+
for (const rec of sl.logRecords ?? []) {
|
|
806
|
+
const attributes = agentAttributes(flattenAttributes(rec.attributes));
|
|
807
|
+
const eventName = rec.eventName || String(attributes["event.name"] ?? "");
|
|
772
808
|
events.push({
|
|
773
809
|
eventName,
|
|
774
810
|
timestamp: nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano),
|
|
@@ -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_json_fields = require('./json-fields-DZFlNqT2.cjs');
|
|
28
29
|
const require_trace_root = require('./trace-root-BMa667jK.cjs');
|
|
29
30
|
const require_resource_utils = require('./resource-utils-DjHJB6uc.cjs');
|
|
30
31
|
let node_http = require("node:http");
|
|
@@ -104,9 +105,9 @@ var ErrorAggregator = class {
|
|
|
104
105
|
*/
|
|
105
106
|
extractErrorFromSpan(span, trace) {
|
|
106
107
|
const exceptionEvent = span.events?.find((e) => e.name === "exception");
|
|
107
|
-
const errorType = span.attributes
|
|
108
|
-
const errorMessage = span.status.message || span.attributes
|
|
109
|
-
const stackTrace = span.attributes
|
|
108
|
+
const errorType = require_json_fields.stringAttr(span.attributes, "exception.type", "error.type") ?? require_json_fields.stringAttr(exceptionEvent?.attributes, "exception.type") ?? "Error";
|
|
109
|
+
const errorMessage = span.status.message || require_json_fields.stringAttr(span.attributes, "exception.message", "error.message") || "Unknown error";
|
|
110
|
+
const stackTrace = require_json_fields.stringAttr(span.attributes, "exception.stacktrace", "exception.stack", "error.stack") ?? this.extractStackFromEvents(span);
|
|
110
111
|
return {
|
|
111
112
|
traceId: trace.traceId,
|
|
112
113
|
spanId: span.spanId,
|
|
@@ -116,7 +117,8 @@ var ErrorAggregator = class {
|
|
|
116
117
|
error: {
|
|
117
118
|
type: errorType,
|
|
118
119
|
message: errorMessage,
|
|
119
|
-
stackTrace
|
|
120
|
+
stackTrace,
|
|
121
|
+
fingerprint: require_json_fields.stringAttr(span.attributes, "exception.fingerprint") ?? require_json_fields.stringAttr(exceptionEvent?.attributes, "exception.fingerprint")
|
|
120
122
|
},
|
|
121
123
|
attributes: this.extractRelevantAttributes(span.attributes)
|
|
122
124
|
};
|
|
@@ -127,7 +129,7 @@ var ErrorAggregator = class {
|
|
|
127
129
|
extractStackFromEvents(span) {
|
|
128
130
|
if (!span.events) return void 0;
|
|
129
131
|
const exceptionEvent = span.events.find((e) => e.name === "exception");
|
|
130
|
-
if (exceptionEvent?.attributes) return exceptionEvent.attributes
|
|
132
|
+
if (exceptionEvent?.attributes) return require_json_fields.stringAttr(exceptionEvent.attributes, "exception.stacktrace", "exception.stack");
|
|
131
133
|
}
|
|
132
134
|
/**
|
|
133
135
|
* Extract relevant attributes for error context
|
|
@@ -156,6 +158,7 @@ var ErrorAggregator = class {
|
|
|
156
158
|
* Uses error type + first N stack frames (normalized)
|
|
157
159
|
*/
|
|
158
160
|
generateFingerprint(occurrence) {
|
|
161
|
+
if (occurrence.error.fingerprint) return occurrence.error.fingerprint;
|
|
159
162
|
const parts = [occurrence.error.type];
|
|
160
163
|
if (occurrence.error.stackTrace) {
|
|
161
164
|
const frames = this.extractStackFrames(occurrence.error.stackTrace, this.options.stackFramesForFingerprint);
|
|
@@ -559,13 +562,28 @@ var DevtoolsServer = class {
|
|
|
559
562
|
}
|
|
560
563
|
};
|
|
561
564
|
|
|
565
|
+
//#endregion
|
|
566
|
+
//#region src/server/otlp-types.ts
|
|
567
|
+
/**
|
|
568
|
+
* An exporter's payload, read as the envelope it claims to be.
|
|
569
|
+
*
|
|
570
|
+
* SAFETY: this is the one place the receiver trusts the wire. Every field of
|
|
571
|
+
* every envelope above is optional, so a payload that is not what it claims
|
|
572
|
+
* reads back as empty arrays and undefined fields rather than throwing - which
|
|
573
|
+
* is what the callers below rely on when they find no spans to add.
|
|
574
|
+
*/
|
|
575
|
+
function otlpEnvelope(payload) {
|
|
576
|
+
if (typeof payload !== "object" || payload === null) return void 0;
|
|
577
|
+
return payload;
|
|
578
|
+
}
|
|
579
|
+
|
|
562
580
|
//#endregion
|
|
563
581
|
//#region src/server/otlp.ts
|
|
564
582
|
function resolveOtlpValue(v) {
|
|
565
583
|
if (!v) return void 0;
|
|
566
584
|
if (v.stringValue !== void 0) return v.stringValue;
|
|
567
585
|
if (v.boolValue !== void 0) return v.boolValue;
|
|
568
|
-
if (v.intValue !== void 0) return
|
|
586
|
+
if (v.intValue !== void 0) return Number(v.intValue);
|
|
569
587
|
if (v.doubleValue !== void 0) return v.doubleValue;
|
|
570
588
|
if (v.bytesValue !== void 0) return v.bytesValue;
|
|
571
589
|
if (v.arrayValue?.values) return v.arrayValue.values.map(resolveOtlpValue);
|
|
@@ -577,6 +595,29 @@ function flattenAttributes(attrs) {
|
|
|
577
595
|
for (const { key, value } of attrs) out[key] = resolveOtlpValue(value);
|
|
578
596
|
return out;
|
|
579
597
|
}
|
|
598
|
+
/**
|
|
599
|
+
* A log record's body: the text it carried, or the structure it carried when
|
|
600
|
+
* the sender used an OTLP kvlist or array rather than a string.
|
|
601
|
+
*/
|
|
602
|
+
function logBody(body) {
|
|
603
|
+
const text = require_json_fields.asString(body);
|
|
604
|
+
if (text !== void 0) return text;
|
|
605
|
+
if (body === void 0 || body === null) return "";
|
|
606
|
+
const structured = require_json_fields.asObject(body);
|
|
607
|
+
if (!structured) return String(body);
|
|
608
|
+
return structured;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Attributes handed to the agent layer, whose `Attributes` is OTel's own -
|
|
612
|
+
* scalars and arrays of scalars, nothing nested.
|
|
613
|
+
*
|
|
614
|
+
* SAFETY: a coding agent's metrics and events carry scalar attributes only,
|
|
615
|
+
* so the two shapes agree in practice. A sender that nests one anyway is
|
|
616
|
+
* rendered by the Agents tab as whatever it is rather than being dropped.
|
|
617
|
+
*/
|
|
618
|
+
function agentAttributes(attributes) {
|
|
619
|
+
return attributes;
|
|
620
|
+
}
|
|
580
621
|
function nanoToMs(nano) {
|
|
581
622
|
if (!nano) return 0;
|
|
582
623
|
const ns = BigInt(nano);
|
|
@@ -584,19 +625,19 @@ function nanoToMs(nano) {
|
|
|
584
625
|
const remNs = ns % 1000000n;
|
|
585
626
|
return Number(ms) + Number(remNs) / 1e6;
|
|
586
627
|
}
|
|
587
|
-
const SPAN_KIND_MAP =
|
|
588
|
-
0
|
|
589
|
-
1
|
|
590
|
-
2
|
|
591
|
-
3
|
|
592
|
-
4
|
|
593
|
-
5
|
|
594
|
-
SPAN_KIND_INTERNAL
|
|
595
|
-
SPAN_KIND_SERVER
|
|
596
|
-
SPAN_KIND_CLIENT
|
|
597
|
-
SPAN_KIND_PRODUCER
|
|
598
|
-
SPAN_KIND_CONSUMER
|
|
599
|
-
|
|
628
|
+
const SPAN_KIND_MAP = /* @__PURE__ */ new Map([
|
|
629
|
+
[0, "INTERNAL"],
|
|
630
|
+
[1, "INTERNAL"],
|
|
631
|
+
[2, "SERVER"],
|
|
632
|
+
[3, "CLIENT"],
|
|
633
|
+
[4, "PRODUCER"],
|
|
634
|
+
[5, "CONSUMER"],
|
|
635
|
+
["SPAN_KIND_INTERNAL", "INTERNAL"],
|
|
636
|
+
["SPAN_KIND_SERVER", "SERVER"],
|
|
637
|
+
["SPAN_KIND_CLIENT", "CLIENT"],
|
|
638
|
+
["SPAN_KIND_PRODUCER", "PRODUCER"],
|
|
639
|
+
["SPAN_KIND_CONSUMER", "CONSUMER"]
|
|
640
|
+
]);
|
|
600
641
|
function normalizeHexId(id) {
|
|
601
642
|
if (!id) return "";
|
|
602
643
|
if (/^[A-Za-z0-9+/=]+$/.test(id) && !/^[0-9a-f]+$/i.test(id) && (id.length === 12 || id.length === 24 || id.length === 28 || id.length === 44 || id.length === 48)) try {
|
|
@@ -605,15 +646,13 @@ function normalizeHexId(id) {
|
|
|
605
646
|
return id;
|
|
606
647
|
}
|
|
607
648
|
function parseOtlpTraces(payload) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (!Array.isArray(resourceSpans) || resourceSpans.length === 0) return [];
|
|
649
|
+
const resourceSpans = otlpEnvelope(payload)?.resourceSpans;
|
|
650
|
+
if (!resourceSpans || resourceSpans.length === 0) return [];
|
|
611
651
|
const traceMap = /* @__PURE__ */ new Map();
|
|
612
652
|
for (const rs of resourceSpans) {
|
|
613
653
|
const resourceAttrs = flattenAttributes(rs.resource?.attributes);
|
|
614
654
|
const service = String(resourceAttrs["service.name"] || "unknown");
|
|
615
|
-
const
|
|
616
|
-
for (const ss of scopeSpans) {
|
|
655
|
+
for (const ss of rs.scopeSpans ?? []) {
|
|
617
656
|
const scope = ss.scope?.name ? {
|
|
618
657
|
name: ss.scope.name,
|
|
619
658
|
version: ss.scope.version || void 0
|
|
@@ -632,7 +671,7 @@ function parseOtlpTraces(payload) {
|
|
|
632
671
|
spanId: normalizeHexId(span.spanId),
|
|
633
672
|
parentSpanId: normalizeHexId(span.parentSpanId) || void 0,
|
|
634
673
|
name: span.name || "unknown",
|
|
635
|
-
kind: SPAN_KIND_MAP
|
|
674
|
+
kind: SPAN_KIND_MAP.get(span.kind ?? 0) ?? "INTERNAL",
|
|
636
675
|
startTime: startMs,
|
|
637
676
|
endTime: endMs,
|
|
638
677
|
duration: endMs - startMs,
|
|
@@ -644,12 +683,12 @@ function parseOtlpTraces(payload) {
|
|
|
644
683
|
code: status,
|
|
645
684
|
message: span.status?.message
|
|
646
685
|
},
|
|
647
|
-
events: (span.events
|
|
686
|
+
events: (span.events ?? []).map((e) => ({
|
|
648
687
|
name: e.name || "",
|
|
649
688
|
timestamp: nanoToMs(e.timeUnixNano),
|
|
650
689
|
attributes: flattenAttributes(e.attributes)
|
|
651
690
|
})),
|
|
652
|
-
links: (span.links
|
|
691
|
+
links: (span.links ?? []).map((l) => ({
|
|
653
692
|
traceId: normalizeHexId(l.traceId),
|
|
654
693
|
spanId: normalizeHexId(l.spanId),
|
|
655
694
|
attributes: flattenAttributes(l.attributes)
|
|
@@ -672,7 +711,7 @@ function parseOtlpTraces(payload) {
|
|
|
672
711
|
const startTime = Math.min(...sorted.map((s) => s.startTime));
|
|
673
712
|
const endTime = Math.max(...sorted.map((s) => s.endTime));
|
|
674
713
|
const hasError = sorted.some((s) => s.status.code === "ERROR");
|
|
675
|
-
|
|
714
|
+
const trace = {
|
|
676
715
|
traceId,
|
|
677
716
|
correlationId: traceId.slice(0, 16),
|
|
678
717
|
rootSpan,
|
|
@@ -681,20 +720,20 @@ function parseOtlpTraces(payload) {
|
|
|
681
720
|
endTime,
|
|
682
721
|
duration: endTime - startTime,
|
|
683
722
|
status: hasError ? "ERROR" : "OK",
|
|
684
|
-
service
|
|
685
|
-
|
|
686
|
-
|
|
723
|
+
service
|
|
724
|
+
};
|
|
725
|
+
if (partial) trace.partial = true;
|
|
726
|
+
traces.push(trace);
|
|
687
727
|
}
|
|
688
728
|
return traces;
|
|
689
729
|
}
|
|
690
730
|
function parseOtlpLogs(payload) {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
if (!Array.isArray(resourceLogs)) return [];
|
|
731
|
+
const resourceLogs = otlpEnvelope(payload)?.resourceLogs;
|
|
732
|
+
if (!resourceLogs) return [];
|
|
694
733
|
const logs = [];
|
|
695
734
|
for (const rl of resourceLogs) {
|
|
696
735
|
const resourceAttrs = flattenAttributes(rl.resource?.attributes);
|
|
697
|
-
for (const sl of rl.scopeLogs
|
|
736
|
+
for (const sl of rl.scopeLogs ?? []) for (const rec of sl.logRecords ?? []) {
|
|
698
737
|
const timestamp = nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano);
|
|
699
738
|
const traceId = normalizeHexId(rec.traceId) || void 0;
|
|
700
739
|
const spanId = normalizeHexId(rec.spanId) || void 0;
|
|
@@ -706,7 +745,7 @@ function parseOtlpLogs(payload) {
|
|
|
706
745
|
resourceName: require_resource_utils.getResourceName(resourceAttrs),
|
|
707
746
|
severityText: rec.severityText,
|
|
708
747
|
severityNumber: rec.severityNumber,
|
|
709
|
-
body:
|
|
748
|
+
body: logBody(body),
|
|
710
749
|
timestamp,
|
|
711
750
|
attributes: flattenAttributes(rec.attributes),
|
|
712
751
|
resource: resourceAttrs
|
|
@@ -716,11 +755,10 @@ function parseOtlpLogs(payload) {
|
|
|
716
755
|
return logs;
|
|
717
756
|
}
|
|
718
757
|
function countOtlpMetrics(payload) {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
if (!Array.isArray(resourceMetrics)) return 0;
|
|
758
|
+
const resourceMetrics = otlpEnvelope(payload)?.resourceMetrics;
|
|
759
|
+
if (!resourceMetrics) return 0;
|
|
722
760
|
let count = 0;
|
|
723
|
-
for (const rm of resourceMetrics) for (const sm of rm.scopeMetrics
|
|
761
|
+
for (const rm of resourceMetrics) for (const sm of rm.scopeMetrics ?? []) count += (sm.metrics ?? []).length;
|
|
724
762
|
return count;
|
|
725
763
|
}
|
|
726
764
|
function extractDataPoints(metric) {
|
|
@@ -730,14 +768,14 @@ function extractDataPoints(metric) {
|
|
|
730
768
|
const value = dp.asDouble !== void 0 ? Number(dp.asDouble) : dp.asInt !== void 0 ? Number(dp.asInt) : 0;
|
|
731
769
|
points.push({
|
|
732
770
|
value,
|
|
733
|
-
attributes: flattenAttributes(dp.attributes),
|
|
771
|
+
attributes: agentAttributes(flattenAttributes(dp.attributes)),
|
|
734
772
|
timestamp: nanoToMs(dp.timeUnixNano || dp.startTimeUnixNano)
|
|
735
773
|
});
|
|
736
774
|
}
|
|
737
775
|
const histPoints = metric.histogram?.dataPoints;
|
|
738
776
|
if (Array.isArray(histPoints)) for (const dp of histPoints) points.push({
|
|
739
777
|
value: dp.count !== void 0 ? Number(dp.count) : 0,
|
|
740
|
-
attributes: flattenAttributes(dp.attributes),
|
|
778
|
+
attributes: agentAttributes(flattenAttributes(dp.attributes)),
|
|
741
779
|
timestamp: nanoToMs(dp.timeUnixNano || dp.startTimeUnixNano)
|
|
742
780
|
});
|
|
743
781
|
return points;
|
|
@@ -753,19 +791,18 @@ function readTemporality(metric) {
|
|
|
753
791
|
if (raw === 1 || raw === "AGGREGATION_TEMPORALITY_DELTA") return "delta";
|
|
754
792
|
}
|
|
755
793
|
function parseOtlpMetrics(payload) {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
if (!Array.isArray(resourceMetrics)) return [];
|
|
794
|
+
const resourceMetrics = otlpEnvelope(payload)?.resourceMetrics;
|
|
795
|
+
if (!resourceMetrics) return [];
|
|
759
796
|
const records = [];
|
|
760
797
|
for (const rm of resourceMetrics) {
|
|
761
|
-
const resource = flattenAttributes(rm.resource?.attributes);
|
|
762
|
-
for (const sm of rm.scopeMetrics
|
|
798
|
+
const resource = agentAttributes(flattenAttributes(rm.resource?.attributes));
|
|
799
|
+
for (const sm of rm.scopeMetrics ?? []) {
|
|
763
800
|
const scope = sm.scope?.name ? {
|
|
764
801
|
name: sm.scope.name,
|
|
765
802
|
version: sm.scope.version || void 0
|
|
766
803
|
} : void 0;
|
|
767
|
-
for (const metric of sm.metrics
|
|
768
|
-
name: metric.name,
|
|
804
|
+
for (const metric of sm.metrics ?? []) records.push({
|
|
805
|
+
name: metric.name ?? "",
|
|
769
806
|
unit: metric.unit || void 0,
|
|
770
807
|
description: metric.description || void 0,
|
|
771
808
|
temporality: readTemporality(metric),
|
|
@@ -784,20 +821,19 @@ function parseOtlpMetrics(payload) {
|
|
|
784
821
|
* `parseOtlpLogs`, which feeds the generic Logs tab.
|
|
785
822
|
*/
|
|
786
823
|
function parseOtlpAgentEvents(payload) {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
if (!Array.isArray(resourceLogs)) return [];
|
|
824
|
+
const resourceLogs = otlpEnvelope(payload)?.resourceLogs;
|
|
825
|
+
if (!resourceLogs) return [];
|
|
790
826
|
const events = [];
|
|
791
827
|
for (const rl of resourceLogs) {
|
|
792
|
-
const resource = flattenAttributes(rl.resource?.attributes);
|
|
793
|
-
for (const sl of rl.scopeLogs
|
|
828
|
+
const resource = agentAttributes(flattenAttributes(rl.resource?.attributes));
|
|
829
|
+
for (const sl of rl.scopeLogs ?? []) {
|
|
794
830
|
const scope = sl.scope?.name ? {
|
|
795
831
|
name: sl.scope.name,
|
|
796
832
|
version: sl.scope.version || void 0
|
|
797
833
|
} : void 0;
|
|
798
|
-
for (const rec of sl.logRecords
|
|
799
|
-
const attributes = flattenAttributes(rec.attributes);
|
|
800
|
-
const eventName =
|
|
834
|
+
for (const rec of sl.logRecords ?? []) {
|
|
835
|
+
const attributes = agentAttributes(flattenAttributes(rec.attributes));
|
|
836
|
+
const eventName = rec.eventName || String(attributes["event.name"] ?? "");
|
|
801
837
|
events.push({
|
|
802
838
|
eventName,
|
|
803
839
|
timestamp: nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano),
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_http = require('./http-
|
|
3
|
-
const require_listen = require('./listen-
|
|
2
|
+
const require_http = require('./http-CXSzX4ee.cjs');
|
|
3
|
+
const require_listen = require('./listen-CEJ3nYJf.cjs');
|
|
4
4
|
const require_server_exporter = require('./server/exporter.cjs');
|
|
5
5
|
const require_server_log_exporter = require('./server/log-exporter.cjs');
|
|
6
6
|
const require_server_remote_exporter = require('./server/remote-exporter.cjs');
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as SpanAttributes, t as AttributeValue } from "./types-DHDvZnnn.cjs";
|
|
2
|
+
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-Dt4kx128.cjs";
|
|
2
3
|
import { DevtoolsLogExporter } from "./server/log-exporter.cjs";
|
|
3
4
|
import { DevtoolsRemoteExporter } from "./server/remote-exporter.cjs";
|
|
4
|
-
import { t as ErrorAggregator } from "./error-aggregator-
|
|
5
|
+
import { t as ErrorAggregator } from "./error-aggregator-DCEKMOm3.cjs";
|
|
5
6
|
import { Server } from "node:http";
|
|
6
7
|
//#region src/index.d.ts
|
|
7
8
|
interface CreateDevtoolsOptions {
|
|
@@ -30,4 +31,4 @@ interface DevtoolsInstance {
|
|
|
30
31
|
}
|
|
31
32
|
declare function createDevtools(options?: CreateDevtoolsOptions): DevtoolsInstance;
|
|
32
33
|
//#endregion
|
|
33
|
-
export { CreateDevtoolsOptions, type DevtoolsData, DevtoolsInstance, DevtoolsLogExporter, DevtoolsRemoteExporter, DevtoolsServer, DevtoolsSpanExporter, ErrorAggregator, type ErrorGroup, type LogData, type MetricData, type SpanData, type TraceData, createDevtools };
|
|
34
|
+
export { type AttributeValue, CreateDevtoolsOptions, type DevtoolsData, DevtoolsInstance, DevtoolsLogExporter, DevtoolsRemoteExporter, DevtoolsServer, DevtoolsSpanExporter, ErrorAggregator, type ErrorGroup, type LogData, type MetricData, type SpanAttributes, type SpanData, type TraceData, createDevtools };
|