autotel-devtools 8.1.0 → 9.0.0
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 +108 -1409
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +109 -1402
- package/dist/cli.js.map +1 -1
- package/dist/error-aggregator-BvNmgn7E.d.ts +120 -0
- package/dist/error-aggregator-nnfbpSR7.d.cts +120 -0
- package/dist/exporter-1Y3GmLVS.d.cts +182 -0
- package/dist/exporter-CZ5HdD3o.d.ts +182 -0
- package/dist/genai/index.cjs +650 -537
- package/dist/genai/index.cjs.map +1 -1
- package/dist/genai/index.d.cts +164 -157
- package/dist/genai/index.d.ts +164 -157
- package/dist/genai/index.js +649 -536
- package/dist/genai/index.js.map +1 -1
- package/dist/http-BkkKa9C_.js +1128 -0
- package/dist/http-BkkKa9C_.js.map +1 -0
- package/dist/http-Yj6iSrMX.cjs +1275 -0
- package/dist/http-Yj6iSrMX.cjs.map +1 -0
- package/dist/index.cjs +50 -1708
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -23
- package/dist/index.d.ts +21 -23
- package/dist/index.js +44 -1696
- package/dist/index.js.map +1 -1
- package/dist/listen-BBsxO0wm.cjs +125 -0
- package/dist/listen-BBsxO0wm.cjs.map +1 -0
- package/dist/listen-DfOCquUq.js +120 -0
- package/dist/listen-DfOCquUq.js.map +1 -0
- package/dist/resource-utils-B4UVvfnH.js +18 -0
- package/dist/resource-utils-B4UVvfnH.js.map +1 -0
- package/dist/resource-utils-DjHJB6uc.cjs +24 -0
- package/dist/resource-utils-DjHJB6uc.cjs.map +1 -0
- package/dist/server/exporter.cjs +135 -159
- package/dist/server/exporter.cjs.map +1 -1
- package/dist/server/exporter.d.cts +2 -4
- package/dist/server/exporter.d.ts +2 -4
- package/dist/server/exporter.js +134 -158
- package/dist/server/exporter.js.map +1 -1
- package/dist/server/index.cjs +29 -1640
- package/dist/server/index.d.cts +34 -31
- package/dist/server/index.d.ts +34 -31
- package/dist/server/index.js +5 -1610
- package/dist/server/log-exporter.cjs +75 -102
- package/dist/server/log-exporter.cjs.map +1 -1
- package/dist/server/log-exporter.d.cts +27 -46
- package/dist/server/log-exporter.d.ts +27 -46
- package/dist/server/log-exporter.js +74 -100
- package/dist/server/log-exporter.js.map +1 -1
- package/dist/server/remote-exporter.cjs +171 -213
- package/dist/server/remote-exporter.cjs.map +1 -1
- package/dist/server/remote-exporter.d.cts +62 -82
- package/dist/server/remote-exporter.d.ts +62 -82
- package/dist/server/remote-exporter.js +170 -212
- package/dist/server/remote-exporter.js.map +1 -1
- package/dist/widget.global.js +10 -10
- package/package.json +5 -5
- package/dist/error-aggregator-D0Uu5r38.d.ts +0 -147
- package/dist/error-aggregator-D1Mr221Y.d.cts +0 -147
- package/dist/exporter-De6p4iAD.d.cts +0 -182
- package/dist/exporter-De6p4iAD.d.ts +0 -182
- package/dist/server/index.cjs.map +0 -1
- package/dist/server/index.js.map +0 -1
package/dist/server/exporter.js
CHANGED
|
@@ -1,163 +1,139 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/server/exporter.ts
|
|
2
2
|
var DevtoolsSpanExporter = class {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
* Convert OpenTelemetry SpanKind to string
|
|
136
|
-
*/
|
|
137
|
-
convertSpanKind(kind) {
|
|
138
|
-
switch (kind) {
|
|
139
|
-
case 0: {
|
|
140
|
-
return "INTERNAL";
|
|
141
|
-
}
|
|
142
|
-
case 1: {
|
|
143
|
-
return "SERVER";
|
|
144
|
-
}
|
|
145
|
-
case 2: {
|
|
146
|
-
return "CLIENT";
|
|
147
|
-
}
|
|
148
|
-
case 3: {
|
|
149
|
-
return "PRODUCER";
|
|
150
|
-
}
|
|
151
|
-
case 4: {
|
|
152
|
-
return "CONSUMER";
|
|
153
|
-
}
|
|
154
|
-
default: {
|
|
155
|
-
return "INTERNAL";
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
3
|
+
server;
|
|
4
|
+
serviceName;
|
|
5
|
+
constructor(server, serviceName = "unknown-service") {
|
|
6
|
+
this.server = server;
|
|
7
|
+
this.serviceName = serviceName;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Export spans to the WebSocket server
|
|
11
|
+
*/
|
|
12
|
+
async export(spans, resultCallback) {
|
|
13
|
+
resultCallback({ code: 0 });
|
|
14
|
+
Promise.resolve().then(() => {
|
|
15
|
+
try {
|
|
16
|
+
console.log(`[Autotel Exporter] Exporting ${spans.length} span(s)`);
|
|
17
|
+
const traceMap = /* @__PURE__ */ new Map();
|
|
18
|
+
for (const span of spans) {
|
|
19
|
+
const traceId = span.spanContext().traceId;
|
|
20
|
+
if (!traceMap.has(traceId)) traceMap.set(traceId, []);
|
|
21
|
+
traceMap.get(traceId).push(span);
|
|
22
|
+
}
|
|
23
|
+
for (const [traceId, traceSpans] of traceMap) {
|
|
24
|
+
const trace = this.convertToTraceData(traceId, traceSpans);
|
|
25
|
+
console.log(`[Autotel Exporter] Adding trace ${traceId.slice(0, 16)} with ${traceSpans.length} spans`);
|
|
26
|
+
this.server.addTrace(trace);
|
|
27
|
+
}
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error("[Autotel Exporter] Export error:", error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Shutdown the exporter
|
|
35
|
+
*/
|
|
36
|
+
async shutdown() {}
|
|
37
|
+
/**
|
|
38
|
+
* Force flush any buffered spans
|
|
39
|
+
*/
|
|
40
|
+
async forceFlush() {}
|
|
41
|
+
/**
|
|
42
|
+
* Convert OpenTelemetry spans to TraceData
|
|
43
|
+
*/
|
|
44
|
+
convertToTraceData(traceId, spans) {
|
|
45
|
+
const spanData = spans.map((span) => this.convertSpan(span));
|
|
46
|
+
const rootSpan = spanData.find((s) => !s.parentSpanId) || spanData[0];
|
|
47
|
+
spanData.sort((a, b) => a.startTime - b.startTime);
|
|
48
|
+
const startTime = Math.min(...spanData.map((s) => s.startTime));
|
|
49
|
+
const endTime = Math.max(...spanData.map((s) => s.endTime));
|
|
50
|
+
const status = spanData.some((s) => s.status.code === "ERROR") ? "ERROR" : "OK";
|
|
51
|
+
return {
|
|
52
|
+
traceId,
|
|
53
|
+
correlationId: traceId.slice(0, 16),
|
|
54
|
+
rootSpan,
|
|
55
|
+
spans: spanData,
|
|
56
|
+
startTime,
|
|
57
|
+
endTime,
|
|
58
|
+
duration: endTime - startTime,
|
|
59
|
+
status,
|
|
60
|
+
service: this.serviceName
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Convert OpenTelemetry span to SpanData
|
|
65
|
+
*/
|
|
66
|
+
convertSpan(span) {
|
|
67
|
+
const spanContext = span.spanContext();
|
|
68
|
+
const startTime = span.startTime[0] * 1e3 + span.startTime[1] / 1e6;
|
|
69
|
+
const endTime = span.endTime[0] * 1e3 + span.endTime[1] / 1e6;
|
|
70
|
+
const attributes = {};
|
|
71
|
+
for (const [key, value] of Object.entries(span.attributes)) attributes[key] = value;
|
|
72
|
+
const statusCode = span.status.code;
|
|
73
|
+
let status;
|
|
74
|
+
switch (statusCode) {
|
|
75
|
+
case 0:
|
|
76
|
+
status = "UNSET";
|
|
77
|
+
break;
|
|
78
|
+
case 1:
|
|
79
|
+
status = "OK";
|
|
80
|
+
break;
|
|
81
|
+
case 2:
|
|
82
|
+
status = "ERROR";
|
|
83
|
+
break;
|
|
84
|
+
default: status = "UNSET";
|
|
85
|
+
}
|
|
86
|
+
const events = span.events.map((event) => ({
|
|
87
|
+
name: event.name,
|
|
88
|
+
timestamp: event.time[0] * 1e3 + event.time[1] / 1e6,
|
|
89
|
+
attributes: event.attributes ? Object.fromEntries(Object.entries(event.attributes)) : void 0
|
|
90
|
+
}));
|
|
91
|
+
const links = span.links.map((link) => ({
|
|
92
|
+
traceId: link.context.traceId,
|
|
93
|
+
spanId: link.context.spanId,
|
|
94
|
+
attributes: link.attributes ? Object.fromEntries(Object.entries(link.attributes)) : void 0
|
|
95
|
+
}));
|
|
96
|
+
return {
|
|
97
|
+
traceId: spanContext.traceId,
|
|
98
|
+
spanId: spanContext.spanId,
|
|
99
|
+
parentSpanId: span.parentSpanId,
|
|
100
|
+
name: span.name,
|
|
101
|
+
kind: this.convertSpanKind(span.kind),
|
|
102
|
+
startTime,
|
|
103
|
+
endTime,
|
|
104
|
+
duration: endTime - startTime,
|
|
105
|
+
attributes,
|
|
106
|
+
status: {
|
|
107
|
+
code: status,
|
|
108
|
+
message: span.status.message
|
|
109
|
+
},
|
|
110
|
+
events: events.length > 0 ? events : void 0,
|
|
111
|
+
links: links.length > 0 ? links : void 0,
|
|
112
|
+
scope: this.convertScope(span)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
convertScope(span) {
|
|
116
|
+
const s = span.instrumentationScope ?? span.instrumentationLibrary;
|
|
117
|
+
return s?.name ? {
|
|
118
|
+
name: s.name,
|
|
119
|
+
version: s.version || void 0
|
|
120
|
+
} : void 0;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Convert OpenTelemetry SpanKind to string
|
|
124
|
+
*/
|
|
125
|
+
convertSpanKind(kind) {
|
|
126
|
+
switch (kind) {
|
|
127
|
+
case 0: return "INTERNAL";
|
|
128
|
+
case 1: return "SERVER";
|
|
129
|
+
case 2: return "CLIENT";
|
|
130
|
+
case 3: return "PRODUCER";
|
|
131
|
+
case 4: return "CONSUMER";
|
|
132
|
+
default: return "INTERNAL";
|
|
133
|
+
}
|
|
134
|
+
}
|
|
159
135
|
};
|
|
160
136
|
|
|
137
|
+
//#endregion
|
|
161
138
|
export { DevtoolsSpanExporter };
|
|
162
|
-
//# sourceMappingURL=exporter.js.map
|
|
163
139
|
//# sourceMappingURL=exporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/exporter.ts"],"names":[],"mappings":"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","file":"exporter.js","sourcesContent":["/**\n * OpenTelemetry SpanExporter that streams spans to DevtoolsServer\n */\n\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base';\nimport type { ExportResult, ExportResultCode } from '@opentelemetry/core';\nimport type { DevtoolsServer } from './server';\nimport type { TraceData, SpanData } from './types';\n\nexport class DevtoolsSpanExporter implements SpanExporter {\n private server: DevtoolsServer;\n private serviceName: string;\n\n constructor(server: DevtoolsServer, serviceName: string = 'unknown-service') {\n this.server = server;\n this.serviceName = serviceName;\n }\n\n /**\n * Export spans to the WebSocket server\n */\n async export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void,\n ): Promise<void> {\n // Immediately call the callback to unblock the span processor\n // Then process the spans asynchronously\n resultCallback({ code: 0 as ExportResultCode });\n\n // Process spans asynchronously without blocking\n Promise.resolve().then(() => {\n try {\n console.log(`[Autotel Exporter] Exporting ${spans.length} span(s)`);\n\n // Group spans by trace ID\n const traceMap = new Map<string, ReadableSpan[]>();\n\n for (const span of spans) {\n const traceId = span.spanContext().traceId;\n if (!traceMap.has(traceId)) {\n traceMap.set(traceId, []);\n }\n traceMap.get(traceId)!.push(span);\n }\n\n // Convert each trace and send to server\n for (const [traceId, traceSpans] of traceMap) {\n const trace = this.convertToTraceData(traceId, traceSpans);\n console.log(\n `[Autotel Exporter] Adding trace ${traceId.slice(0, 16)} with ${traceSpans.length} spans`,\n );\n this.server.addTrace(trace);\n }\n } catch (error) {\n console.error('[Autotel Exporter] Export error:', error);\n }\n });\n }\n\n /**\n * Shutdown the exporter\n */\n async shutdown(): Promise<void> {\n // Nothing to clean up\n }\n\n /**\n * Force flush any buffered spans\n */\n async forceFlush(): Promise<void> {\n // Nothing to flush\n }\n\n /**\n * Convert OpenTelemetry spans to TraceData\n */\n private convertToTraceData(\n traceId: string,\n spans: ReadableSpan[],\n ): TraceData {\n // Convert spans\n const spanData: SpanData[] = spans.map((span) => this.convertSpan(span));\n\n // Find root span (no parent)\n const rootSpan = spanData.find((s) => !s.parentSpanId) || spanData[0];\n\n // Sort spans by start time\n spanData.sort((a, b) => a.startTime - b.startTime);\n\n const startTime = Math.min(...spanData.map((s) => s.startTime));\n const endTime = Math.max(...spanData.map((s) => s.endTime));\n\n // Determine overall status (ERROR if any span errored)\n const hasError = spanData.some((s) => s.status.code === 'ERROR');\n const status = hasError ? 'ERROR' : 'OK';\n\n return {\n traceId,\n correlationId: traceId.slice(0, 16), // First 16 chars\n rootSpan,\n spans: spanData,\n startTime,\n endTime,\n duration: endTime - startTime,\n status: status as 'OK' | 'ERROR' | 'UNSET',\n service: this.serviceName,\n };\n }\n\n /**\n * Convert OpenTelemetry span to SpanData\n */\n private convertSpan(span: ReadableSpan): SpanData {\n const spanContext = span.spanContext();\n const startTime = span.startTime[0] * 1000 + span.startTime[1] / 1_000_000;\n const endTime = span.endTime[0] * 1000 + span.endTime[1] / 1_000_000;\n\n // Convert attributes\n const attributes: Record<string, any> = {};\n for (const [key, value] of Object.entries(span.attributes)) {\n attributes[key] = value;\n }\n\n // Convert status\n const statusCode = span.status.code;\n let status: 'OK' | 'ERROR' | 'UNSET';\n switch (statusCode) {\n case 0: {\n status = 'UNSET';\n break;\n }\n case 1: {\n status = 'OK';\n break;\n }\n case 2: {\n status = 'ERROR';\n break;\n }\n default: {\n status = 'UNSET';\n }\n }\n\n // Convert events\n const events = span.events.map((event) => ({\n name: event.name,\n timestamp: event.time[0] * 1000 + event.time[1] / 1_000_000,\n attributes: event.attributes\n ? Object.fromEntries(Object.entries(event.attributes))\n : undefined,\n }));\n\n // Convert links\n const links = span.links.map((link) => ({\n traceId: link.context.traceId,\n spanId: link.context.spanId,\n attributes: link.attributes\n ? Object.fromEntries(Object.entries(link.attributes))\n : undefined,\n }));\n\n return {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n parentSpanId: (span as any).parentSpanId,\n name: span.name,\n kind: this.convertSpanKind(span.kind),\n startTime,\n endTime,\n duration: endTime - startTime,\n attributes,\n status: {\n code: status,\n message: span.status.message,\n },\n events: events.length > 0 ? events : undefined,\n links: links.length > 0 ? links : undefined,\n scope: this.convertScope(span),\n };\n }\n\n private convertScope(span: ReadableSpan): SpanData['scope'] {\n const s =\n (span as any).instrumentationScope ??\n (span as any).instrumentationLibrary;\n return s?.name ? { name: s.name, version: s.version || undefined } : undefined;\n }\n\n /**\n * Convert OpenTelemetry SpanKind to string\n */\n private convertSpanKind(\n kind: number,\n ): 'INTERNAL' | 'SERVER' | 'CLIENT' | 'PRODUCER' | 'CONSUMER' {\n switch (kind) {\n case 0: {\n return 'INTERNAL';\n }\n case 1: {\n return 'SERVER';\n }\n case 2: {\n return 'CLIENT';\n }\n case 3: {\n return 'PRODUCER';\n }\n case 4: {\n return 'CONSUMER';\n }\n default: {\n return 'INTERNAL';\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"exporter.js","names":[],"sources":["../../src/server/exporter.ts"],"sourcesContent":["/**\n * OpenTelemetry SpanExporter that streams spans to DevtoolsServer\n */\n\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base';\nimport type { ExportResult, ExportResultCode } from '@opentelemetry/core';\nimport type { DevtoolsServer } from './server';\nimport type { TraceData, SpanData } from './types';\n\nexport class DevtoolsSpanExporter implements SpanExporter {\n private server: DevtoolsServer;\n private serviceName: string;\n\n constructor(server: DevtoolsServer, serviceName: string = 'unknown-service') {\n this.server = server;\n this.serviceName = serviceName;\n }\n\n /**\n * Export spans to the WebSocket server\n */\n async export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void,\n ): Promise<void> {\n // Immediately call the callback to unblock the span processor\n // Then process the spans asynchronously\n resultCallback({ code: 0 as ExportResultCode });\n\n // Process spans asynchronously without blocking\n Promise.resolve().then(() => {\n try {\n console.log(`[Autotel Exporter] Exporting ${spans.length} span(s)`);\n\n // Group spans by trace ID\n const traceMap = new Map<string, ReadableSpan[]>();\n\n for (const span of spans) {\n const traceId = span.spanContext().traceId;\n if (!traceMap.has(traceId)) {\n traceMap.set(traceId, []);\n }\n traceMap.get(traceId)!.push(span);\n }\n\n // Convert each trace and send to server\n for (const [traceId, traceSpans] of traceMap) {\n const trace = this.convertToTraceData(traceId, traceSpans);\n console.log(\n `[Autotel Exporter] Adding trace ${traceId.slice(0, 16)} with ${traceSpans.length} spans`,\n );\n this.server.addTrace(trace);\n }\n } catch (error) {\n console.error('[Autotel Exporter] Export error:', error);\n }\n });\n }\n\n /**\n * Shutdown the exporter\n */\n async shutdown(): Promise<void> {\n // Nothing to clean up\n }\n\n /**\n * Force flush any buffered spans\n */\n async forceFlush(): Promise<void> {\n // Nothing to flush\n }\n\n /**\n * Convert OpenTelemetry spans to TraceData\n */\n private convertToTraceData(\n traceId: string,\n spans: ReadableSpan[],\n ): TraceData {\n // Convert spans\n const spanData: SpanData[] = spans.map((span) => this.convertSpan(span));\n\n // Find root span (no parent)\n const rootSpan = spanData.find((s) => !s.parentSpanId) || spanData[0];\n\n // Sort spans by start time\n spanData.sort((a, b) => a.startTime - b.startTime);\n\n const startTime = Math.min(...spanData.map((s) => s.startTime));\n const endTime = Math.max(...spanData.map((s) => s.endTime));\n\n // Determine overall status (ERROR if any span errored)\n const hasError = spanData.some((s) => s.status.code === 'ERROR');\n const status = hasError ? 'ERROR' : 'OK';\n\n return {\n traceId,\n correlationId: traceId.slice(0, 16), // First 16 chars\n rootSpan,\n spans: spanData,\n startTime,\n endTime,\n duration: endTime - startTime,\n status: status as 'OK' | 'ERROR' | 'UNSET',\n service: this.serviceName,\n };\n }\n\n /**\n * Convert OpenTelemetry span to SpanData\n */\n private convertSpan(span: ReadableSpan): SpanData {\n const spanContext = span.spanContext();\n const startTime = span.startTime[0] * 1000 + span.startTime[1] / 1_000_000;\n const endTime = span.endTime[0] * 1000 + span.endTime[1] / 1_000_000;\n\n // Convert attributes\n const attributes: Record<string, any> = {};\n for (const [key, value] of Object.entries(span.attributes)) {\n attributes[key] = value;\n }\n\n // Convert status\n const statusCode = span.status.code;\n let status: 'OK' | 'ERROR' | 'UNSET';\n switch (statusCode) {\n case 0: {\n status = 'UNSET';\n break;\n }\n case 1: {\n status = 'OK';\n break;\n }\n case 2: {\n status = 'ERROR';\n break;\n }\n default: {\n status = 'UNSET';\n }\n }\n\n // Convert events\n const events = span.events.map((event) => ({\n name: event.name,\n timestamp: event.time[0] * 1000 + event.time[1] / 1_000_000,\n attributes: event.attributes\n ? Object.fromEntries(Object.entries(event.attributes))\n : undefined,\n }));\n\n // Convert links\n const links = span.links.map((link) => ({\n traceId: link.context.traceId,\n spanId: link.context.spanId,\n attributes: link.attributes\n ? Object.fromEntries(Object.entries(link.attributes))\n : undefined,\n }));\n\n return {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n parentSpanId: (span as any).parentSpanId,\n name: span.name,\n kind: this.convertSpanKind(span.kind),\n startTime,\n endTime,\n duration: endTime - startTime,\n attributes,\n status: {\n code: status,\n message: span.status.message,\n },\n events: events.length > 0 ? events : undefined,\n links: links.length > 0 ? links : undefined,\n scope: this.convertScope(span),\n };\n }\n\n private convertScope(span: ReadableSpan): SpanData['scope'] {\n const s =\n (span as any).instrumentationScope ??\n (span as any).instrumentationLibrary;\n return s?.name ? { name: s.name, version: s.version || undefined } : undefined;\n }\n\n /**\n * Convert OpenTelemetry SpanKind to string\n */\n private convertSpanKind(\n kind: number,\n ): 'INTERNAL' | 'SERVER' | 'CLIENT' | 'PRODUCER' | 'CONSUMER' {\n switch (kind) {\n case 0: {\n return 'INTERNAL';\n }\n case 1: {\n return 'SERVER';\n }\n case 2: {\n return 'CLIENT';\n }\n case 3: {\n return 'PRODUCER';\n }\n case 4: {\n return 'CONSUMER';\n }\n default: {\n return 'INTERNAL';\n }\n }\n }\n}\n"],"mappings":"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"}
|