@mastra/otel-exporter 0.0.0-ai-sdk-network-text-delta-20251017172601 → 0.0.0-allow-to-pass-a-mastra-url-instance-20251105224938
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 +122 -3
- package/README.md +12 -12
- package/dist/index.cjs +162 -145
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +162 -145
- package/dist/index.js.map +1 -1
- package/dist/mastra-span.d.ts +3 -2
- package/dist/mastra-span.d.ts.map +1 -1
- package/dist/span-converter.d.ts +5 -5
- package/dist/span-converter.d.ts.map +1 -1
- package/dist/tracing.d.ts +27 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/types.d.ts +6 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -6
- package/dist/ai-tracing.d.ts +0 -26
- package/dist/ai-tracing.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var observability$1 = require('@mastra/core/observability');
|
|
4
|
+
var observability = require('@mastra/observability');
|
|
5
5
|
var api = require('@opentelemetry/api');
|
|
6
6
|
var resources = require('@opentelemetry/resources');
|
|
7
7
|
var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
8
8
|
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
9
9
|
|
|
10
|
-
// src/
|
|
10
|
+
// src/tracing.ts
|
|
11
11
|
|
|
12
12
|
// src/loadExporter.ts
|
|
13
13
|
var OTLPHttpExporter;
|
|
@@ -209,6 +209,7 @@ var MastraReadableSpan = class {
|
|
|
209
209
|
name;
|
|
210
210
|
kind;
|
|
211
211
|
spanContext;
|
|
212
|
+
parentSpanContext;
|
|
212
213
|
parentSpanId;
|
|
213
214
|
startTime;
|
|
214
215
|
endTime;
|
|
@@ -224,45 +225,45 @@ var MastraReadableSpan = class {
|
|
|
224
225
|
droppedAttributesCount = 0;
|
|
225
226
|
droppedEventsCount = 0;
|
|
226
227
|
droppedLinksCount = 0;
|
|
227
|
-
constructor(
|
|
228
|
-
this.name =
|
|
228
|
+
constructor(span, attributes, kind, parentSpanId, resource, instrumentationLibrary) {
|
|
229
|
+
this.name = span.name;
|
|
229
230
|
this.kind = kind;
|
|
230
231
|
this.attributes = attributes;
|
|
231
232
|
this.parentSpanId = parentSpanId;
|
|
232
233
|
this.links = [];
|
|
233
234
|
this.events = [];
|
|
234
|
-
this.startTime = this.dateToHrTime(
|
|
235
|
-
this.endTime =
|
|
236
|
-
this.ended = !!
|
|
237
|
-
if (
|
|
238
|
-
const durationMs =
|
|
235
|
+
this.startTime = this.dateToHrTime(span.startTime);
|
|
236
|
+
this.endTime = span.endTime ? this.dateToHrTime(span.endTime) : this.startTime;
|
|
237
|
+
this.ended = !!span.endTime;
|
|
238
|
+
if (span.endTime) {
|
|
239
|
+
const durationMs = span.endTime.getTime() - span.startTime.getTime();
|
|
239
240
|
this.duration = [Math.floor(durationMs / 1e3), durationMs % 1e3 * 1e6];
|
|
240
241
|
} else {
|
|
241
242
|
this.duration = [0, 0];
|
|
242
243
|
}
|
|
243
|
-
if (
|
|
244
|
+
if (span.errorInfo) {
|
|
244
245
|
this.status = {
|
|
245
246
|
code: api.SpanStatusCode.ERROR,
|
|
246
|
-
message:
|
|
247
|
+
message: span.errorInfo.message
|
|
247
248
|
};
|
|
248
249
|
this.events.push({
|
|
249
250
|
name: "exception",
|
|
250
251
|
attributes: {
|
|
251
|
-
"exception.message":
|
|
252
|
+
"exception.message": span.errorInfo.message,
|
|
252
253
|
"exception.type": "Error",
|
|
253
|
-
...
|
|
254
|
-
"exception.stacktrace":
|
|
254
|
+
...span.errorInfo.details?.stack && {
|
|
255
|
+
"exception.stacktrace": span.errorInfo.details.stack
|
|
255
256
|
}
|
|
256
257
|
},
|
|
257
258
|
time: this.startTime,
|
|
258
259
|
droppedAttributesCount: 0
|
|
259
260
|
});
|
|
260
|
-
} else if (
|
|
261
|
+
} else if (span.endTime) {
|
|
261
262
|
this.status = { code: api.SpanStatusCode.OK };
|
|
262
263
|
} else {
|
|
263
264
|
this.status = { code: api.SpanStatusCode.UNSET };
|
|
264
265
|
}
|
|
265
|
-
if (
|
|
266
|
+
if (span.isEvent) {
|
|
266
267
|
this.events.push({
|
|
267
268
|
name: "instant_event",
|
|
268
269
|
attributes: {},
|
|
@@ -271,11 +272,19 @@ var MastraReadableSpan = class {
|
|
|
271
272
|
});
|
|
272
273
|
}
|
|
273
274
|
this.spanContext = () => ({
|
|
274
|
-
traceId:
|
|
275
|
-
spanId:
|
|
275
|
+
traceId: span.traceId,
|
|
276
|
+
spanId: span.id,
|
|
276
277
|
traceFlags: api.TraceFlags.SAMPLED,
|
|
277
278
|
isRemote: false
|
|
278
279
|
});
|
|
280
|
+
if (parentSpanId) {
|
|
281
|
+
this.parentSpanContext = {
|
|
282
|
+
traceId: span.traceId,
|
|
283
|
+
spanId: parentSpanId,
|
|
284
|
+
traceFlags: api.TraceFlags.SAMPLED,
|
|
285
|
+
isRemote: false
|
|
286
|
+
};
|
|
287
|
+
}
|
|
279
288
|
this.resource = resource || {};
|
|
280
289
|
this.instrumentationLibrary = instrumentationLibrary || {
|
|
281
290
|
name: "@mastra/otel",
|
|
@@ -296,14 +305,14 @@ var MastraReadableSpan = class {
|
|
|
296
305
|
|
|
297
306
|
// src/span-converter.ts
|
|
298
307
|
var SPAN_KIND_MAPPING = {
|
|
299
|
-
//
|
|
300
|
-
[
|
|
301
|
-
[
|
|
308
|
+
// Model operations are CLIENT spans (calling external AI services)
|
|
309
|
+
[observability$1.SpanType.MODEL_GENERATION]: api.SpanKind.CLIENT,
|
|
310
|
+
[observability$1.SpanType.MODEL_CHUNK]: api.SpanKind.CLIENT,
|
|
302
311
|
// MCP tool calls are CLIENT (external service calls)
|
|
303
|
-
[
|
|
312
|
+
[observability$1.SpanType.MCP_TOOL_CALL]: api.SpanKind.CLIENT,
|
|
304
313
|
// Root spans for agent/workflow are SERVER (entry points)
|
|
305
|
-
[
|
|
306
|
-
[
|
|
314
|
+
[observability$1.SpanType.AGENT_RUN]: api.SpanKind.SERVER,
|
|
315
|
+
[observability$1.SpanType.WORKFLOW_RUN]: api.SpanKind.SERVER
|
|
307
316
|
};
|
|
308
317
|
var SpanConverter = class {
|
|
309
318
|
resource;
|
|
@@ -316,19 +325,19 @@ var SpanConverter = class {
|
|
|
316
325
|
};
|
|
317
326
|
}
|
|
318
327
|
/**
|
|
319
|
-
* Convert a Mastra
|
|
328
|
+
* Convert a Mastra Span to an OpenTelemetry ReadableSpan
|
|
320
329
|
* This preserves Mastra's trace and span IDs
|
|
321
330
|
*/
|
|
322
|
-
convertSpan(
|
|
323
|
-
const spanKind = this.getSpanKind(
|
|
324
|
-
const attributes = this.buildAttributes(
|
|
325
|
-
const spanName = this.buildSpanName(
|
|
326
|
-
const otelSpan = { ...
|
|
331
|
+
convertSpan(Span) {
|
|
332
|
+
const spanKind = this.getSpanKind(Span);
|
|
333
|
+
const attributes = this.buildAttributes(Span);
|
|
334
|
+
const spanName = this.buildSpanName(Span);
|
|
335
|
+
const otelSpan = { ...Span, name: spanName };
|
|
327
336
|
return new MastraReadableSpan(
|
|
328
337
|
otelSpan,
|
|
329
338
|
attributes,
|
|
330
339
|
spanKind,
|
|
331
|
-
|
|
340
|
+
Span.parentSpanId,
|
|
332
341
|
// Use the parentSpanId from the Mastra span directly
|
|
333
342
|
this.resource,
|
|
334
343
|
this.instrumentationLibrary
|
|
@@ -337,139 +346,139 @@ var SpanConverter = class {
|
|
|
337
346
|
/**
|
|
338
347
|
* Get the appropriate SpanKind based on span type and context
|
|
339
348
|
*/
|
|
340
|
-
getSpanKind(
|
|
341
|
-
if (
|
|
342
|
-
if (
|
|
349
|
+
getSpanKind(Span) {
|
|
350
|
+
if (Span.isRootSpan) {
|
|
351
|
+
if (Span.type === observability$1.SpanType.AGENT_RUN || Span.type === observability$1.SpanType.WORKFLOW_RUN) {
|
|
343
352
|
return api.SpanKind.SERVER;
|
|
344
353
|
}
|
|
345
354
|
}
|
|
346
|
-
return SPAN_KIND_MAPPING[
|
|
355
|
+
return SPAN_KIND_MAPPING[Span.type] || api.SpanKind.INTERNAL;
|
|
347
356
|
}
|
|
348
357
|
/**
|
|
349
358
|
* Build OTEL-compliant span name based on span type and attributes
|
|
350
359
|
*/
|
|
351
|
-
buildSpanName(
|
|
352
|
-
switch (
|
|
353
|
-
case
|
|
354
|
-
const attrs =
|
|
360
|
+
buildSpanName(Span) {
|
|
361
|
+
switch (Span.type) {
|
|
362
|
+
case observability$1.SpanType.MODEL_GENERATION: {
|
|
363
|
+
const attrs = Span.attributes;
|
|
355
364
|
const operation = attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
|
|
356
365
|
const model = attrs?.model || "unknown";
|
|
357
366
|
return `${operation} ${model}`;
|
|
358
367
|
}
|
|
359
|
-
case
|
|
360
|
-
case
|
|
361
|
-
const toolAttrs =
|
|
368
|
+
case observability$1.SpanType.TOOL_CALL:
|
|
369
|
+
case observability$1.SpanType.MCP_TOOL_CALL: {
|
|
370
|
+
const toolAttrs = Span.attributes;
|
|
362
371
|
const toolName = toolAttrs?.toolId || "unknown";
|
|
363
372
|
return `tool.execute ${toolName}`;
|
|
364
373
|
}
|
|
365
|
-
case
|
|
366
|
-
const agentAttrs =
|
|
374
|
+
case observability$1.SpanType.AGENT_RUN: {
|
|
375
|
+
const agentAttrs = Span.attributes;
|
|
367
376
|
const agentId = agentAttrs?.agentId || "unknown";
|
|
368
377
|
return `agent.${agentId}`;
|
|
369
378
|
}
|
|
370
|
-
case
|
|
371
|
-
const workflowAttrs =
|
|
379
|
+
case observability$1.SpanType.WORKFLOW_RUN: {
|
|
380
|
+
const workflowAttrs = Span.attributes;
|
|
372
381
|
const workflowId = workflowAttrs?.workflowId || "unknown";
|
|
373
382
|
return `workflow.${workflowId}`;
|
|
374
383
|
}
|
|
375
|
-
case
|
|
376
|
-
return
|
|
384
|
+
case observability$1.SpanType.WORKFLOW_STEP:
|
|
385
|
+
return Span.name;
|
|
377
386
|
default:
|
|
378
|
-
return
|
|
387
|
+
return Span.name;
|
|
379
388
|
}
|
|
380
389
|
}
|
|
381
390
|
/**
|
|
382
|
-
* Build OpenTelemetry attributes from Mastra
|
|
391
|
+
* Build OpenTelemetry attributes from Mastra Span
|
|
383
392
|
* Following OTEL Semantic Conventions for GenAI
|
|
384
393
|
*/
|
|
385
|
-
buildAttributes(
|
|
394
|
+
buildAttributes(Span) {
|
|
386
395
|
const attributes = {};
|
|
387
|
-
attributes["gen_ai.operation.name"] = this.getOperationName(
|
|
388
|
-
attributes["span.kind"] = this.getSpanKindString(
|
|
389
|
-
attributes["mastra.span.type"] =
|
|
390
|
-
attributes["mastra.trace_id"] =
|
|
391
|
-
attributes["mastra.span_id"] =
|
|
392
|
-
if (
|
|
393
|
-
attributes["mastra.parent_span_id"] =
|
|
396
|
+
attributes["gen_ai.operation.name"] = this.getOperationName(Span);
|
|
397
|
+
attributes["span.kind"] = this.getSpanKindString(Span);
|
|
398
|
+
attributes["mastra.span.type"] = Span.type;
|
|
399
|
+
attributes["mastra.trace_id"] = Span.traceId;
|
|
400
|
+
attributes["mastra.span_id"] = Span.id;
|
|
401
|
+
if (Span.parentSpanId) {
|
|
402
|
+
attributes["mastra.parent_span_id"] = Span.parentSpanId;
|
|
394
403
|
}
|
|
395
|
-
if (
|
|
396
|
-
const inputStr = typeof
|
|
404
|
+
if (Span.input !== void 0) {
|
|
405
|
+
const inputStr = typeof Span.input === "string" ? Span.input : JSON.stringify(Span.input);
|
|
397
406
|
attributes["input"] = inputStr;
|
|
398
|
-
if (
|
|
407
|
+
if (Span.type === observability$1.SpanType.MODEL_GENERATION) {
|
|
399
408
|
attributes["gen_ai.prompt"] = inputStr;
|
|
400
|
-
} else if (
|
|
409
|
+
} else if (Span.type === observability$1.SpanType.TOOL_CALL || Span.type === observability$1.SpanType.MCP_TOOL_CALL) {
|
|
401
410
|
attributes["gen_ai.tool.input"] = inputStr;
|
|
402
411
|
}
|
|
403
412
|
}
|
|
404
|
-
if (
|
|
405
|
-
const outputStr = typeof
|
|
413
|
+
if (Span.output !== void 0) {
|
|
414
|
+
const outputStr = typeof Span.output === "string" ? Span.output : JSON.stringify(Span.output);
|
|
406
415
|
attributes["output"] = outputStr;
|
|
407
|
-
if (
|
|
416
|
+
if (Span.type === observability$1.SpanType.MODEL_GENERATION) {
|
|
408
417
|
attributes["gen_ai.completion"] = outputStr;
|
|
409
|
-
} else if (
|
|
418
|
+
} else if (Span.type === observability$1.SpanType.TOOL_CALL || Span.type === observability$1.SpanType.MCP_TOOL_CALL) {
|
|
410
419
|
attributes["gen_ai.tool.output"] = outputStr;
|
|
411
420
|
}
|
|
412
421
|
}
|
|
413
|
-
if (
|
|
414
|
-
const
|
|
415
|
-
if (
|
|
416
|
-
attributes["gen_ai.request.model"] =
|
|
422
|
+
if (Span.type === observability$1.SpanType.MODEL_GENERATION && Span.attributes) {
|
|
423
|
+
const modelAttrs = Span.attributes;
|
|
424
|
+
if (modelAttrs.model) {
|
|
425
|
+
attributes["gen_ai.request.model"] = modelAttrs.model;
|
|
417
426
|
}
|
|
418
|
-
if (
|
|
419
|
-
attributes["gen_ai.system"] =
|
|
427
|
+
if (modelAttrs.provider) {
|
|
428
|
+
attributes["gen_ai.system"] = modelAttrs.provider;
|
|
420
429
|
}
|
|
421
|
-
if (
|
|
422
|
-
const inputTokens =
|
|
423
|
-
const outputTokens =
|
|
430
|
+
if (modelAttrs.usage) {
|
|
431
|
+
const inputTokens = modelAttrs.usage.inputTokens ?? modelAttrs.usage.promptTokens;
|
|
432
|
+
const outputTokens = modelAttrs.usage.outputTokens ?? modelAttrs.usage.completionTokens;
|
|
424
433
|
if (inputTokens !== void 0) {
|
|
425
434
|
attributes["gen_ai.usage.input_tokens"] = inputTokens;
|
|
426
435
|
}
|
|
427
436
|
if (outputTokens !== void 0) {
|
|
428
437
|
attributes["gen_ai.usage.output_tokens"] = outputTokens;
|
|
429
438
|
}
|
|
430
|
-
if (
|
|
431
|
-
attributes["gen_ai.usage.total_tokens"] =
|
|
439
|
+
if (modelAttrs.usage.totalTokens !== void 0) {
|
|
440
|
+
attributes["gen_ai.usage.total_tokens"] = modelAttrs.usage.totalTokens;
|
|
432
441
|
}
|
|
433
|
-
if (
|
|
434
|
-
attributes["gen_ai.usage.reasoning_tokens"] =
|
|
442
|
+
if (modelAttrs.usage.reasoningTokens !== void 0) {
|
|
443
|
+
attributes["gen_ai.usage.reasoning_tokens"] = modelAttrs.usage.reasoningTokens;
|
|
435
444
|
}
|
|
436
|
-
if (
|
|
437
|
-
attributes["gen_ai.usage.cached_input_tokens"] =
|
|
445
|
+
if (modelAttrs.usage.cachedInputTokens !== void 0) {
|
|
446
|
+
attributes["gen_ai.usage.cached_input_tokens"] = modelAttrs.usage.cachedInputTokens;
|
|
438
447
|
}
|
|
439
448
|
}
|
|
440
|
-
if (
|
|
441
|
-
if (
|
|
442
|
-
attributes["gen_ai.request.temperature"] =
|
|
449
|
+
if (modelAttrs.parameters) {
|
|
450
|
+
if (modelAttrs.parameters.temperature !== void 0) {
|
|
451
|
+
attributes["gen_ai.request.temperature"] = modelAttrs.parameters.temperature;
|
|
443
452
|
}
|
|
444
|
-
if (
|
|
445
|
-
attributes["gen_ai.request.max_tokens"] =
|
|
453
|
+
if (modelAttrs.parameters.maxOutputTokens !== void 0) {
|
|
454
|
+
attributes["gen_ai.request.max_tokens"] = modelAttrs.parameters.maxOutputTokens;
|
|
446
455
|
}
|
|
447
|
-
if (
|
|
448
|
-
attributes["gen_ai.request.top_p"] =
|
|
456
|
+
if (modelAttrs.parameters.topP !== void 0) {
|
|
457
|
+
attributes["gen_ai.request.top_p"] = modelAttrs.parameters.topP;
|
|
449
458
|
}
|
|
450
|
-
if (
|
|
451
|
-
attributes["gen_ai.request.top_k"] =
|
|
459
|
+
if (modelAttrs.parameters.topK !== void 0) {
|
|
460
|
+
attributes["gen_ai.request.top_k"] = modelAttrs.parameters.topK;
|
|
452
461
|
}
|
|
453
|
-
if (
|
|
454
|
-
attributes["gen_ai.request.presence_penalty"] =
|
|
462
|
+
if (modelAttrs.parameters.presencePenalty !== void 0) {
|
|
463
|
+
attributes["gen_ai.request.presence_penalty"] = modelAttrs.parameters.presencePenalty;
|
|
455
464
|
}
|
|
456
|
-
if (
|
|
457
|
-
attributes["gen_ai.request.frequency_penalty"] =
|
|
465
|
+
if (modelAttrs.parameters.frequencyPenalty !== void 0) {
|
|
466
|
+
attributes["gen_ai.request.frequency_penalty"] = modelAttrs.parameters.frequencyPenalty;
|
|
458
467
|
}
|
|
459
|
-
if (
|
|
460
|
-
attributes["gen_ai.request.stop_sequences"] = JSON.stringify(
|
|
468
|
+
if (modelAttrs.parameters.stopSequences) {
|
|
469
|
+
attributes["gen_ai.request.stop_sequences"] = JSON.stringify(modelAttrs.parameters.stopSequences);
|
|
461
470
|
}
|
|
462
471
|
}
|
|
463
|
-
if (
|
|
464
|
-
attributes["gen_ai.response.finish_reasons"] =
|
|
472
|
+
if (modelAttrs.finishReason) {
|
|
473
|
+
attributes["gen_ai.response.finish_reasons"] = modelAttrs.finishReason;
|
|
465
474
|
}
|
|
466
475
|
}
|
|
467
|
-
if ((
|
|
468
|
-
const toolAttrs =
|
|
476
|
+
if ((Span.type === observability$1.SpanType.TOOL_CALL || Span.type === observability$1.SpanType.MCP_TOOL_CALL) && Span.attributes) {
|
|
477
|
+
const toolAttrs = Span.attributes;
|
|
469
478
|
if (toolAttrs.toolId) {
|
|
470
479
|
attributes["gen_ai.tool.name"] = toolAttrs.toolId;
|
|
471
480
|
}
|
|
472
|
-
if (
|
|
481
|
+
if (Span.type === observability$1.SpanType.MCP_TOOL_CALL) {
|
|
473
482
|
const mcpAttrs = toolAttrs;
|
|
474
483
|
if (mcpAttrs.mcpServer) {
|
|
475
484
|
attributes["mcp.server"] = mcpAttrs.mcpServer;
|
|
@@ -486,10 +495,11 @@ var SpanConverter = class {
|
|
|
486
495
|
attributes["gen_ai.tool.success"] = toolAttrs.success;
|
|
487
496
|
}
|
|
488
497
|
}
|
|
489
|
-
if (
|
|
490
|
-
const agentAttrs =
|
|
498
|
+
if (Span.type === observability$1.SpanType.AGENT_RUN && Span.attributes) {
|
|
499
|
+
const agentAttrs = Span.attributes;
|
|
491
500
|
if (agentAttrs.agentId) {
|
|
492
501
|
attributes["agent.id"] = agentAttrs.agentId;
|
|
502
|
+
attributes["gen_ai.agent.id"] = agentAttrs.agentId;
|
|
493
503
|
}
|
|
494
504
|
if (agentAttrs.maxSteps) {
|
|
495
505
|
attributes["agent.max_steps"] = agentAttrs.maxSteps;
|
|
@@ -498,8 +508,8 @@ var SpanConverter = class {
|
|
|
498
508
|
attributes["agent.available_tools"] = JSON.stringify(agentAttrs.availableTools);
|
|
499
509
|
}
|
|
500
510
|
}
|
|
501
|
-
if (
|
|
502
|
-
const workflowAttrs =
|
|
511
|
+
if (Span.type === observability$1.SpanType.WORKFLOW_RUN && Span.attributes) {
|
|
512
|
+
const workflowAttrs = Span.attributes;
|
|
503
513
|
if (workflowAttrs.workflowId) {
|
|
504
514
|
attributes["workflow.id"] = workflowAttrs.workflowId;
|
|
505
515
|
}
|
|
@@ -507,19 +517,19 @@ var SpanConverter = class {
|
|
|
507
517
|
attributes["workflow.status"] = workflowAttrs.status;
|
|
508
518
|
}
|
|
509
519
|
}
|
|
510
|
-
if (
|
|
520
|
+
if (Span.errorInfo) {
|
|
511
521
|
attributes["error"] = true;
|
|
512
|
-
attributes["error.type"] =
|
|
513
|
-
attributes["error.message"] =
|
|
514
|
-
if (
|
|
515
|
-
attributes["error.domain"] =
|
|
522
|
+
attributes["error.type"] = Span.errorInfo.id || "unknown";
|
|
523
|
+
attributes["error.message"] = Span.errorInfo.message;
|
|
524
|
+
if (Span.errorInfo.domain) {
|
|
525
|
+
attributes["error.domain"] = Span.errorInfo.domain;
|
|
516
526
|
}
|
|
517
|
-
if (
|
|
518
|
-
attributes["error.category"] =
|
|
527
|
+
if (Span.errorInfo.category) {
|
|
528
|
+
attributes["error.category"] = Span.errorInfo.category;
|
|
519
529
|
}
|
|
520
530
|
}
|
|
521
|
-
if (
|
|
522
|
-
Object.entries(
|
|
531
|
+
if (Span.metadata) {
|
|
532
|
+
Object.entries(Span.metadata).forEach(([key, value]) => {
|
|
523
533
|
if (!attributes[key]) {
|
|
524
534
|
if (value === null || value === void 0) {
|
|
525
535
|
return;
|
|
@@ -532,12 +542,12 @@ var SpanConverter = class {
|
|
|
532
542
|
}
|
|
533
543
|
});
|
|
534
544
|
}
|
|
535
|
-
if (
|
|
536
|
-
attributes["mastra.start_time"] =
|
|
545
|
+
if (Span.startTime) {
|
|
546
|
+
attributes["mastra.start_time"] = Span.startTime.toISOString();
|
|
537
547
|
}
|
|
538
|
-
if (
|
|
539
|
-
attributes["mastra.end_time"] =
|
|
540
|
-
const duration =
|
|
548
|
+
if (Span.endTime) {
|
|
549
|
+
attributes["mastra.end_time"] = Span.endTime.toISOString();
|
|
550
|
+
const duration = Span.endTime.getTime() - Span.startTime.getTime();
|
|
541
551
|
attributes["mastra.duration_ms"] = duration;
|
|
542
552
|
}
|
|
543
553
|
return attributes;
|
|
@@ -545,28 +555,28 @@ var SpanConverter = class {
|
|
|
545
555
|
/**
|
|
546
556
|
* Get the operation name based on span type for gen_ai.operation.name
|
|
547
557
|
*/
|
|
548
|
-
getOperationName(
|
|
549
|
-
switch (
|
|
550
|
-
case
|
|
551
|
-
const attrs =
|
|
558
|
+
getOperationName(Span) {
|
|
559
|
+
switch (Span.type) {
|
|
560
|
+
case observability$1.SpanType.MODEL_GENERATION: {
|
|
561
|
+
const attrs = Span.attributes;
|
|
552
562
|
return attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
|
|
553
563
|
}
|
|
554
|
-
case
|
|
555
|
-
case
|
|
564
|
+
case observability$1.SpanType.TOOL_CALL:
|
|
565
|
+
case observability$1.SpanType.MCP_TOOL_CALL:
|
|
556
566
|
return "tool.execute";
|
|
557
|
-
case
|
|
567
|
+
case observability$1.SpanType.AGENT_RUN:
|
|
558
568
|
return "agent.run";
|
|
559
|
-
case
|
|
569
|
+
case observability$1.SpanType.WORKFLOW_RUN:
|
|
560
570
|
return "workflow.run";
|
|
561
571
|
default:
|
|
562
|
-
return
|
|
572
|
+
return Span.type.replace(/_/g, ".");
|
|
563
573
|
}
|
|
564
574
|
}
|
|
565
575
|
/**
|
|
566
576
|
* Get span kind as string for attribute
|
|
567
577
|
*/
|
|
568
|
-
getSpanKindString(
|
|
569
|
-
const kind = this.getSpanKind(
|
|
578
|
+
getSpanKindString(Span) {
|
|
579
|
+
const kind = this.getSpanKind(Span);
|
|
570
580
|
switch (kind) {
|
|
571
581
|
case api.SpanKind.SERVER:
|
|
572
582
|
return "server";
|
|
@@ -584,21 +594,19 @@ var SpanConverter = class {
|
|
|
584
594
|
}
|
|
585
595
|
};
|
|
586
596
|
|
|
587
|
-
// src/
|
|
588
|
-
var OtelExporter = class {
|
|
597
|
+
// src/tracing.ts
|
|
598
|
+
var OtelExporter = class extends observability.BaseExporter {
|
|
589
599
|
config;
|
|
590
600
|
tracingConfig;
|
|
591
601
|
spanConverter;
|
|
592
602
|
processor;
|
|
593
603
|
exporter;
|
|
594
604
|
isSetup = false;
|
|
595
|
-
isDisabled = false;
|
|
596
|
-
logger;
|
|
597
605
|
name = "opentelemetry";
|
|
598
606
|
constructor(config) {
|
|
607
|
+
super(config);
|
|
599
608
|
this.config = config;
|
|
600
609
|
this.spanConverter = new SpanConverter();
|
|
601
|
-
this.logger = new logger.ConsoleLogger({ level: config.logLevel ?? "warn" });
|
|
602
610
|
if (config.logLevel === "debug") {
|
|
603
611
|
api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG);
|
|
604
612
|
}
|
|
@@ -606,11 +614,11 @@ var OtelExporter = class {
|
|
|
606
614
|
/**
|
|
607
615
|
* Initialize with tracing configuration
|
|
608
616
|
*/
|
|
609
|
-
init(
|
|
610
|
-
this.tracingConfig = config;
|
|
617
|
+
init(options) {
|
|
618
|
+
this.tracingConfig = options.config;
|
|
611
619
|
}
|
|
612
620
|
async setupExporter() {
|
|
613
|
-
if (this.isSetup) return;
|
|
621
|
+
if (this.isSetup || this.exporter) return;
|
|
614
622
|
if (!this.config.provider) {
|
|
615
623
|
this.logger.error(
|
|
616
624
|
'[OtelExporter] Provider configuration is required. Use the "custom" provider for generic endpoints.'
|
|
@@ -625,6 +633,10 @@ var OtelExporter = class {
|
|
|
625
633
|
this.isSetup = true;
|
|
626
634
|
return;
|
|
627
635
|
}
|
|
636
|
+
if (this.config.exporter) {
|
|
637
|
+
this.exporter = this.config.exporter;
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
628
640
|
const endpoint = resolved.endpoint;
|
|
629
641
|
const headers = resolved.headers;
|
|
630
642
|
const protocol = resolved.protocol;
|
|
@@ -678,6 +690,9 @@ var OtelExporter = class {
|
|
|
678
690
|
this.isSetup = true;
|
|
679
691
|
return;
|
|
680
692
|
}
|
|
693
|
+
}
|
|
694
|
+
async setupProcessor() {
|
|
695
|
+
if (this.processor || this.isSetup) return;
|
|
681
696
|
let resource = resources.resourceFromAttributes({
|
|
682
697
|
[semanticConventions.ATTR_SERVICE_NAME]: this.tracingConfig?.serviceName || "mastra-service",
|
|
683
698
|
[semanticConventions.ATTR_SERVICE_VERSION]: "1.0.0",
|
|
@@ -706,13 +721,15 @@ var OtelExporter = class {
|
|
|
706
721
|
this.logger.debug(
|
|
707
722
|
`[OtelExporter] Using BatchSpanProcessor (batch size: ${this.config.batchSize || 512}, delay: 5s)`
|
|
708
723
|
);
|
|
724
|
+
}
|
|
725
|
+
async setup() {
|
|
726
|
+
if (this.isSetup) return;
|
|
727
|
+
await this.setupExporter();
|
|
728
|
+
await this.setupProcessor();
|
|
709
729
|
this.isSetup = true;
|
|
710
730
|
}
|
|
711
|
-
async
|
|
712
|
-
if (
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
if (event.type !== aiTracing.AITracingEventType.SPAN_ENDED) {
|
|
731
|
+
async _exportTracingEvent(event) {
|
|
732
|
+
if (event.type !== observability$1.TracingEventType.SPAN_ENDED) {
|
|
716
733
|
return;
|
|
717
734
|
}
|
|
718
735
|
const span = event.exportedSpan;
|
|
@@ -720,7 +737,7 @@ var OtelExporter = class {
|
|
|
720
737
|
}
|
|
721
738
|
async exportSpan(span) {
|
|
722
739
|
if (!this.isSetup) {
|
|
723
|
-
await this.
|
|
740
|
+
await this.setup();
|
|
724
741
|
}
|
|
725
742
|
if (this.isDisabled || !this.processor) {
|
|
726
743
|
return;
|