@mastra/otel-exporter 0.0.0-netlify-no-bundle-20251127120354 → 0.0.0-new-button-export-20251219130424
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/CHANGELOG.md +129 -12
- package/README.md +47 -3
- package/dist/gen-ai-messages.d.ts +26 -0
- package/dist/gen-ai-messages.d.ts.map +1 -0
- package/dist/gen-ai-semantics.d.ts +40 -0
- package/dist/gen-ai-semantics.d.ts.map +1 -0
- package/dist/index.cjs +450 -364
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +452 -365
- package/dist/index.js.map +1 -1
- package/dist/span-converter.d.ts +26 -35
- package/dist/span-converter.d.ts.map +1 -1
- package/dist/tracing.d.ts +2 -2
- package/dist/tracing.d.ts.map +1 -1
- package/package.json +7 -8
- package/dist/mastra-span.d.ts +0 -38
- package/dist/mastra-span.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { SpanType, TracingEventType } from '@mastra/core/observability';
|
|
2
2
|
import { BaseExporter } from '@mastra/observability';
|
|
3
|
-
import {
|
|
4
|
-
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
3
|
+
import { TraceFlags, SpanKind, SpanStatusCode, diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
|
|
5
4
|
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
5
|
+
import { readFileSync } from 'fs';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
6
8
|
import { ATTR_TELEMETRY_SDK_LANGUAGE, ATTR_TELEMETRY_SDK_VERSION, ATTR_TELEMETRY_SDK_NAME, ATTR_SERVICE_VERSION, ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
|
|
9
|
+
import { ATTR_GEN_AI_OPERATION_NAME, ATTR_GEN_AI_INPUT_MESSAGES, ATTR_GEN_AI_OUTPUT_MESSAGES, ATTR_GEN_AI_REQUEST_MODEL, ATTR_GEN_AI_PROVIDER_NAME, ATTR_GEN_AI_AGENT_ID, ATTR_GEN_AI_AGENT_NAME, ATTR_GEN_AI_REQUEST_TEMPERATURE, ATTR_GEN_AI_REQUEST_MAX_TOKENS, ATTR_GEN_AI_REQUEST_TOP_P, ATTR_GEN_AI_REQUEST_TOP_K, ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY, ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY, ATTR_GEN_AI_REQUEST_STOP_SEQUENCES, ATTR_GEN_AI_REQUEST_SEED, ATTR_GEN_AI_RESPONSE_FINISH_REASONS, ATTR_GEN_AI_RESPONSE_MODEL, ATTR_GEN_AI_RESPONSE_ID, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_GEN_AI_TOOL_NAME, ATTR_GEN_AI_TOOL_DESCRIPTION, ATTR_GEN_AI_CONVERSATION_ID, ATTR_GEN_AI_SYSTEM_INSTRUCTIONS, ATTR_ERROR_TYPE, ATTR_ERROR_MESSAGE, ATTR_GEN_AI_USAGE_INPUT_TOKENS, ATTR_GEN_AI_USAGE_OUTPUT_TOKENS } from '@opentelemetry/semantic-conventions/incubating';
|
|
7
10
|
|
|
8
11
|
// src/tracing.ts
|
|
9
12
|
|
|
@@ -203,396 +206,490 @@ function resolveCustomConfig(config) {
|
|
|
203
206
|
protocol: config.protocol || "http/json"
|
|
204
207
|
};
|
|
205
208
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
ended;
|
|
220
|
-
resource;
|
|
221
|
-
instrumentationLibrary;
|
|
222
|
-
instrumentationScope;
|
|
223
|
-
droppedAttributesCount = 0;
|
|
224
|
-
droppedEventsCount = 0;
|
|
225
|
-
droppedLinksCount = 0;
|
|
226
|
-
constructor(span, attributes, kind, parentSpanId, resource, instrumentationLibrary) {
|
|
227
|
-
this.name = span.name;
|
|
228
|
-
this.kind = kind;
|
|
229
|
-
this.attributes = attributes;
|
|
230
|
-
this.parentSpanId = parentSpanId;
|
|
231
|
-
this.links = [];
|
|
232
|
-
this.events = [];
|
|
233
|
-
this.startTime = this.dateToHrTime(span.startTime);
|
|
234
|
-
this.endTime = span.endTime ? this.dateToHrTime(span.endTime) : this.startTime;
|
|
235
|
-
this.ended = !!span.endTime;
|
|
236
|
-
if (span.endTime) {
|
|
237
|
-
const durationMs = span.endTime.getTime() - span.startTime.getTime();
|
|
238
|
-
this.duration = [Math.floor(durationMs / 1e3), durationMs % 1e3 * 1e6];
|
|
239
|
-
} else {
|
|
240
|
-
this.duration = [0, 0];
|
|
209
|
+
|
|
210
|
+
// src/gen-ai-messages.ts
|
|
211
|
+
var isMastraMessagePart = (p) => {
|
|
212
|
+
return typeof p === "object" && p != null && "type" in p && (p.type === "text" || p.type === "tool-call" || p.type === "tool-result") && (p.type === "text" && "text" in p || p.type === "tool-call" && "toolCallId" in p && "toolName" in p && "input" in p || p.type === "tool-result" && "toolCallId" in p && "toolName" in p && "output" in p);
|
|
213
|
+
};
|
|
214
|
+
var isMastraMessage = (m) => {
|
|
215
|
+
return typeof m === "object" && m != null && "role" in m && "content" in m && (typeof m.content === "string" || Array.isArray(m.content) && m.content.every(isMastraMessagePart));
|
|
216
|
+
};
|
|
217
|
+
var convertMastraMessagesToGenAIMessages = (inputOutputString) => {
|
|
218
|
+
try {
|
|
219
|
+
const parsedIO = JSON.parse(inputOutputString);
|
|
220
|
+
if (typeof parsedIO !== "object" || parsedIO == null || !("messages" in parsedIO) && !("text" in parsedIO)) {
|
|
221
|
+
return inputOutputString;
|
|
241
222
|
}
|
|
242
|
-
if (
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
attributes: {
|
|
250
|
-
"exception.message": span.errorInfo.message,
|
|
251
|
-
"exception.type": "Error",
|
|
252
|
-
...span.errorInfo.details?.stack && {
|
|
253
|
-
"exception.stacktrace": span.errorInfo.details.stack
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
time: this.startTime,
|
|
257
|
-
droppedAttributesCount: 0
|
|
258
|
-
});
|
|
259
|
-
} else if (span.endTime) {
|
|
260
|
-
this.status = { code: SpanStatusCode.OK };
|
|
261
|
-
} else {
|
|
262
|
-
this.status = { code: SpanStatusCode.UNSET };
|
|
263
|
-
}
|
|
264
|
-
if (span.isEvent) {
|
|
265
|
-
this.events.push({
|
|
266
|
-
name: "instant_event",
|
|
267
|
-
attributes: {},
|
|
268
|
-
time: this.startTime,
|
|
269
|
-
droppedAttributesCount: 0
|
|
270
|
-
});
|
|
223
|
+
if ("text" in parsedIO) {
|
|
224
|
+
return JSON.stringify([
|
|
225
|
+
{
|
|
226
|
+
role: "assistant",
|
|
227
|
+
parts: [{ type: "text", content: parsedIO.text }]
|
|
228
|
+
}
|
|
229
|
+
]);
|
|
271
230
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
231
|
+
if (Array.isArray(parsedIO.messages)) {
|
|
232
|
+
return JSON.stringify(
|
|
233
|
+
parsedIO.messages.map((m) => {
|
|
234
|
+
if (!isMastraMessage(m)) {
|
|
235
|
+
return m;
|
|
236
|
+
}
|
|
237
|
+
const role = m.role;
|
|
238
|
+
let parts = [];
|
|
239
|
+
if (Array.isArray(m.content)) {
|
|
240
|
+
parts = m.content.map((c) => {
|
|
241
|
+
switch (c.type) {
|
|
242
|
+
case "text":
|
|
243
|
+
return {
|
|
244
|
+
type: "text",
|
|
245
|
+
content: c.text
|
|
246
|
+
};
|
|
247
|
+
case "tool-call":
|
|
248
|
+
return {
|
|
249
|
+
type: "tool_call",
|
|
250
|
+
id: c.toolCallId,
|
|
251
|
+
name: c.toolName,
|
|
252
|
+
arguments: JSON.stringify(c.input)
|
|
253
|
+
};
|
|
254
|
+
case "tool-result":
|
|
255
|
+
return {
|
|
256
|
+
type: "tool_call_response",
|
|
257
|
+
id: c.toolCallId,
|
|
258
|
+
name: c.toolName,
|
|
259
|
+
response: JSON.stringify(c.output.value)
|
|
260
|
+
};
|
|
261
|
+
default:
|
|
262
|
+
return c;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
} else {
|
|
266
|
+
parts = [
|
|
267
|
+
{
|
|
268
|
+
type: "text",
|
|
269
|
+
content: m.content
|
|
270
|
+
}
|
|
271
|
+
];
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
role,
|
|
275
|
+
parts
|
|
276
|
+
};
|
|
277
|
+
})
|
|
278
|
+
);
|
|
285
279
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
version: "1.0.0"
|
|
290
|
-
};
|
|
291
|
-
this.instrumentationScope = this.instrumentationLibrary;
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Convert JavaScript Date to hrtime format
|
|
295
|
-
*/
|
|
296
|
-
dateToHrTime(date) {
|
|
297
|
-
const ms = date.getTime();
|
|
298
|
-
const seconds = Math.floor(ms / 1e3);
|
|
299
|
-
const nanoseconds = ms % 1e3 * 1e6;
|
|
300
|
-
return [seconds, nanoseconds];
|
|
280
|
+
return inputOutputString;
|
|
281
|
+
} catch {
|
|
282
|
+
return inputOutputString;
|
|
301
283
|
}
|
|
302
284
|
};
|
|
303
285
|
|
|
304
|
-
// src/
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
286
|
+
// src/gen-ai-semantics.ts
|
|
287
|
+
function formatUsageMetrics(usage) {
|
|
288
|
+
if (!usage) return {};
|
|
289
|
+
const metrics = {};
|
|
290
|
+
if (usage.inputTokens !== void 0) {
|
|
291
|
+
metrics[ATTR_GEN_AI_USAGE_INPUT_TOKENS] = usage.inputTokens;
|
|
292
|
+
}
|
|
293
|
+
if (usage.outputTokens !== void 0) {
|
|
294
|
+
metrics[ATTR_GEN_AI_USAGE_OUTPUT_TOKENS] = usage.outputTokens;
|
|
295
|
+
}
|
|
296
|
+
if (usage.outputDetails?.reasoning !== void 0) {
|
|
297
|
+
metrics["gen_ai.usage.reasoning_tokens"] = usage.outputDetails.reasoning;
|
|
298
|
+
}
|
|
299
|
+
if (usage.inputDetails?.cacheRead !== void 0) {
|
|
300
|
+
metrics["gen_ai.usage.cached_input_tokens"] = usage.inputDetails.cacheRead;
|
|
301
|
+
}
|
|
302
|
+
if (usage.inputDetails?.cacheWrite !== void 0) {
|
|
303
|
+
metrics["gen_ai.usage.cache_write_tokens"] = usage.inputDetails.cacheWrite;
|
|
304
|
+
}
|
|
305
|
+
if (usage.inputDetails?.audio !== void 0) {
|
|
306
|
+
metrics["gen_ai.usage.audio_input_tokens"] = usage.inputDetails.audio;
|
|
307
|
+
}
|
|
308
|
+
if (usage.outputDetails?.audio !== void 0) {
|
|
309
|
+
metrics["gen_ai.usage.audio_output_tokens"] = usage.outputDetails.audio;
|
|
310
|
+
}
|
|
311
|
+
return metrics;
|
|
312
|
+
}
|
|
313
|
+
function getOperationName(span) {
|
|
314
|
+
switch (span.type) {
|
|
315
|
+
case SpanType.MODEL_GENERATION:
|
|
316
|
+
return "chat";
|
|
317
|
+
case SpanType.TOOL_CALL:
|
|
318
|
+
case SpanType.MCP_TOOL_CALL:
|
|
319
|
+
return "execute_tool";
|
|
320
|
+
case SpanType.AGENT_RUN:
|
|
321
|
+
return "invoke_agent";
|
|
322
|
+
case SpanType.WORKFLOW_RUN:
|
|
323
|
+
return "invoke_workflow";
|
|
324
|
+
default:
|
|
325
|
+
return span.type.toLowerCase();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
function sanitizeSpanName(name) {
|
|
329
|
+
return name.replace(/[^\p{L}\p{N}._ -]/gu, "");
|
|
330
|
+
}
|
|
331
|
+
function getSpanIdentifier(span) {
|
|
332
|
+
switch (span.type) {
|
|
333
|
+
case SpanType.MODEL_GENERATION: {
|
|
334
|
+
const attrs = span.attributes;
|
|
335
|
+
return attrs?.model ?? "unknown";
|
|
336
|
+
}
|
|
337
|
+
case SpanType.TOOL_CALL:
|
|
338
|
+
case SpanType.MCP_TOOL_CALL: {
|
|
339
|
+
const attrs = span.attributes;
|
|
340
|
+
return attrs?.toolId ?? "unknown";
|
|
341
|
+
}
|
|
342
|
+
case SpanType.AGENT_RUN: {
|
|
343
|
+
const attrs = span.attributes;
|
|
344
|
+
return attrs?.agentName ?? attrs?.agentId ?? "unknown";
|
|
319
345
|
}
|
|
346
|
+
case SpanType.WORKFLOW_RUN: {
|
|
347
|
+
const attrs = span.attributes;
|
|
348
|
+
return attrs?.workflowId ?? "unknown";
|
|
349
|
+
}
|
|
350
|
+
default:
|
|
351
|
+
return null;
|
|
320
352
|
}
|
|
321
|
-
return SPAN_KIND_MAPPING[type] || SpanKind.INTERNAL;
|
|
322
353
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
this.instrumentationLibrary = {
|
|
329
|
-
name: "@mastra/otel-exporter",
|
|
330
|
-
version: "1.0.0"
|
|
331
|
-
};
|
|
354
|
+
function getSpanName(span) {
|
|
355
|
+
const identifier = getSpanIdentifier(span);
|
|
356
|
+
if (identifier) {
|
|
357
|
+
const operation = getOperationName(span);
|
|
358
|
+
return `${operation} ${identifier}`;
|
|
332
359
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
this.instrumentationLibrary
|
|
350
|
-
);
|
|
360
|
+
return sanitizeSpanName(span.name);
|
|
361
|
+
}
|
|
362
|
+
function getAttributes(span) {
|
|
363
|
+
const attributes = {};
|
|
364
|
+
const spanType = span.type.toLowerCase();
|
|
365
|
+
attributes[ATTR_GEN_AI_OPERATION_NAME] = getOperationName(span);
|
|
366
|
+
attributes["mastra.span.type"] = span.type;
|
|
367
|
+
if (span.input !== void 0) {
|
|
368
|
+
const inputStr = typeof span.input === "string" ? span.input : JSON.stringify(span.input);
|
|
369
|
+
if (span.type === SpanType.MODEL_GENERATION) {
|
|
370
|
+
attributes[ATTR_GEN_AI_INPUT_MESSAGES] = convertMastraMessagesToGenAIMessages(inputStr);
|
|
371
|
+
} else if (span.type === SpanType.TOOL_CALL || span.type === SpanType.MCP_TOOL_CALL) {
|
|
372
|
+
attributes["gen_ai.tool.call.arguments"] = inputStr;
|
|
373
|
+
} else {
|
|
374
|
+
attributes[`mastra.${spanType}.input`] = inputStr;
|
|
375
|
+
}
|
|
351
376
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const model = attrs?.model || "unknown";
|
|
361
|
-
return `${operation} ${model}`;
|
|
362
|
-
}
|
|
363
|
-
case SpanType.TOOL_CALL:
|
|
364
|
-
case SpanType.MCP_TOOL_CALL: {
|
|
365
|
-
const toolAttrs = Span.attributes;
|
|
366
|
-
const toolName = toolAttrs?.toolId || "unknown";
|
|
367
|
-
return `tool.execute ${toolName}`;
|
|
368
|
-
}
|
|
369
|
-
case SpanType.AGENT_RUN: {
|
|
370
|
-
const agentAttrs = Span.attributes;
|
|
371
|
-
const agentId = agentAttrs?.agentId || "unknown";
|
|
372
|
-
return `agent.${agentId}`;
|
|
373
|
-
}
|
|
374
|
-
case SpanType.WORKFLOW_RUN: {
|
|
375
|
-
const workflowAttrs = Span.attributes;
|
|
376
|
-
const workflowId = workflowAttrs?.workflowId || "unknown";
|
|
377
|
-
return `workflow.${workflowId}`;
|
|
378
|
-
}
|
|
379
|
-
case SpanType.WORKFLOW_STEP:
|
|
380
|
-
return Span.name;
|
|
381
|
-
default:
|
|
382
|
-
return Span.name;
|
|
377
|
+
if (span.output !== void 0) {
|
|
378
|
+
const outputStr = typeof span.output === "string" ? span.output : JSON.stringify(span.output);
|
|
379
|
+
if (span.type === SpanType.MODEL_GENERATION) {
|
|
380
|
+
attributes[ATTR_GEN_AI_OUTPUT_MESSAGES] = convertMastraMessagesToGenAIMessages(outputStr);
|
|
381
|
+
} else if (span.type === SpanType.TOOL_CALL || span.type === SpanType.MCP_TOOL_CALL) {
|
|
382
|
+
attributes["gen_ai.tool.call.result"] = outputStr;
|
|
383
|
+
} else {
|
|
384
|
+
attributes[`mastra.${spanType}.output`] = outputStr;
|
|
383
385
|
}
|
|
384
386
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
buildAttributes(Span) {
|
|
390
|
-
const attributes = {};
|
|
391
|
-
attributes["gen_ai.operation.name"] = this.getOperationName(Span);
|
|
392
|
-
attributes["span.kind"] = this.getSpanKindString(Span);
|
|
393
|
-
attributes["mastra.span.type"] = Span.type;
|
|
394
|
-
attributes["mastra.trace_id"] = Span.traceId;
|
|
395
|
-
attributes["mastra.span_id"] = Span.id;
|
|
396
|
-
if (Span.parentSpanId) {
|
|
397
|
-
attributes["mastra.parent_span_id"] = Span.parentSpanId;
|
|
398
|
-
}
|
|
399
|
-
if (Span.input !== void 0) {
|
|
400
|
-
const inputStr = typeof Span.input === "string" ? Span.input : JSON.stringify(Span.input);
|
|
401
|
-
attributes["input"] = inputStr;
|
|
402
|
-
if (Span.type === SpanType.MODEL_GENERATION) {
|
|
403
|
-
attributes["gen_ai.prompt"] = inputStr;
|
|
404
|
-
} else if (Span.type === SpanType.TOOL_CALL || Span.type === SpanType.MCP_TOOL_CALL) {
|
|
405
|
-
attributes["gen_ai.tool.input"] = inputStr;
|
|
406
|
-
}
|
|
387
|
+
if (span.type === SpanType.MODEL_GENERATION && span.attributes) {
|
|
388
|
+
const modelAttrs = span.attributes;
|
|
389
|
+
if (modelAttrs.model) {
|
|
390
|
+
attributes[ATTR_GEN_AI_REQUEST_MODEL] = modelAttrs.model;
|
|
407
391
|
}
|
|
408
|
-
if (
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
} else if (Span.type === SpanType.TOOL_CALL || Span.type === SpanType.MCP_TOOL_CALL) {
|
|
414
|
-
attributes["gen_ai.tool.output"] = outputStr;
|
|
415
|
-
}
|
|
392
|
+
if (modelAttrs.provider) {
|
|
393
|
+
attributes[ATTR_GEN_AI_PROVIDER_NAME] = normalizeProvider(modelAttrs.provider);
|
|
394
|
+
}
|
|
395
|
+
if (modelAttrs.agentId) {
|
|
396
|
+
attributes[ATTR_GEN_AI_AGENT_ID] = modelAttrs.agentId;
|
|
416
397
|
}
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
398
|
+
if (modelAttrs.agentName) {
|
|
399
|
+
attributes[ATTR_GEN_AI_AGENT_NAME] = modelAttrs.agentName;
|
|
400
|
+
}
|
|
401
|
+
Object.assign(attributes, formatUsageMetrics(modelAttrs.usage));
|
|
402
|
+
if (modelAttrs.parameters) {
|
|
403
|
+
if (modelAttrs.parameters.temperature !== void 0) {
|
|
404
|
+
attributes[ATTR_GEN_AI_REQUEST_TEMPERATURE] = modelAttrs.parameters.temperature;
|
|
421
405
|
}
|
|
422
|
-
if (modelAttrs.
|
|
423
|
-
attributes[
|
|
406
|
+
if (modelAttrs.parameters.maxOutputTokens !== void 0) {
|
|
407
|
+
attributes[ATTR_GEN_AI_REQUEST_MAX_TOKENS] = modelAttrs.parameters.maxOutputTokens;
|
|
424
408
|
}
|
|
425
|
-
if (modelAttrs.
|
|
426
|
-
|
|
427
|
-
const outputTokens = modelAttrs.usage.outputTokens ?? modelAttrs.usage.completionTokens;
|
|
428
|
-
if (inputTokens !== void 0) {
|
|
429
|
-
attributes["gen_ai.usage.input_tokens"] = inputTokens;
|
|
430
|
-
}
|
|
431
|
-
if (outputTokens !== void 0) {
|
|
432
|
-
attributes["gen_ai.usage.output_tokens"] = outputTokens;
|
|
433
|
-
}
|
|
434
|
-
if (modelAttrs.usage.totalTokens !== void 0) {
|
|
435
|
-
attributes["gen_ai.usage.total_tokens"] = modelAttrs.usage.totalTokens;
|
|
436
|
-
}
|
|
437
|
-
if (modelAttrs.usage.reasoningTokens !== void 0) {
|
|
438
|
-
attributes["gen_ai.usage.reasoning_tokens"] = modelAttrs.usage.reasoningTokens;
|
|
439
|
-
}
|
|
440
|
-
if (modelAttrs.usage.cachedInputTokens !== void 0) {
|
|
441
|
-
attributes["gen_ai.usage.cached_input_tokens"] = modelAttrs.usage.cachedInputTokens;
|
|
442
|
-
}
|
|
409
|
+
if (modelAttrs.parameters.topP !== void 0) {
|
|
410
|
+
attributes[ATTR_GEN_AI_REQUEST_TOP_P] = modelAttrs.parameters.topP;
|
|
443
411
|
}
|
|
444
|
-
if (modelAttrs.parameters) {
|
|
445
|
-
|
|
446
|
-
attributes["gen_ai.request.temperature"] = modelAttrs.parameters.temperature;
|
|
447
|
-
}
|
|
448
|
-
if (modelAttrs.parameters.maxOutputTokens !== void 0) {
|
|
449
|
-
attributes["gen_ai.request.max_tokens"] = modelAttrs.parameters.maxOutputTokens;
|
|
450
|
-
}
|
|
451
|
-
if (modelAttrs.parameters.topP !== void 0) {
|
|
452
|
-
attributes["gen_ai.request.top_p"] = modelAttrs.parameters.topP;
|
|
453
|
-
}
|
|
454
|
-
if (modelAttrs.parameters.topK !== void 0) {
|
|
455
|
-
attributes["gen_ai.request.top_k"] = modelAttrs.parameters.topK;
|
|
456
|
-
}
|
|
457
|
-
if (modelAttrs.parameters.presencePenalty !== void 0) {
|
|
458
|
-
attributes["gen_ai.request.presence_penalty"] = modelAttrs.parameters.presencePenalty;
|
|
459
|
-
}
|
|
460
|
-
if (modelAttrs.parameters.frequencyPenalty !== void 0) {
|
|
461
|
-
attributes["gen_ai.request.frequency_penalty"] = modelAttrs.parameters.frequencyPenalty;
|
|
462
|
-
}
|
|
463
|
-
if (modelAttrs.parameters.stopSequences) {
|
|
464
|
-
attributes["gen_ai.request.stop_sequences"] = JSON.stringify(modelAttrs.parameters.stopSequences);
|
|
465
|
-
}
|
|
412
|
+
if (modelAttrs.parameters.topK !== void 0) {
|
|
413
|
+
attributes[ATTR_GEN_AI_REQUEST_TOP_K] = modelAttrs.parameters.topK;
|
|
466
414
|
}
|
|
467
|
-
if (modelAttrs.
|
|
468
|
-
attributes[
|
|
415
|
+
if (modelAttrs.parameters.presencePenalty !== void 0) {
|
|
416
|
+
attributes[ATTR_GEN_AI_REQUEST_PRESENCE_PENALTY] = modelAttrs.parameters.presencePenalty;
|
|
469
417
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
const toolAttrs = Span.attributes;
|
|
473
|
-
if (toolAttrs.toolId) {
|
|
474
|
-
attributes["gen_ai.tool.name"] = toolAttrs.toolId;
|
|
418
|
+
if (modelAttrs.parameters.frequencyPenalty !== void 0) {
|
|
419
|
+
attributes[ATTR_GEN_AI_REQUEST_FREQUENCY_PENALTY] = modelAttrs.parameters.frequencyPenalty;
|
|
475
420
|
}
|
|
476
|
-
if (
|
|
477
|
-
|
|
478
|
-
if (mcpAttrs.mcpServer) {
|
|
479
|
-
attributes["mcp.server"] = mcpAttrs.mcpServer;
|
|
480
|
-
}
|
|
481
|
-
if (mcpAttrs.serverVersion) {
|
|
482
|
-
attributes["mcp.server.version"] = mcpAttrs.serverVersion;
|
|
483
|
-
}
|
|
484
|
-
} else {
|
|
485
|
-
if (toolAttrs.toolDescription) {
|
|
486
|
-
attributes["gen_ai.tool.description"] = toolAttrs.toolDescription;
|
|
487
|
-
}
|
|
421
|
+
if (modelAttrs.parameters.stopSequences) {
|
|
422
|
+
attributes[ATTR_GEN_AI_REQUEST_STOP_SEQUENCES] = JSON.stringify(modelAttrs.parameters.stopSequences);
|
|
488
423
|
}
|
|
489
|
-
if (
|
|
490
|
-
attributes[
|
|
424
|
+
if (modelAttrs.parameters.seed) {
|
|
425
|
+
attributes[ATTR_GEN_AI_REQUEST_SEED] = modelAttrs.parameters.seed;
|
|
491
426
|
}
|
|
492
427
|
}
|
|
493
|
-
if (
|
|
494
|
-
|
|
495
|
-
if (agentAttrs.agentId) {
|
|
496
|
-
attributes["agent.id"] = agentAttrs.agentId;
|
|
497
|
-
attributes["gen_ai.agent.id"] = agentAttrs.agentId;
|
|
498
|
-
}
|
|
499
|
-
if (agentAttrs.maxSteps) {
|
|
500
|
-
attributes["agent.max_steps"] = agentAttrs.maxSteps;
|
|
501
|
-
}
|
|
502
|
-
if (agentAttrs.availableTools) {
|
|
503
|
-
attributes["agent.available_tools"] = JSON.stringify(agentAttrs.availableTools);
|
|
504
|
-
}
|
|
428
|
+
if (modelAttrs.finishReason) {
|
|
429
|
+
attributes[ATTR_GEN_AI_RESPONSE_FINISH_REASONS] = JSON.stringify([modelAttrs.finishReason]);
|
|
505
430
|
}
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
431
|
+
if (modelAttrs.responseModel) {
|
|
432
|
+
attributes[ATTR_GEN_AI_RESPONSE_MODEL] = modelAttrs.responseModel;
|
|
433
|
+
}
|
|
434
|
+
if (modelAttrs.responseId) {
|
|
435
|
+
attributes[ATTR_GEN_AI_RESPONSE_ID] = modelAttrs.responseId;
|
|
436
|
+
}
|
|
437
|
+
if (modelAttrs.serverAddress) {
|
|
438
|
+
attributes[ATTR_SERVER_ADDRESS] = modelAttrs.serverAddress;
|
|
439
|
+
}
|
|
440
|
+
if (modelAttrs.serverPort !== void 0) {
|
|
441
|
+
attributes[ATTR_SERVER_PORT] = modelAttrs.serverPort;
|
|
514
442
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
443
|
+
}
|
|
444
|
+
if ((span.type === SpanType.TOOL_CALL || span.type === SpanType.MCP_TOOL_CALL) && span.attributes) {
|
|
445
|
+
const toolAttrs = span.attributes;
|
|
446
|
+
if (toolAttrs.toolId) {
|
|
447
|
+
attributes[ATTR_GEN_AI_TOOL_NAME] = toolAttrs.toolId;
|
|
448
|
+
}
|
|
449
|
+
if (span.type === SpanType.MCP_TOOL_CALL) {
|
|
450
|
+
const mcpAttrs = toolAttrs;
|
|
451
|
+
if (mcpAttrs.mcpServer) {
|
|
452
|
+
attributes[ATTR_SERVER_ADDRESS] = mcpAttrs.mcpServer;
|
|
521
453
|
}
|
|
522
|
-
|
|
523
|
-
|
|
454
|
+
} else {
|
|
455
|
+
if (toolAttrs.toolDescription) {
|
|
456
|
+
attributes[ATTR_GEN_AI_TOOL_DESCRIPTION] = toolAttrs.toolDescription;
|
|
524
457
|
}
|
|
525
458
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
} else {
|
|
535
|
-
attributes[key] = value;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
});
|
|
459
|
+
}
|
|
460
|
+
if (span.type === SpanType.AGENT_RUN && span.attributes) {
|
|
461
|
+
const agentAttrs = span.attributes;
|
|
462
|
+
if (agentAttrs.agentId) {
|
|
463
|
+
attributes[ATTR_GEN_AI_AGENT_ID] = agentAttrs.agentId;
|
|
464
|
+
}
|
|
465
|
+
if (agentAttrs.agentName) {
|
|
466
|
+
attributes[ATTR_GEN_AI_AGENT_NAME] = agentAttrs.agentName;
|
|
539
467
|
}
|
|
540
|
-
if (
|
|
541
|
-
attributes[
|
|
468
|
+
if (agentAttrs.conversationId) {
|
|
469
|
+
attributes[ATTR_GEN_AI_CONVERSATION_ID] = agentAttrs.conversationId;
|
|
542
470
|
}
|
|
543
|
-
if (
|
|
544
|
-
attributes[
|
|
545
|
-
const duration = Span.endTime.getTime() - Span.startTime.getTime();
|
|
546
|
-
attributes["mastra.duration_ms"] = duration;
|
|
471
|
+
if (agentAttrs.maxSteps) {
|
|
472
|
+
attributes[`mastra.${spanType}.max_steps`] = agentAttrs.maxSteps;
|
|
547
473
|
}
|
|
548
|
-
|
|
474
|
+
if (agentAttrs.availableTools) {
|
|
475
|
+
attributes[`gen_ai.tool.definitions`] = JSON.stringify(agentAttrs.availableTools);
|
|
476
|
+
}
|
|
477
|
+
attributes[ATTR_GEN_AI_SYSTEM_INSTRUCTIONS] = agentAttrs.instructions;
|
|
478
|
+
}
|
|
479
|
+
if (span.errorInfo) {
|
|
480
|
+
attributes[ATTR_ERROR_TYPE] = span.errorInfo.id || "unknown";
|
|
481
|
+
attributes[ATTR_ERROR_MESSAGE] = span.errorInfo.message;
|
|
482
|
+
if (span.errorInfo.domain) {
|
|
483
|
+
attributes["error.domain"] = span.errorInfo.domain;
|
|
484
|
+
}
|
|
485
|
+
if (span.errorInfo.category) {
|
|
486
|
+
attributes["error.category"] = span.errorInfo.category;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return attributes;
|
|
490
|
+
}
|
|
491
|
+
var PROVIDER_ALIASES = {
|
|
492
|
+
anthropic: ["anthropic", "claude"],
|
|
493
|
+
"aws.bedrock": ["awsbedrock", "bedrock", "amazonbedrock"],
|
|
494
|
+
"azure.ai.inference": ["azureaiinference", "azureinference"],
|
|
495
|
+
"azure.ai.openai": ["azureaiopenai", "azureopenai", "msopenai", "microsoftopenai"],
|
|
496
|
+
cohere: ["cohere"],
|
|
497
|
+
deepseek: ["deepseek"],
|
|
498
|
+
"gcp.gemini": ["gcpgemini", "gemini"],
|
|
499
|
+
"gcp.gen_ai": ["gcpgenai", "googlegenai", "googleai"],
|
|
500
|
+
"gcp.vertex_ai": ["gcpvertexai", "vertexai"],
|
|
501
|
+
groq: ["groq"],
|
|
502
|
+
"ibm.watsonx.ai": ["ibmwatsonxai", "watsonx", "watsonxai"],
|
|
503
|
+
mistral_ai: ["mistral", "mistralai"],
|
|
504
|
+
openai: ["openai", "oai"],
|
|
505
|
+
perplexity: ["perplexity", "pplx"],
|
|
506
|
+
x_ai: ["xai", "x-ai", "x_ai", "x.com ai"]
|
|
507
|
+
};
|
|
508
|
+
function normalizeProviderString(input) {
|
|
509
|
+
return input.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
510
|
+
}
|
|
511
|
+
function normalizeProvider(providerName) {
|
|
512
|
+
const normalized = normalizeProviderString(providerName);
|
|
513
|
+
for (const [canonical, aliases] of Object.entries(PROVIDER_ALIASES)) {
|
|
514
|
+
for (const alias of aliases) {
|
|
515
|
+
if (normalized === alias) {
|
|
516
|
+
return canonical;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return providerName.toLowerCase();
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// src/span-converter.ts
|
|
524
|
+
var SpanConverter = class {
|
|
525
|
+
constructor(params) {
|
|
526
|
+
this.params = params;
|
|
527
|
+
this.format = params.format;
|
|
549
528
|
}
|
|
529
|
+
resource;
|
|
530
|
+
scope;
|
|
531
|
+
initPromise;
|
|
532
|
+
format;
|
|
550
533
|
/**
|
|
551
|
-
*
|
|
534
|
+
* Lazily initialize resource & scope on first use.
|
|
535
|
+
* Subsequent calls reuse the same promise (no races).
|
|
552
536
|
*/
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
const attrs = Span.attributes;
|
|
557
|
-
return attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
|
|
558
|
-
}
|
|
559
|
-
case SpanType.TOOL_CALL:
|
|
560
|
-
case SpanType.MCP_TOOL_CALL:
|
|
561
|
-
return "tool.execute";
|
|
562
|
-
case SpanType.AGENT_RUN:
|
|
563
|
-
return "agent.run";
|
|
564
|
-
case SpanType.WORKFLOW_RUN:
|
|
565
|
-
return "workflow.run";
|
|
566
|
-
default:
|
|
567
|
-
return Span.type.replace(/_/g, ".");
|
|
537
|
+
async initIfNeeded() {
|
|
538
|
+
if (this.initPromise) {
|
|
539
|
+
return this.initPromise;
|
|
568
540
|
}
|
|
541
|
+
this.initPromise = (async () => {
|
|
542
|
+
const packageVersion = await getPackageVersion(this.params.packageName) ?? "unknown";
|
|
543
|
+
const serviceVersion = await getPackageVersion("@mastra/core") ?? "unknown";
|
|
544
|
+
let resource = resourceFromAttributes({
|
|
545
|
+
[ATTR_SERVICE_NAME]: this.params.serviceName || "mastra-service",
|
|
546
|
+
[ATTR_SERVICE_VERSION]: serviceVersion,
|
|
547
|
+
[ATTR_TELEMETRY_SDK_NAME]: this.params.packageName,
|
|
548
|
+
[ATTR_TELEMETRY_SDK_VERSION]: packageVersion,
|
|
549
|
+
[ATTR_TELEMETRY_SDK_LANGUAGE]: "nodejs"
|
|
550
|
+
});
|
|
551
|
+
if (this.params.config?.resourceAttributes) {
|
|
552
|
+
resource = resource.merge(
|
|
553
|
+
// Duplicate attributes from config will override defaults above
|
|
554
|
+
resourceFromAttributes(this.params.config.resourceAttributes)
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
this.resource = resource;
|
|
558
|
+
this.scope = {
|
|
559
|
+
name: this.params.packageName,
|
|
560
|
+
version: packageVersion
|
|
561
|
+
};
|
|
562
|
+
})();
|
|
563
|
+
return this.initPromise;
|
|
569
564
|
}
|
|
570
565
|
/**
|
|
571
|
-
*
|
|
566
|
+
* Convert a Mastra Span to an OpenTelemetry ReadableSpan
|
|
572
567
|
*/
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
568
|
+
async convertSpan(span) {
|
|
569
|
+
await this.initIfNeeded();
|
|
570
|
+
if (!this.resource || !this.scope) {
|
|
571
|
+
throw new Error("SpanConverter not initialized correctly");
|
|
572
|
+
}
|
|
573
|
+
const name = getSpanName(span);
|
|
574
|
+
const kind = getSpanKind(span.type);
|
|
575
|
+
const attributes = getAttributes(span);
|
|
576
|
+
if (span.metadata) {
|
|
577
|
+
for (const [k, v] of Object.entries(span.metadata)) {
|
|
578
|
+
if (v === null || v === void 0) {
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
attributes[`mastra.metadata.${k}`] = typeof v === "object" ? JSON.stringify(v) : v;
|
|
582
|
+
}
|
|
588
583
|
}
|
|
584
|
+
if (span.isRootSpan && span.tags?.length) {
|
|
585
|
+
attributes["mastra.tags"] = JSON.stringify(span.tags);
|
|
586
|
+
}
|
|
587
|
+
const startTime = dateToHrTime(span.startTime);
|
|
588
|
+
const endTime = span.endTime ? dateToHrTime(span.endTime) : startTime;
|
|
589
|
+
const duration = computeDuration(span.startTime, span.endTime);
|
|
590
|
+
const { status, events } = buildStatusAndEvents(span, startTime);
|
|
591
|
+
const spanContext = {
|
|
592
|
+
traceId: span.traceId,
|
|
593
|
+
spanId: span.id,
|
|
594
|
+
traceFlags: TraceFlags.SAMPLED,
|
|
595
|
+
isRemote: false
|
|
596
|
+
};
|
|
597
|
+
const parentSpanContext = span.parentSpanId ? {
|
|
598
|
+
traceId: span.traceId,
|
|
599
|
+
spanId: span.parentSpanId,
|
|
600
|
+
traceFlags: TraceFlags.SAMPLED,
|
|
601
|
+
isRemote: false
|
|
602
|
+
} : void 0;
|
|
603
|
+
const links = [];
|
|
604
|
+
const readable = {
|
|
605
|
+
name,
|
|
606
|
+
kind,
|
|
607
|
+
spanContext: () => spanContext,
|
|
608
|
+
parentSpanContext,
|
|
609
|
+
startTime,
|
|
610
|
+
endTime,
|
|
611
|
+
status,
|
|
612
|
+
attributes,
|
|
613
|
+
links,
|
|
614
|
+
events,
|
|
615
|
+
duration,
|
|
616
|
+
ended: !!span.endTime,
|
|
617
|
+
resource: this.resource,
|
|
618
|
+
instrumentationScope: this.scope,
|
|
619
|
+
droppedAttributesCount: 0,
|
|
620
|
+
droppedEventsCount: 0,
|
|
621
|
+
droppedLinksCount: 0
|
|
622
|
+
};
|
|
623
|
+
return readable;
|
|
589
624
|
}
|
|
590
625
|
};
|
|
626
|
+
async function getPackageVersion(pkgName) {
|
|
627
|
+
try {
|
|
628
|
+
const manifestUrl = new URL(await import.meta.resolve(`${pkgName}/package.json`));
|
|
629
|
+
const path = fileURLToPath(manifestUrl);
|
|
630
|
+
const pkgJson = JSON.parse(readFileSync(path, "utf8"));
|
|
631
|
+
return pkgJson.version;
|
|
632
|
+
} catch {
|
|
633
|
+
return void 0;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
function getSpanKind(type) {
|
|
637
|
+
switch (type) {
|
|
638
|
+
case SpanType.MODEL_GENERATION:
|
|
639
|
+
case SpanType.MCP_TOOL_CALL:
|
|
640
|
+
return SpanKind.CLIENT;
|
|
641
|
+
default:
|
|
642
|
+
return SpanKind.INTERNAL;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
function dateToHrTime(date) {
|
|
646
|
+
const ms = date.getTime();
|
|
647
|
+
const seconds = Math.floor(ms / 1e3);
|
|
648
|
+
const nanoseconds = ms % 1e3 * 1e6;
|
|
649
|
+
return [seconds, nanoseconds];
|
|
650
|
+
}
|
|
651
|
+
function computeDuration(start, end) {
|
|
652
|
+
if (!end) return [0, 0];
|
|
653
|
+
const diffMs = end.getTime() - start.getTime();
|
|
654
|
+
return [Math.floor(diffMs / 1e3), diffMs % 1e3 * 1e6];
|
|
655
|
+
}
|
|
656
|
+
function buildStatusAndEvents(span, defaultTime) {
|
|
657
|
+
const events = [];
|
|
658
|
+
if (span.errorInfo) {
|
|
659
|
+
const status = {
|
|
660
|
+
code: SpanStatusCode.ERROR,
|
|
661
|
+
message: span.errorInfo.message
|
|
662
|
+
};
|
|
663
|
+
events.push({
|
|
664
|
+
name: "exception",
|
|
665
|
+
attributes: {
|
|
666
|
+
"exception.message": span.errorInfo.message,
|
|
667
|
+
"exception.type": "Error",
|
|
668
|
+
...span.errorInfo.details?.stack && {
|
|
669
|
+
"exception.stacktrace": span.errorInfo.details.stack
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
time: defaultTime,
|
|
673
|
+
droppedAttributesCount: 0
|
|
674
|
+
});
|
|
675
|
+
return { status, events };
|
|
676
|
+
}
|
|
677
|
+
if (span.endTime) {
|
|
678
|
+
return {
|
|
679
|
+
status: { code: SpanStatusCode.OK },
|
|
680
|
+
events
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
return {
|
|
684
|
+
status: { code: SpanStatusCode.UNSET },
|
|
685
|
+
events
|
|
686
|
+
};
|
|
687
|
+
}
|
|
591
688
|
|
|
592
689
|
// src/tracing.ts
|
|
593
690
|
var OtelExporter = class extends BaseExporter {
|
|
594
691
|
config;
|
|
595
|
-
|
|
692
|
+
observabilityConfig;
|
|
596
693
|
spanConverter;
|
|
597
694
|
processor;
|
|
598
695
|
exporter;
|
|
@@ -601,7 +698,6 @@ var OtelExporter = class extends BaseExporter {
|
|
|
601
698
|
constructor(config) {
|
|
602
699
|
super(config);
|
|
603
700
|
this.config = config;
|
|
604
|
-
this.spanConverter = new SpanConverter();
|
|
605
701
|
if (config.logLevel === "debug") {
|
|
606
702
|
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
|
|
607
703
|
}
|
|
@@ -610,7 +706,7 @@ var OtelExporter = class extends BaseExporter {
|
|
|
610
706
|
* Initialize with tracing configuration
|
|
611
707
|
*/
|
|
612
708
|
init(options) {
|
|
613
|
-
this.
|
|
709
|
+
this.observabilityConfig = options.config;
|
|
614
710
|
}
|
|
615
711
|
async setupExporter() {
|
|
616
712
|
if (this.isSetup || this.exporter) return;
|
|
@@ -688,21 +784,12 @@ var OtelExporter = class extends BaseExporter {
|
|
|
688
784
|
}
|
|
689
785
|
async setupProcessor() {
|
|
690
786
|
if (this.processor || this.isSetup) return;
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
[ATTR_TELEMETRY_SDK_VERSION]: "1.0.0",
|
|
697
|
-
[ATTR_TELEMETRY_SDK_LANGUAGE]: "nodejs"
|
|
787
|
+
this.spanConverter = new SpanConverter({
|
|
788
|
+
packageName: "@mastra/otel-exporter",
|
|
789
|
+
serviceName: this.observabilityConfig?.serviceName,
|
|
790
|
+
config: this.config,
|
|
791
|
+
format: "GenAI_v1_38_0"
|
|
698
792
|
});
|
|
699
|
-
if (this.config.resourceAttributes) {
|
|
700
|
-
resource = resource.merge(
|
|
701
|
-
// Duplicate attributes from config will override defaults above
|
|
702
|
-
resourceFromAttributes(this.config.resourceAttributes)
|
|
703
|
-
);
|
|
704
|
-
}
|
|
705
|
-
this.spanConverter = new SpanConverter(resource);
|
|
706
793
|
this.processor = new BatchSpanProcessor(this.exporter, {
|
|
707
794
|
maxExportBatchSize: this.config.batchSize || 512,
|
|
708
795
|
// Default batch size
|
|
@@ -738,9 +825,9 @@ var OtelExporter = class extends BaseExporter {
|
|
|
738
825
|
return;
|
|
739
826
|
}
|
|
740
827
|
try {
|
|
741
|
-
const
|
|
828
|
+
const otelSpan = await this.spanConverter.convertSpan(span);
|
|
742
829
|
await new Promise((resolve) => {
|
|
743
|
-
this.processor.onEnd(
|
|
830
|
+
this.processor.onEnd(otelSpan);
|
|
744
831
|
resolve();
|
|
745
832
|
});
|
|
746
833
|
this.logger.debug(
|
|
@@ -757,6 +844,6 @@ var OtelExporter = class extends BaseExporter {
|
|
|
757
844
|
}
|
|
758
845
|
};
|
|
759
846
|
|
|
760
|
-
export {
|
|
847
|
+
export { OtelExporter, SpanConverter, getSpanKind };
|
|
761
848
|
//# sourceMappingURL=index.js.map
|
|
762
849
|
//# sourceMappingURL=index.js.map
|