@mastra/otel-exporter 0.0.0-model-router-unknown-provider-20251017212006 → 0.0.0-netlify-no-bundle-20251127120354
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 +202 -3
- package/README.md +12 -12
- package/dist/index.cjs +170 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +169 -155
- 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 +16 -9
- 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 +16 -10
- 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 = require('@mastra/core/observability');
|
|
4
|
+
var observability$1 = 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,180 +305,177 @@ 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.SpanType.MODEL_GENERATION]: api.SpanKind.CLIENT,
|
|
310
|
+
[observability.SpanType.MODEL_CHUNK]: api.SpanKind.CLIENT,
|
|
302
311
|
// MCP tool calls are CLIENT (external service calls)
|
|
303
|
-
[
|
|
312
|
+
[observability.SpanType.MCP_TOOL_CALL]: api.SpanKind.CLIENT,
|
|
304
313
|
// Root spans for agent/workflow are SERVER (entry points)
|
|
305
|
-
[
|
|
306
|
-
[
|
|
314
|
+
[observability.SpanType.AGENT_RUN]: api.SpanKind.SERVER,
|
|
315
|
+
[observability.SpanType.WORKFLOW_RUN]: api.SpanKind.SERVER
|
|
307
316
|
};
|
|
317
|
+
function getSpanKind(type, isRootSpan) {
|
|
318
|
+
if (isRootSpan) {
|
|
319
|
+
if (type === observability.SpanType.AGENT_RUN || type === observability.SpanType.WORKFLOW_RUN) {
|
|
320
|
+
return api.SpanKind.SERVER;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return SPAN_KIND_MAPPING[type] || api.SpanKind.INTERNAL;
|
|
324
|
+
}
|
|
308
325
|
var SpanConverter = class {
|
|
309
326
|
resource;
|
|
310
327
|
instrumentationLibrary;
|
|
311
328
|
constructor(resource) {
|
|
312
329
|
this.resource = resource;
|
|
313
330
|
this.instrumentationLibrary = {
|
|
314
|
-
name: "@mastra/otel",
|
|
331
|
+
name: "@mastra/otel-exporter",
|
|
315
332
|
version: "1.0.0"
|
|
316
333
|
};
|
|
317
334
|
}
|
|
318
335
|
/**
|
|
319
|
-
* Convert a Mastra
|
|
336
|
+
* Convert a Mastra Span to an OpenTelemetry ReadableSpan
|
|
320
337
|
* This preserves Mastra's trace and span IDs
|
|
321
338
|
*/
|
|
322
|
-
convertSpan(
|
|
323
|
-
const spanKind =
|
|
324
|
-
const attributes = this.buildAttributes(
|
|
325
|
-
const spanName = this.buildSpanName(
|
|
326
|
-
const otelSpan = { ...
|
|
339
|
+
convertSpan(span) {
|
|
340
|
+
const spanKind = getSpanKind(span.type, span.isRootSpan);
|
|
341
|
+
const attributes = this.buildAttributes(span);
|
|
342
|
+
const spanName = this.buildSpanName(span);
|
|
343
|
+
const otelSpan = { ...span, name: spanName };
|
|
327
344
|
return new MastraReadableSpan(
|
|
328
345
|
otelSpan,
|
|
329
346
|
attributes,
|
|
330
347
|
spanKind,
|
|
331
|
-
|
|
348
|
+
span.parentSpanId,
|
|
332
349
|
// Use the parentSpanId from the Mastra span directly
|
|
333
350
|
this.resource,
|
|
334
351
|
this.instrumentationLibrary
|
|
335
352
|
);
|
|
336
353
|
}
|
|
337
|
-
/**
|
|
338
|
-
* Get the appropriate SpanKind based on span type and context
|
|
339
|
-
*/
|
|
340
|
-
getSpanKind(aiSpan) {
|
|
341
|
-
if (aiSpan.isRootSpan) {
|
|
342
|
-
if (aiSpan.type === aiTracing.AISpanType.AGENT_RUN || aiSpan.type === aiTracing.AISpanType.WORKFLOW_RUN) {
|
|
343
|
-
return api.SpanKind.SERVER;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return SPAN_KIND_MAPPING[aiSpan.type] || api.SpanKind.INTERNAL;
|
|
347
|
-
}
|
|
348
354
|
/**
|
|
349
355
|
* Build OTEL-compliant span name based on span type and attributes
|
|
350
356
|
*/
|
|
351
|
-
buildSpanName(
|
|
352
|
-
switch (
|
|
353
|
-
case
|
|
354
|
-
const attrs =
|
|
357
|
+
buildSpanName(Span) {
|
|
358
|
+
switch (Span.type) {
|
|
359
|
+
case observability.SpanType.MODEL_GENERATION: {
|
|
360
|
+
const attrs = Span.attributes;
|
|
355
361
|
const operation = attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
|
|
356
362
|
const model = attrs?.model || "unknown";
|
|
357
363
|
return `${operation} ${model}`;
|
|
358
364
|
}
|
|
359
|
-
case
|
|
360
|
-
case
|
|
361
|
-
const toolAttrs =
|
|
365
|
+
case observability.SpanType.TOOL_CALL:
|
|
366
|
+
case observability.SpanType.MCP_TOOL_CALL: {
|
|
367
|
+
const toolAttrs = Span.attributes;
|
|
362
368
|
const toolName = toolAttrs?.toolId || "unknown";
|
|
363
369
|
return `tool.execute ${toolName}`;
|
|
364
370
|
}
|
|
365
|
-
case
|
|
366
|
-
const agentAttrs =
|
|
371
|
+
case observability.SpanType.AGENT_RUN: {
|
|
372
|
+
const agentAttrs = Span.attributes;
|
|
367
373
|
const agentId = agentAttrs?.agentId || "unknown";
|
|
368
374
|
return `agent.${agentId}`;
|
|
369
375
|
}
|
|
370
|
-
case
|
|
371
|
-
const workflowAttrs =
|
|
376
|
+
case observability.SpanType.WORKFLOW_RUN: {
|
|
377
|
+
const workflowAttrs = Span.attributes;
|
|
372
378
|
const workflowId = workflowAttrs?.workflowId || "unknown";
|
|
373
379
|
return `workflow.${workflowId}`;
|
|
374
380
|
}
|
|
375
|
-
case
|
|
376
|
-
return
|
|
381
|
+
case observability.SpanType.WORKFLOW_STEP:
|
|
382
|
+
return Span.name;
|
|
377
383
|
default:
|
|
378
|
-
return
|
|
384
|
+
return Span.name;
|
|
379
385
|
}
|
|
380
386
|
}
|
|
381
387
|
/**
|
|
382
|
-
* Build OpenTelemetry attributes from Mastra
|
|
388
|
+
* Build OpenTelemetry attributes from Mastra Span
|
|
383
389
|
* Following OTEL Semantic Conventions for GenAI
|
|
384
390
|
*/
|
|
385
|
-
buildAttributes(
|
|
391
|
+
buildAttributes(Span) {
|
|
386
392
|
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"] =
|
|
393
|
+
attributes["gen_ai.operation.name"] = this.getOperationName(Span);
|
|
394
|
+
attributes["span.kind"] = this.getSpanKindString(Span);
|
|
395
|
+
attributes["mastra.span.type"] = Span.type;
|
|
396
|
+
attributes["mastra.trace_id"] = Span.traceId;
|
|
397
|
+
attributes["mastra.span_id"] = Span.id;
|
|
398
|
+
if (Span.parentSpanId) {
|
|
399
|
+
attributes["mastra.parent_span_id"] = Span.parentSpanId;
|
|
394
400
|
}
|
|
395
|
-
if (
|
|
396
|
-
const inputStr = typeof
|
|
401
|
+
if (Span.input !== void 0) {
|
|
402
|
+
const inputStr = typeof Span.input === "string" ? Span.input : JSON.stringify(Span.input);
|
|
397
403
|
attributes["input"] = inputStr;
|
|
398
|
-
if (
|
|
404
|
+
if (Span.type === observability.SpanType.MODEL_GENERATION) {
|
|
399
405
|
attributes["gen_ai.prompt"] = inputStr;
|
|
400
|
-
} else if (
|
|
406
|
+
} else if (Span.type === observability.SpanType.TOOL_CALL || Span.type === observability.SpanType.MCP_TOOL_CALL) {
|
|
401
407
|
attributes["gen_ai.tool.input"] = inputStr;
|
|
402
408
|
}
|
|
403
409
|
}
|
|
404
|
-
if (
|
|
405
|
-
const outputStr = typeof
|
|
410
|
+
if (Span.output !== void 0) {
|
|
411
|
+
const outputStr = typeof Span.output === "string" ? Span.output : JSON.stringify(Span.output);
|
|
406
412
|
attributes["output"] = outputStr;
|
|
407
|
-
if (
|
|
413
|
+
if (Span.type === observability.SpanType.MODEL_GENERATION) {
|
|
408
414
|
attributes["gen_ai.completion"] = outputStr;
|
|
409
|
-
} else if (
|
|
415
|
+
} else if (Span.type === observability.SpanType.TOOL_CALL || Span.type === observability.SpanType.MCP_TOOL_CALL) {
|
|
410
416
|
attributes["gen_ai.tool.output"] = outputStr;
|
|
411
417
|
}
|
|
412
418
|
}
|
|
413
|
-
if (
|
|
414
|
-
const
|
|
415
|
-
if (
|
|
416
|
-
attributes["gen_ai.request.model"] =
|
|
419
|
+
if (Span.type === observability.SpanType.MODEL_GENERATION && Span.attributes) {
|
|
420
|
+
const modelAttrs = Span.attributes;
|
|
421
|
+
if (modelAttrs.model) {
|
|
422
|
+
attributes["gen_ai.request.model"] = modelAttrs.model;
|
|
417
423
|
}
|
|
418
|
-
if (
|
|
419
|
-
attributes["gen_ai.system"] =
|
|
424
|
+
if (modelAttrs.provider) {
|
|
425
|
+
attributes["gen_ai.system"] = modelAttrs.provider;
|
|
420
426
|
}
|
|
421
|
-
if (
|
|
422
|
-
const inputTokens =
|
|
423
|
-
const outputTokens =
|
|
427
|
+
if (modelAttrs.usage) {
|
|
428
|
+
const inputTokens = modelAttrs.usage.inputTokens ?? modelAttrs.usage.promptTokens;
|
|
429
|
+
const outputTokens = modelAttrs.usage.outputTokens ?? modelAttrs.usage.completionTokens;
|
|
424
430
|
if (inputTokens !== void 0) {
|
|
425
431
|
attributes["gen_ai.usage.input_tokens"] = inputTokens;
|
|
426
432
|
}
|
|
427
433
|
if (outputTokens !== void 0) {
|
|
428
434
|
attributes["gen_ai.usage.output_tokens"] = outputTokens;
|
|
429
435
|
}
|
|
430
|
-
if (
|
|
431
|
-
attributes["gen_ai.usage.total_tokens"] =
|
|
436
|
+
if (modelAttrs.usage.totalTokens !== void 0) {
|
|
437
|
+
attributes["gen_ai.usage.total_tokens"] = modelAttrs.usage.totalTokens;
|
|
432
438
|
}
|
|
433
|
-
if (
|
|
434
|
-
attributes["gen_ai.usage.reasoning_tokens"] =
|
|
439
|
+
if (modelAttrs.usage.reasoningTokens !== void 0) {
|
|
440
|
+
attributes["gen_ai.usage.reasoning_tokens"] = modelAttrs.usage.reasoningTokens;
|
|
435
441
|
}
|
|
436
|
-
if (
|
|
437
|
-
attributes["gen_ai.usage.cached_input_tokens"] =
|
|
442
|
+
if (modelAttrs.usage.cachedInputTokens !== void 0) {
|
|
443
|
+
attributes["gen_ai.usage.cached_input_tokens"] = modelAttrs.usage.cachedInputTokens;
|
|
438
444
|
}
|
|
439
445
|
}
|
|
440
|
-
if (
|
|
441
|
-
if (
|
|
442
|
-
attributes["gen_ai.request.temperature"] =
|
|
446
|
+
if (modelAttrs.parameters) {
|
|
447
|
+
if (modelAttrs.parameters.temperature !== void 0) {
|
|
448
|
+
attributes["gen_ai.request.temperature"] = modelAttrs.parameters.temperature;
|
|
443
449
|
}
|
|
444
|
-
if (
|
|
445
|
-
attributes["gen_ai.request.max_tokens"] =
|
|
450
|
+
if (modelAttrs.parameters.maxOutputTokens !== void 0) {
|
|
451
|
+
attributes["gen_ai.request.max_tokens"] = modelAttrs.parameters.maxOutputTokens;
|
|
446
452
|
}
|
|
447
|
-
if (
|
|
448
|
-
attributes["gen_ai.request.top_p"] =
|
|
453
|
+
if (modelAttrs.parameters.topP !== void 0) {
|
|
454
|
+
attributes["gen_ai.request.top_p"] = modelAttrs.parameters.topP;
|
|
449
455
|
}
|
|
450
|
-
if (
|
|
451
|
-
attributes["gen_ai.request.top_k"] =
|
|
456
|
+
if (modelAttrs.parameters.topK !== void 0) {
|
|
457
|
+
attributes["gen_ai.request.top_k"] = modelAttrs.parameters.topK;
|
|
452
458
|
}
|
|
453
|
-
if (
|
|
454
|
-
attributes["gen_ai.request.presence_penalty"] =
|
|
459
|
+
if (modelAttrs.parameters.presencePenalty !== void 0) {
|
|
460
|
+
attributes["gen_ai.request.presence_penalty"] = modelAttrs.parameters.presencePenalty;
|
|
455
461
|
}
|
|
456
|
-
if (
|
|
457
|
-
attributes["gen_ai.request.frequency_penalty"] =
|
|
462
|
+
if (modelAttrs.parameters.frequencyPenalty !== void 0) {
|
|
463
|
+
attributes["gen_ai.request.frequency_penalty"] = modelAttrs.parameters.frequencyPenalty;
|
|
458
464
|
}
|
|
459
|
-
if (
|
|
460
|
-
attributes["gen_ai.request.stop_sequences"] = JSON.stringify(
|
|
465
|
+
if (modelAttrs.parameters.stopSequences) {
|
|
466
|
+
attributes["gen_ai.request.stop_sequences"] = JSON.stringify(modelAttrs.parameters.stopSequences);
|
|
461
467
|
}
|
|
462
468
|
}
|
|
463
|
-
if (
|
|
464
|
-
attributes["gen_ai.response.finish_reasons"] =
|
|
469
|
+
if (modelAttrs.finishReason) {
|
|
470
|
+
attributes["gen_ai.response.finish_reasons"] = modelAttrs.finishReason;
|
|
465
471
|
}
|
|
466
472
|
}
|
|
467
|
-
if ((
|
|
468
|
-
const toolAttrs =
|
|
473
|
+
if ((Span.type === observability.SpanType.TOOL_CALL || Span.type === observability.SpanType.MCP_TOOL_CALL) && Span.attributes) {
|
|
474
|
+
const toolAttrs = Span.attributes;
|
|
469
475
|
if (toolAttrs.toolId) {
|
|
470
476
|
attributes["gen_ai.tool.name"] = toolAttrs.toolId;
|
|
471
477
|
}
|
|
472
|
-
if (
|
|
478
|
+
if (Span.type === observability.SpanType.MCP_TOOL_CALL) {
|
|
473
479
|
const mcpAttrs = toolAttrs;
|
|
474
480
|
if (mcpAttrs.mcpServer) {
|
|
475
481
|
attributes["mcp.server"] = mcpAttrs.mcpServer;
|
|
@@ -486,10 +492,11 @@ var SpanConverter = class {
|
|
|
486
492
|
attributes["gen_ai.tool.success"] = toolAttrs.success;
|
|
487
493
|
}
|
|
488
494
|
}
|
|
489
|
-
if (
|
|
490
|
-
const agentAttrs =
|
|
495
|
+
if (Span.type === observability.SpanType.AGENT_RUN && Span.attributes) {
|
|
496
|
+
const agentAttrs = Span.attributes;
|
|
491
497
|
if (agentAttrs.agentId) {
|
|
492
498
|
attributes["agent.id"] = agentAttrs.agentId;
|
|
499
|
+
attributes["gen_ai.agent.id"] = agentAttrs.agentId;
|
|
493
500
|
}
|
|
494
501
|
if (agentAttrs.maxSteps) {
|
|
495
502
|
attributes["agent.max_steps"] = agentAttrs.maxSteps;
|
|
@@ -498,8 +505,8 @@ var SpanConverter = class {
|
|
|
498
505
|
attributes["agent.available_tools"] = JSON.stringify(agentAttrs.availableTools);
|
|
499
506
|
}
|
|
500
507
|
}
|
|
501
|
-
if (
|
|
502
|
-
const workflowAttrs =
|
|
508
|
+
if (Span.type === observability.SpanType.WORKFLOW_RUN && Span.attributes) {
|
|
509
|
+
const workflowAttrs = Span.attributes;
|
|
503
510
|
if (workflowAttrs.workflowId) {
|
|
504
511
|
attributes["workflow.id"] = workflowAttrs.workflowId;
|
|
505
512
|
}
|
|
@@ -507,19 +514,19 @@ var SpanConverter = class {
|
|
|
507
514
|
attributes["workflow.status"] = workflowAttrs.status;
|
|
508
515
|
}
|
|
509
516
|
}
|
|
510
|
-
if (
|
|
517
|
+
if (Span.errorInfo) {
|
|
511
518
|
attributes["error"] = true;
|
|
512
|
-
attributes["error.type"] =
|
|
513
|
-
attributes["error.message"] =
|
|
514
|
-
if (
|
|
515
|
-
attributes["error.domain"] =
|
|
519
|
+
attributes["error.type"] = Span.errorInfo.id || "unknown";
|
|
520
|
+
attributes["error.message"] = Span.errorInfo.message;
|
|
521
|
+
if (Span.errorInfo.domain) {
|
|
522
|
+
attributes["error.domain"] = Span.errorInfo.domain;
|
|
516
523
|
}
|
|
517
|
-
if (
|
|
518
|
-
attributes["error.category"] =
|
|
524
|
+
if (Span.errorInfo.category) {
|
|
525
|
+
attributes["error.category"] = Span.errorInfo.category;
|
|
519
526
|
}
|
|
520
527
|
}
|
|
521
|
-
if (
|
|
522
|
-
Object.entries(
|
|
528
|
+
if (Span.metadata) {
|
|
529
|
+
Object.entries(Span.metadata).forEach(([key, value]) => {
|
|
523
530
|
if (!attributes[key]) {
|
|
524
531
|
if (value === null || value === void 0) {
|
|
525
532
|
return;
|
|
@@ -532,12 +539,12 @@ var SpanConverter = class {
|
|
|
532
539
|
}
|
|
533
540
|
});
|
|
534
541
|
}
|
|
535
|
-
if (
|
|
536
|
-
attributes["mastra.start_time"] =
|
|
542
|
+
if (Span.startTime) {
|
|
543
|
+
attributes["mastra.start_time"] = Span.startTime.toISOString();
|
|
537
544
|
}
|
|
538
|
-
if (
|
|
539
|
-
attributes["mastra.end_time"] =
|
|
540
|
-
const duration =
|
|
545
|
+
if (Span.endTime) {
|
|
546
|
+
attributes["mastra.end_time"] = Span.endTime.toISOString();
|
|
547
|
+
const duration = Span.endTime.getTime() - Span.startTime.getTime();
|
|
541
548
|
attributes["mastra.duration_ms"] = duration;
|
|
542
549
|
}
|
|
543
550
|
return attributes;
|
|
@@ -545,28 +552,28 @@ var SpanConverter = class {
|
|
|
545
552
|
/**
|
|
546
553
|
* Get the operation name based on span type for gen_ai.operation.name
|
|
547
554
|
*/
|
|
548
|
-
getOperationName(
|
|
549
|
-
switch (
|
|
550
|
-
case
|
|
551
|
-
const attrs =
|
|
555
|
+
getOperationName(Span) {
|
|
556
|
+
switch (Span.type) {
|
|
557
|
+
case observability.SpanType.MODEL_GENERATION: {
|
|
558
|
+
const attrs = Span.attributes;
|
|
552
559
|
return attrs?.resultType === "tool_selection" ? "tool_selection" : "chat";
|
|
553
560
|
}
|
|
554
|
-
case
|
|
555
|
-
case
|
|
561
|
+
case observability.SpanType.TOOL_CALL:
|
|
562
|
+
case observability.SpanType.MCP_TOOL_CALL:
|
|
556
563
|
return "tool.execute";
|
|
557
|
-
case
|
|
564
|
+
case observability.SpanType.AGENT_RUN:
|
|
558
565
|
return "agent.run";
|
|
559
|
-
case
|
|
566
|
+
case observability.SpanType.WORKFLOW_RUN:
|
|
560
567
|
return "workflow.run";
|
|
561
568
|
default:
|
|
562
|
-
return
|
|
569
|
+
return Span.type.replace(/_/g, ".");
|
|
563
570
|
}
|
|
564
571
|
}
|
|
565
572
|
/**
|
|
566
573
|
* Get span kind as string for attribute
|
|
567
574
|
*/
|
|
568
|
-
getSpanKindString(
|
|
569
|
-
const kind =
|
|
575
|
+
getSpanKindString(Span) {
|
|
576
|
+
const kind = getSpanKind(Span.type, Span.isRootSpan);
|
|
570
577
|
switch (kind) {
|
|
571
578
|
case api.SpanKind.SERVER:
|
|
572
579
|
return "server";
|
|
@@ -584,21 +591,19 @@ var SpanConverter = class {
|
|
|
584
591
|
}
|
|
585
592
|
};
|
|
586
593
|
|
|
587
|
-
// src/
|
|
588
|
-
var OtelExporter = class {
|
|
594
|
+
// src/tracing.ts
|
|
595
|
+
var OtelExporter = class extends observability$1.BaseExporter {
|
|
589
596
|
config;
|
|
590
597
|
tracingConfig;
|
|
591
598
|
spanConverter;
|
|
592
599
|
processor;
|
|
593
600
|
exporter;
|
|
594
601
|
isSetup = false;
|
|
595
|
-
isDisabled = false;
|
|
596
|
-
logger;
|
|
597
602
|
name = "opentelemetry";
|
|
598
603
|
constructor(config) {
|
|
604
|
+
super(config);
|
|
599
605
|
this.config = config;
|
|
600
606
|
this.spanConverter = new SpanConverter();
|
|
601
|
-
this.logger = new logger.ConsoleLogger({ level: config.logLevel ?? "warn" });
|
|
602
607
|
if (config.logLevel === "debug") {
|
|
603
608
|
api.diag.setLogger(new api.DiagConsoleLogger(), api.DiagLogLevel.DEBUG);
|
|
604
609
|
}
|
|
@@ -606,11 +611,11 @@ var OtelExporter = class {
|
|
|
606
611
|
/**
|
|
607
612
|
* Initialize with tracing configuration
|
|
608
613
|
*/
|
|
609
|
-
init(
|
|
610
|
-
this.tracingConfig = config;
|
|
614
|
+
init(options) {
|
|
615
|
+
this.tracingConfig = options.config;
|
|
611
616
|
}
|
|
612
617
|
async setupExporter() {
|
|
613
|
-
if (this.isSetup) return;
|
|
618
|
+
if (this.isSetup || this.exporter) return;
|
|
614
619
|
if (!this.config.provider) {
|
|
615
620
|
this.logger.error(
|
|
616
621
|
'[OtelExporter] Provider configuration is required. Use the "custom" provider for generic endpoints.'
|
|
@@ -625,6 +630,10 @@ var OtelExporter = class {
|
|
|
625
630
|
this.isSetup = true;
|
|
626
631
|
return;
|
|
627
632
|
}
|
|
633
|
+
if (this.config.exporter) {
|
|
634
|
+
this.exporter = this.config.exporter;
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
628
637
|
const endpoint = resolved.endpoint;
|
|
629
638
|
const headers = resolved.headers;
|
|
630
639
|
const protocol = resolved.protocol;
|
|
@@ -678,6 +687,9 @@ var OtelExporter = class {
|
|
|
678
687
|
this.isSetup = true;
|
|
679
688
|
return;
|
|
680
689
|
}
|
|
690
|
+
}
|
|
691
|
+
async setupProcessor() {
|
|
692
|
+
if (this.processor || this.isSetup) return;
|
|
681
693
|
let resource = resources.resourceFromAttributes({
|
|
682
694
|
[semanticConventions.ATTR_SERVICE_NAME]: this.tracingConfig?.serviceName || "mastra-service",
|
|
683
695
|
[semanticConventions.ATTR_SERVICE_VERSION]: "1.0.0",
|
|
@@ -706,13 +718,15 @@ var OtelExporter = class {
|
|
|
706
718
|
this.logger.debug(
|
|
707
719
|
`[OtelExporter] Using BatchSpanProcessor (batch size: ${this.config.batchSize || 512}, delay: 5s)`
|
|
708
720
|
);
|
|
721
|
+
}
|
|
722
|
+
async setup() {
|
|
723
|
+
if (this.isSetup) return;
|
|
724
|
+
await this.setupExporter();
|
|
725
|
+
await this.setupProcessor();
|
|
709
726
|
this.isSetup = true;
|
|
710
727
|
}
|
|
711
|
-
async
|
|
712
|
-
if (
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
if (event.type !== aiTracing.AITracingEventType.SPAN_ENDED) {
|
|
728
|
+
async _exportTracingEvent(event) {
|
|
729
|
+
if (event.type !== observability.TracingEventType.SPAN_ENDED) {
|
|
716
730
|
return;
|
|
717
731
|
}
|
|
718
732
|
const span = event.exportedSpan;
|
|
@@ -720,7 +734,7 @@ var OtelExporter = class {
|
|
|
720
734
|
}
|
|
721
735
|
async exportSpan(span) {
|
|
722
736
|
if (!this.isSetup) {
|
|
723
|
-
await this.
|
|
737
|
+
await this.setup();
|
|
724
738
|
}
|
|
725
739
|
if (this.isDisabled || !this.processor) {
|
|
726
740
|
return;
|
|
@@ -745,6 +759,9 @@ var OtelExporter = class {
|
|
|
745
759
|
}
|
|
746
760
|
};
|
|
747
761
|
|
|
762
|
+
exports.MastraReadableSpan = MastraReadableSpan;
|
|
748
763
|
exports.OtelExporter = OtelExporter;
|
|
764
|
+
exports.SpanConverter = SpanConverter;
|
|
765
|
+
exports.getSpanKind = getSpanKind;
|
|
749
766
|
//# sourceMappingURL=index.cjs.map
|
|
750
767
|
//# sourceMappingURL=index.cjs.map
|