@mastra/sentry 1.0.0-beta.2 → 1.0.0-beta.4

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 CHANGED
@@ -1,5 +1,45 @@
1
1
  # @mastra/sentry
2
2
 
3
+ ## 1.0.0-beta.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Added `flush()` method to observability exporters and instances for serverless environments ([#12003](https://github.com/mastra-ai/mastra/pull/12003))
8
+
9
+ This feature allows flushing buffered spans without shutting down the exporter, which is useful in serverless environments like Vercel's fluid compute where runtime instances can be reused across multiple requests.
10
+
11
+ **New API:**
12
+
13
+ ```typescript
14
+ // Flush all exporters via the observability instance
15
+ const observability = mastra.getObservability();
16
+ await observability.flush();
17
+
18
+ // Or flush individual exporters
19
+ const exporters = observability.getExporters();
20
+ await exporters[0].flush();
21
+ ```
22
+
23
+ **Why this matters:**
24
+
25
+ In serverless environments, you may need to ensure all spans are exported before the runtime instance is terminated, while keeping the exporter active for future requests. Unlike shutdown(), flush() does not release resources or prevent future exports.
26
+
27
+ Closes #11372
28
+
29
+ - Updated dependencies [[`1dbd8c7`](https://github.com/mastra-ai/mastra/commit/1dbd8c729fb6536ec52f00064d76b80253d346e9), [`1dbd8c7`](https://github.com/mastra-ai/mastra/commit/1dbd8c729fb6536ec52f00064d76b80253d346e9), [`c59e13c`](https://github.com/mastra-ai/mastra/commit/c59e13c7688284bd96b2baee3e314335003548de), [`f9a2509`](https://github.com/mastra-ai/mastra/commit/f9a25093ea72d210a5e52cfcb3bcc8b5e02dc25c), [`7a010c5`](https://github.com/mastra-ai/mastra/commit/7a010c56b846a313a49ae42fccd3d8de2b9f292d)]:
30
+ - @mastra/core@1.0.0-beta.24
31
+ - @mastra/observability@1.0.0-beta.13
32
+ - @mastra/otel-exporter@1.0.0-beta.15
33
+
34
+ ## 1.0.0-beta.3
35
+
36
+ ### Patch Changes
37
+
38
+ - Updated dependencies [[`c8417b4`](https://github.com/mastra-ai/mastra/commit/c8417b41d9f3486854dc7842d977fbe5e2166264), [`dd4f34c`](https://github.com/mastra-ai/mastra/commit/dd4f34c78cbae24063463475b0619575c415f9b8)]:
39
+ - @mastra/core@1.0.0-beta.23
40
+ - @mastra/observability@1.0.0-beta.12
41
+ - @mastra/otel-exporter@1.0.0-beta.14
42
+
3
43
  ## 1.0.0-beta.2
4
44
 
5
45
  ### Major Changes
package/LICENSE.md ADDED
@@ -0,0 +1,15 @@
1
+ # Apache License 2.0
2
+
3
+ Copyright (c) 2025 Kepler Software, Inc.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
package/dist/index.cjs CHANGED
@@ -73,19 +73,19 @@ var ATTRIBUTE_KEYS = {
73
73
  };
74
74
  var SentryExporter = class extends observability.BaseExporter {
75
75
  name = "sentry";
76
- config;
76
+ sentryConfig;
77
77
  spanMap = /* @__PURE__ */ new Map();
78
78
  skippedSpans = /* @__PURE__ */ new Map();
79
79
  initialized = false;
80
80
  constructor(config = {}) {
81
81
  super(config);
82
- this.config = {
82
+ this.sentryConfig = {
83
83
  dsn: config.dsn ?? process.env.SENTRY_DSN ?? "",
84
84
  environment: config.environment ?? process.env.SENTRY_ENVIRONMENT ?? "production",
85
85
  tracesSampleRate: config.tracesSampleRate ?? 1,
86
86
  release: config.release ?? process.env.SENTRY_RELEASE ?? ""
87
87
  };
88
- if (!this.config.dsn) {
88
+ if (!this.sentryConfig.dsn) {
89
89
  const dsnSource = config.dsn ? "from config" : process.env.SENTRY_DSN ? "from env" : "missing";
90
90
  this.setDisabled(
91
91
  `Missing required DSN (dsn: ${dsnSource}). Set SENTRY_DSN environment variable or pass it in config.`
@@ -94,10 +94,10 @@ var SentryExporter = class extends observability.BaseExporter {
94
94
  }
95
95
  try {
96
96
  Sentry__namespace.init({
97
- dsn: this.config.dsn,
98
- environment: this.config.environment,
99
- tracesSampleRate: this.config.tracesSampleRate,
100
- release: this.config.release,
97
+ dsn: this.sentryConfig.dsn,
98
+ environment: this.sentryConfig.environment,
99
+ tracesSampleRate: this.sentryConfig.tracesSampleRate,
100
+ release: this.sentryConfig.release,
101
101
  ...config.options
102
102
  });
103
103
  this.initialized = true;
@@ -455,8 +455,22 @@ var SentryExporter = class extends observability.BaseExporter {
455
455
  }
456
456
  }
457
457
  // ============================================================================
458
- // Shutdown
458
+ // Flush and Shutdown
459
459
  // ============================================================================
460
+ /**
461
+ * Force flush any buffered spans without shutting down the exporter.
462
+ * This is useful in serverless environments where you need to ensure spans
463
+ * are exported before the runtime instance is terminated.
464
+ */
465
+ async flush() {
466
+ if (!this.initialized) return;
467
+ try {
468
+ await Sentry__namespace.flush(2e3);
469
+ this.logger.debug("Sentry exporter: Flushed pending events");
470
+ } catch (error) {
471
+ this.logger.error("Sentry exporter: Error flushing events", { error });
472
+ }
473
+ }
460
474
  async shutdown() {
461
475
  for (const [spanId, spanData] of this.spanMap.entries()) {
462
476
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tracing.ts"],"names":["SpanType","BaseExporter","Sentry","TracingEventType","getGenAISpanName","getGenAIAttributes"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Sentry Exporter for Mastra Observability\n *\n * Sends observability data to Sentry for AI tracing and monitoring.\n * Uses Sentry's modern span model (v8+) with OpenTelemetry semantic conventions.\n *\n * Spans are hierarchically organized: AGENT_RUN -> MODEL_GENERATION -> TOOL_CALL\n * MODEL_STEP and MODEL_CHUNK spans are skipped to simplify the trace hierarchy.\n */\n\nimport type {\n TracingEvent,\n AnyExportedSpan,\n ModelGenerationAttributes,\n ToolCallAttributes,\n AgentRunAttributes,\n WorkflowRunAttributes,\n WorkflowStepAttributes,\n UsageStats,\n} from '@mastra/core/observability';\nimport { SpanType, TracingEventType } from '@mastra/core/observability';\nimport type { BaseExporterConfig } from '@mastra/observability';\nimport { BaseExporter } from '@mastra/observability';\nimport { getAttributes as getGenAIAttributes, getSpanName as getGenAISpanName } from '@mastra/otel-exporter';\nimport * as Sentry from '@sentry/node';\n\nconst SPAN_TYPE_CONFIG: Record<SpanType, { opType: string; opName: string }> = {\n [SpanType.AGENT_RUN]: { opType: 'gen_ai.invoke_agent', opName: 'invoke_agent' },\n [SpanType.MODEL_GENERATION]: { opType: 'gen_ai.chat', opName: 'chat' },\n [SpanType.TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.MCP_TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.WORKFLOW_RUN]: { opType: 'workflow.run', opName: 'workflow' },\n [SpanType.WORKFLOW_STEP]: { opType: 'workflow.step', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_PARALLEL]: { opType: 'workflow.parallel', opName: 'step' },\n [SpanType.WORKFLOW_LOOP]: { opType: 'workflow.loop', opName: 'step' },\n [SpanType.WORKFLOW_SLEEP]: { opType: 'workflow.sleep', opName: 'step' },\n [SpanType.WORKFLOW_WAIT_EVENT]: { opType: 'workflow.wait', opName: 'step' },\n [SpanType.PROCESSOR_RUN]: { opType: 'ai.processor', opName: 'step' },\n [SpanType.GENERIC]: { opType: 'ai.span', opName: 'span' },\n [SpanType.MODEL_STEP]: { opType: 'ai.span', opName: 'step' },\n [SpanType.MODEL_CHUNK]: { opType: 'ai.span', opName: 'step' },\n};\n\nconst ATTRIBUTE_KEYS = {\n SPAN_TYPE: 'ai.span.type',\n ORIGIN: 'sentry.origin',\n TAGS: 'tags',\n INPUT: 'input',\n OUTPUT: 'output',\n GEN_AI_REQUEST_STREAM: 'gen_ai.request.stream',\n GEN_AI_RESPONSE_MODEL: 'gen_ai.response.model',\n GEN_AI_RESPONSE_STREAMING: 'gen_ai.response.streaming',\n GEN_AI_RESPONSE_TOOL_CALLS: 'gen_ai.response.tool_calls',\n GEN_AI_RESPONSE_TEXT: 'gen_ai.response.text',\n GEN_AI_COMPLETION_START_TIME: 'gen_ai.completion_start_time',\n GEN_AI_TOOL_CALL_ID: 'gen_ai.tool.call.id',\n TOOL_SUCCESS: 'tool.success',\n GEN_AI_PIPELINE_NAME: 'gen_ai.pipeline.name',\n GEN_AI_AGENT_PROMPT: 'gen_ai.agent.prompt',\n WORKFLOW_ID: 'workflow.id',\n WORKFLOW_STATUS: 'workflow.status',\n WORKFLOW_STEP_ID: 'workflow.step.id',\n WORKFLOW_STEP_STATUS: 'workflow.step.status',\n GEN_AI_USAGE_INPUT_TOKENS: 'gen_ai.usage.input_tokens',\n GEN_AI_USAGE_OUTPUT_TOKENS: 'gen_ai.usage.output_tokens',\n GEN_AI_USAGE_TOTAL_TOKENS: 'gen_ai.usage.total_tokens',\n GEN_AI_USAGE_CACHE_READ_TOKENS: 'gen_ai.usage.cache_read_input_tokens',\n GEN_AI_USAGE_CACHE_WRITE_TOKENS: 'gen_ai.usage.cache_write_input_tokens',\n GEN_AI_USAGE_REASONING_TOKENS: 'gen_ai.usage.reasoning_tokens',\n} as const;\n\nexport interface SentryExporterConfig extends BaseExporterConfig {\n // Sentry SDK options (passed to Sentry.init())\n /** Data Source Name - tells the SDK where to send events */\n dsn?: string;\n /** Deployment environment (enables filtering issues and alerts by environment) */\n environment?: string;\n /** Percentage of transactions sent to Sentry (0.0 = 0%, 1.0 = 100%) */\n tracesSampleRate?: number;\n /** Version of your code deployed (helps identify regressions and track deployments) */\n release?: string;\n /** Additional Sentry SDK options (integrations, beforeSend, etc.) */\n options?: Partial<Sentry.NodeOptions>;\n}\n\n/**\n * Internal span tracking data.\n * generation tracks the single MODEL_GENERATION for AGENT_RUN response attributes.\n * toolCalls tracks child tool calls for MODEL_GENERATION spans.\n */\ntype SpanData = {\n span: Sentry.Span;\n spanType: SpanType;\n generation?: {\n model?: string;\n output?: any;\n usage?: UsageStats;\n };\n toolCalls?: Array<{\n name: string;\n id?: string;\n type?: string;\n }>;\n};\n\nexport class SentryExporter extends BaseExporter {\n name = 'sentry';\n private config: Required<Omit<SentryExporterConfig, 'logger' | 'logLevel' | 'options'>>;\n private spanMap = new Map<string, SpanData>();\n private skippedSpans = new Map<string, string>();\n private initialized = false;\n\n constructor(config: SentryExporterConfig = {}) {\n super(config);\n\n this.config = {\n dsn: config.dsn ?? process.env.SENTRY_DSN ?? '',\n environment: config.environment ?? process.env.SENTRY_ENVIRONMENT ?? 'production',\n tracesSampleRate: config.tracesSampleRate ?? 1.0,\n release: config.release ?? process.env.SENTRY_RELEASE ?? '',\n };\n\n if (!this.config.dsn) {\n const dsnSource = config.dsn ? 'from config' : process.env.SENTRY_DSN ? 'from env' : 'missing';\n this.setDisabled(\n `Missing required DSN (dsn: ${dsnSource}). Set SENTRY_DSN environment variable or pass it in config.`,\n );\n return;\n }\n\n try {\n Sentry.init({\n dsn: this.config.dsn,\n environment: this.config.environment,\n tracesSampleRate: this.config.tracesSampleRate,\n release: this.config.release,\n ...config.options,\n });\n this.initialized = true;\n } catch (error) {\n this.setDisabled(`Failed to initialize Sentry: ${error}`);\n }\n }\n\n // ============================================================================\n // Main Event Handlers\n // ============================================================================\n\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (!this.initialized) return;\n\n const { type, exportedSpan } = event;\n\n if (exportedSpan.isEvent) {\n this.handleEventSpan(exportedSpan);\n return;\n }\n\n // Skip MODEL_CHUNK and MODEL_STEP spans to simplify trace hierarchy.\n // We store them in skippedSpans to preserve parent-child relationships:\n // when a child span references a skipped span as parent, resolveParentSpanId()\n // walks up the chain to find the first non-skipped ancestor.\n if (exportedSpan.type === SpanType.MODEL_CHUNK || exportedSpan.type === SpanType.MODEL_STEP) {\n if (type === TracingEventType.SPAN_STARTED) {\n this.skippedSpans.set(exportedSpan.id, exportedSpan.parentSpanId || '');\n } else if (type === TracingEventType.SPAN_ENDED) {\n this.skippedSpans.delete(exportedSpan.id);\n }\n return;\n }\n\n switch (type) {\n case TracingEventType.SPAN_STARTED:\n await this.handleSpanStarted(exportedSpan);\n break;\n case TracingEventType.SPAN_UPDATED:\n await this.handleSpanUpdated(exportedSpan);\n break;\n case TracingEventType.SPAN_ENDED:\n await this.handleSpanEnded(exportedSpan);\n break;\n }\n }\n\n private handleEventSpan(span: AnyExportedSpan): void {\n Sentry.addBreadcrumb({\n type: 'default',\n category: span.type,\n message: span.name,\n level: span.errorInfo ? 'error' : 'info',\n data: {\n spanId: span.id,\n traceId: span.traceId,\n ...(span.input && { input: this.serializeValue(span.input) }),\n ...(span.output && { output: this.serializeValue(span.output) }),\n ...(span.metadata && { metadata: span.metadata }),\n ...(span.attributes && { attributes: span.attributes }),\n },\n timestamp: span.startTime.getTime() / 1000,\n });\n }\n\n private async handleSpanStarted(span: AnyExportedSpan): Promise<void> {\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n\n const sentrySpan = Sentry.startInactiveSpan({\n op: this.getOperationType(span),\n name: getGenAISpanName(span),\n startTime: span.startTime.getTime(),\n forceTransaction: span.isRootSpan,\n parentSpan: resolvedParentId ? this.spanMap.get(resolvedParentId)?.span : undefined,\n });\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n this.spanMap.set(span.id, {\n span: sentrySpan,\n spanType: span.type,\n });\n\n // Track tool calls as children of MODEL_GENERATION spans for gen_ai.response.tool_calls attribute\n if (span.type === SpanType.TOOL_CALL && resolvedParentId) {\n this.trackToolCallForParent(span, resolvedParentId);\n }\n }\n\n private async handleSpanUpdated(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span update');\n return;\n }\n // Attributes are set on SPAN_STARTED and finalized on SPAN_ENDED.\n // If dynamic updates become necessary, add spanData.span.setAttributes() here.\n }\n\n private async handleSpanEnded(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span end');\n return;\n }\n\n const { span: sentrySpan } = spanData;\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n if (span.type === SpanType.MODEL_GENERATION) {\n // Set gen_ai.response.tool_calls if this generation had tool calls\n this.applyToolCallsAttribute(spanData);\n\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n if (resolvedParentId) {\n const parentData = this.spanMap.get(resolvedParentId);\n if (parentData?.spanType === SpanType.AGENT_RUN) {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n parentData.generation = {\n model: modelAttr.model,\n output: span.output,\n usage: modelAttr.usage,\n };\n }\n }\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n // Apply token usage from the single child MODEL_GENERATION span\n // (there is only ever one MODEL_GENERATION span per AGENT_RUN)\n this.applyUsageFromGeneration(spanData);\n\n this.setGenerationResponseAttributes(spanData);\n }\n\n if (span.errorInfo) {\n sentrySpan.setStatus({\n code: 2,\n message: span.errorInfo.message,\n });\n\n Sentry.captureException(span.errorInfo.message, {\n contexts: {\n trace: { trace_id: span.traceId, span_id: span.id },\n span_info: {\n name: span.name,\n type: span.type,\n error_id: span.errorInfo.id,\n error_category: span.errorInfo.category,\n },\n },\n });\n }\n\n const endTime = span.endTime ? span.endTime.getTime() : undefined;\n sentrySpan.end(endTime);\n this.spanMap.delete(span.id);\n }\n\n // ============================================================================\n // Span Creation Helpers\n // ============================================================================\n\n private resolveParentSpanId(parentSpanId: string | undefined): string | undefined {\n if (!parentSpanId) return undefined;\n\n let currentParentId: string | undefined = parentSpanId;\n while (currentParentId && this.skippedSpans.has(currentParentId)) {\n currentParentId = this.skippedSpans.get(currentParentId);\n if (!currentParentId) break;\n }\n\n return currentParentId;\n }\n\n private getOperationType(span: AnyExportedSpan): string {\n const config = SPAN_TYPE_CONFIG[span.type];\n return config ? config.opType : 'ai.span';\n }\n\n private buildSpanAttributes(span: AnyExportedSpan): Record<string, any> {\n const attributes = getGenAIAttributes(span) as Record<string, any>;\n\n attributes[ATTRIBUTE_KEYS.SPAN_TYPE] = span.type;\n attributes[ATTRIBUTE_KEYS.ORIGIN] = 'auto.ai.mastra';\n\n if (span.metadata) {\n Object.entries(span.metadata).forEach(([key, value]) => {\n if (value !== undefined && value !== null && key !== 'langfuse') {\n attributes[`metadata.${key}`] = this.serializeValue(value);\n }\n });\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TAGS, span.tags?.join(','));\n\n this.addInputOutputAttributes(attributes, span);\n\n if (span.type === SpanType.MODEL_GENERATION) {\n this.addModelGenerationAttributes(attributes, span);\n }\n\n if (span.type === SpanType.TOOL_CALL) {\n this.addToolCallAttributes(attributes, span);\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n this.addAgentRunAttributes(attributes, span);\n }\n\n if (span.type === SpanType.WORKFLOW_RUN) {\n const workflowAttr = span.attributes as WorkflowRunAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STATUS, workflowAttr.status);\n }\n\n if (span.type === SpanType.WORKFLOW_STEP) {\n const stepAttr = span.attributes as WorkflowStepAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_STATUS, stepAttr.status);\n }\n\n return attributes;\n }\n\n // ============================================================================\n // Sentry-Specific Attribute Formatters\n // ============================================================================\n\n /**\n * Adds Sentry-specific input/output attributes that complement GenAI semantic conventions.\n * Adds 'input' and 'output' keys for Sentry UI compatibility.\n */\n private addInputOutputAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n if (span.input !== undefined) {\n attributes[ATTRIBUTE_KEYS.INPUT] = this.serializeValue(span.input);\n }\n\n if (span.output !== undefined) {\n attributes[ATTRIBUTE_KEYS.OUTPUT] = this.serializeValue(span.output);\n\n // Extract text for MODEL_GENERATION spans\n if (span.type === SpanType.MODEL_GENERATION) {\n const outputText = this.extractOutputText(span.output);\n if (outputText) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT] = outputText;\n }\n }\n }\n }\n\n /**\n * Adds Sentry-specific MODEL_GENERATION attributes that complement GenAI semantic conventions.\n */\n private addModelGenerationAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n\n if (modelAttr.streaming !== undefined) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_REQUEST_STREAM] = modelAttr.streaming;\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_STREAMING] = modelAttr.streaming;\n }\n\n this.setAttributeIfDefined(\n attributes,\n ATTRIBUTE_KEYS.GEN_AI_COMPLETION_START_TIME,\n modelAttr.completionStartTime?.toISOString(),\n );\n\n if (modelAttr.usage) {\n const totalTokens = (modelAttr.usage.inputTokens || 0) + (modelAttr.usage.outputTokens || 0);\n if (totalTokens > 0) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS] = totalTokens;\n }\n }\n }\n\n /**\n * Adds Sentry-specific TOOL_CALL attributes that complement GenAI semantic conventions.\n */\n private addToolCallAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const toolAttr = span.attributes as ToolCallAttributes;\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TOOL_SUCCESS, toolAttr.success);\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_TOOL_CALL_ID, span.metadata?.toolCallId);\n }\n\n /**\n * Adds Sentry-specific AGENT_RUN attributes that complement GenAI semantic conventions.\n */\n private addAgentRunAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const agentAttr = span.attributes as AgentRunAttributes;\n\n const agentName = this.getEntityName(span);\n if (agentName) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_PIPELINE_NAME] = agentName;\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_AGENT_PROMPT, agentAttr.prompt);\n }\n\n // ============================================================================\n // Token Usage Management\n // ============================================================================\n\n /**\n * Applies token usage from the MODEL_GENERATION span to the AGENT_RUN span attributes.\n * Reads usage directly from the generation field.\n * Called when AGENT_RUN spans end to set gen_ai.usage.* attributes.\n */\n private applyUsageFromGeneration(spanData: SpanData): void {\n const usage = spanData.generation?.usage;\n if (!usage) return;\n\n const inputTokens = usage.inputTokens || 0;\n const outputTokens = usage.outputTokens || 0;\n\n if (inputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_INPUT_TOKENS, inputTokens);\n }\n if (outputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_OUTPUT_TOKENS, outputTokens);\n }\n\n const totalTokens = inputTokens + outputTokens;\n if (totalTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS, totalTokens);\n }\n\n const cacheReadTokens = usage.inputDetails?.cacheRead || 0;\n const cacheWriteTokens = usage.inputDetails?.cacheWrite || 0;\n const reasoningTokens = usage.outputDetails?.reasoning || 0;\n\n if (cacheReadTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_READ_TOKENS, cacheReadTokens);\n }\n if (cacheWriteTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_WRITE_TOKENS, cacheWriteTokens);\n }\n if (reasoningTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_REASONING_TOKENS, reasoningTokens);\n }\n }\n\n /**\n * Sets gen_ai.response.model and gen_ai.response.text from the MODEL_GENERATION.\n * Only applies to AGENT_RUN spans.\n */\n private setGenerationResponseAttributes(spanData: SpanData): void {\n if (!spanData.generation) return;\n\n if (spanData.generation.model) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_MODEL, spanData.generation.model);\n }\n\n if (spanData.generation.output) {\n const outputText = this.extractOutputText(spanData.generation.output);\n if (outputText) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT, outputText);\n }\n }\n }\n\n /**\n * Tracks a TOOL_CALL span as a child of its parent MODEL_GENERATION span.\n * This builds the tool_calls array for gen_ai.response.tool_calls attribute.\n */\n private trackToolCallForParent(span: AnyExportedSpan, parentId: string): void {\n const parentSpanData = this.spanMap.get(parentId);\n if (!parentSpanData || parentSpanData.spanType !== SpanType.MODEL_GENERATION) {\n return;\n }\n\n const toolAttr = span.attributes as ToolCallAttributes;\n if (!parentSpanData.toolCalls) {\n parentSpanData.toolCalls = [];\n }\n\n parentSpanData.toolCalls.push({\n name: this.getEntityName(span),\n id: span.metadata?.toolCallId,\n type: toolAttr.toolType || 'function',\n });\n }\n\n /**\n * Applies the gen_ai.response.tool_calls attribute to MODEL_GENERATION spans.\n * Called when MODEL_GENERATION spans end if they have child tool calls.\n */\n private applyToolCallsAttribute(spanData: SpanData): void {\n if (!spanData.toolCalls || spanData.toolCalls.length === 0) {\n return;\n }\n\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TOOL_CALLS, JSON.stringify(spanData.toolCalls));\n }\n\n // ============================================================================\n // Utility Helpers\n // ============================================================================\n\n private logMissingSpan(span: AnyExportedSpan, operation: string): void {\n this.logger.warn(`Sentry exporter: No Sentry span found for ${operation}`, {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n });\n }\n\n private getEntityName(span: AnyExportedSpan): string {\n return span.entityName || span.entityId || 'unknown';\n }\n\n private extractOutputText(output: any): string | undefined {\n if (!output) return undefined;\n if (typeof output === 'string') return output;\n if (output.text && typeof output.text === 'string') return output.text;\n if (output.content && typeof output.content === 'string') return output.content;\n if (output.message?.content && typeof output.message.content === 'string') return output.message.content;\n return undefined;\n }\n\n private serializeValue(value: any): any {\n if (value === null || value === undefined) return value;\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return value;\n }\n\n private setAttributeIfDefined(attributes: Record<string, any>, key: string, value: any): void {\n if (value !== undefined && value !== null) {\n attributes[key] = value;\n }\n }\n\n // ============================================================================\n // Shutdown\n // ============================================================================\n\n async shutdown(): Promise<void> {\n for (const [spanId, spanData] of this.spanMap.entries()) {\n try {\n spanData.span.end();\n } catch (error) {\n this.logger.error('Sentry exporter: Error ending span during shutdown', { spanId, error });\n }\n }\n\n this.spanMap.clear();\n this.skippedSpans.clear();\n\n if (this.initialized) {\n await Sentry.close(2000);\n }\n\n await super.shutdown();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/tracing.ts"],"names":["SpanType","BaseExporter","Sentry","TracingEventType","getGenAISpanName","getGenAIAttributes"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Sentry Exporter for Mastra Observability\n *\n * Sends observability data to Sentry for AI tracing and monitoring.\n * Uses Sentry's modern span model (v8+) with OpenTelemetry semantic conventions.\n *\n * Spans are hierarchically organized: AGENT_RUN -> MODEL_GENERATION -> TOOL_CALL\n * MODEL_STEP and MODEL_CHUNK spans are skipped to simplify the trace hierarchy.\n */\n\nimport type {\n TracingEvent,\n AnyExportedSpan,\n ModelGenerationAttributes,\n ToolCallAttributes,\n AgentRunAttributes,\n WorkflowRunAttributes,\n WorkflowStepAttributes,\n UsageStats,\n} from '@mastra/core/observability';\nimport { SpanType, TracingEventType } from '@mastra/core/observability';\nimport type { BaseExporterConfig } from '@mastra/observability';\nimport { BaseExporter } from '@mastra/observability';\nimport { getAttributes as getGenAIAttributes, getSpanName as getGenAISpanName } from '@mastra/otel-exporter';\nimport * as Sentry from '@sentry/node';\n\nconst SPAN_TYPE_CONFIG: Record<SpanType, { opType: string; opName: string }> = {\n [SpanType.AGENT_RUN]: { opType: 'gen_ai.invoke_agent', opName: 'invoke_agent' },\n [SpanType.MODEL_GENERATION]: { opType: 'gen_ai.chat', opName: 'chat' },\n [SpanType.TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.MCP_TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.WORKFLOW_RUN]: { opType: 'workflow.run', opName: 'workflow' },\n [SpanType.WORKFLOW_STEP]: { opType: 'workflow.step', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_PARALLEL]: { opType: 'workflow.parallel', opName: 'step' },\n [SpanType.WORKFLOW_LOOP]: { opType: 'workflow.loop', opName: 'step' },\n [SpanType.WORKFLOW_SLEEP]: { opType: 'workflow.sleep', opName: 'step' },\n [SpanType.WORKFLOW_WAIT_EVENT]: { opType: 'workflow.wait', opName: 'step' },\n [SpanType.PROCESSOR_RUN]: { opType: 'ai.processor', opName: 'step' },\n [SpanType.GENERIC]: { opType: 'ai.span', opName: 'span' },\n [SpanType.MODEL_STEP]: { opType: 'ai.span', opName: 'step' },\n [SpanType.MODEL_CHUNK]: { opType: 'ai.span', opName: 'step' },\n};\n\nconst ATTRIBUTE_KEYS = {\n SPAN_TYPE: 'ai.span.type',\n ORIGIN: 'sentry.origin',\n TAGS: 'tags',\n INPUT: 'input',\n OUTPUT: 'output',\n GEN_AI_REQUEST_STREAM: 'gen_ai.request.stream',\n GEN_AI_RESPONSE_MODEL: 'gen_ai.response.model',\n GEN_AI_RESPONSE_STREAMING: 'gen_ai.response.streaming',\n GEN_AI_RESPONSE_TOOL_CALLS: 'gen_ai.response.tool_calls',\n GEN_AI_RESPONSE_TEXT: 'gen_ai.response.text',\n GEN_AI_COMPLETION_START_TIME: 'gen_ai.completion_start_time',\n GEN_AI_TOOL_CALL_ID: 'gen_ai.tool.call.id',\n TOOL_SUCCESS: 'tool.success',\n GEN_AI_PIPELINE_NAME: 'gen_ai.pipeline.name',\n GEN_AI_AGENT_PROMPT: 'gen_ai.agent.prompt',\n WORKFLOW_ID: 'workflow.id',\n WORKFLOW_STATUS: 'workflow.status',\n WORKFLOW_STEP_ID: 'workflow.step.id',\n WORKFLOW_STEP_STATUS: 'workflow.step.status',\n GEN_AI_USAGE_INPUT_TOKENS: 'gen_ai.usage.input_tokens',\n GEN_AI_USAGE_OUTPUT_TOKENS: 'gen_ai.usage.output_tokens',\n GEN_AI_USAGE_TOTAL_TOKENS: 'gen_ai.usage.total_tokens',\n GEN_AI_USAGE_CACHE_READ_TOKENS: 'gen_ai.usage.cache_read_input_tokens',\n GEN_AI_USAGE_CACHE_WRITE_TOKENS: 'gen_ai.usage.cache_write_input_tokens',\n GEN_AI_USAGE_REASONING_TOKENS: 'gen_ai.usage.reasoning_tokens',\n} as const;\n\nexport interface SentryExporterConfig extends BaseExporterConfig {\n // Sentry SDK options (passed to Sentry.init())\n /** Data Source Name - tells the SDK where to send events */\n dsn?: string;\n /** Deployment environment (enables filtering issues and alerts by environment) */\n environment?: string;\n /** Percentage of transactions sent to Sentry (0.0 = 0%, 1.0 = 100%) */\n tracesSampleRate?: number;\n /** Version of your code deployed (helps identify regressions and track deployments) */\n release?: string;\n /** Additional Sentry SDK options (integrations, beforeSend, etc.) */\n options?: Partial<Sentry.NodeOptions>;\n}\n\n/**\n * Internal span tracking data.\n * generation tracks the single MODEL_GENERATION for AGENT_RUN response attributes.\n * toolCalls tracks child tool calls for MODEL_GENERATION spans.\n */\ntype SpanData = {\n span: Sentry.Span;\n spanType: SpanType;\n generation?: {\n model?: string;\n output?: any;\n usage?: UsageStats;\n };\n toolCalls?: Array<{\n name: string;\n id?: string;\n type?: string;\n }>;\n};\n\n/** Config type with Sentry-specific fields resolved */\ntype ResolvedSentryConfig = Required<\n Pick<SentryExporterConfig, 'dsn' | 'environment' | 'tracesSampleRate' | 'release'>\n>;\n\nexport class SentryExporter extends BaseExporter {\n name = 'sentry';\n private sentryConfig: ResolvedSentryConfig;\n private spanMap = new Map<string, SpanData>();\n private skippedSpans = new Map<string, string>();\n private initialized = false;\n\n constructor(config: SentryExporterConfig = {}) {\n super(config);\n\n this.sentryConfig = {\n dsn: config.dsn ?? process.env.SENTRY_DSN ?? '',\n environment: config.environment ?? process.env.SENTRY_ENVIRONMENT ?? 'production',\n tracesSampleRate: config.tracesSampleRate ?? 1.0,\n release: config.release ?? process.env.SENTRY_RELEASE ?? '',\n };\n\n if (!this.sentryConfig.dsn) {\n const dsnSource = config.dsn ? 'from config' : process.env.SENTRY_DSN ? 'from env' : 'missing';\n this.setDisabled(\n `Missing required DSN (dsn: ${dsnSource}). Set SENTRY_DSN environment variable or pass it in config.`,\n );\n return;\n }\n\n try {\n Sentry.init({\n dsn: this.sentryConfig.dsn,\n environment: this.sentryConfig.environment,\n tracesSampleRate: this.sentryConfig.tracesSampleRate,\n release: this.sentryConfig.release,\n ...config.options,\n });\n this.initialized = true;\n } catch (error) {\n this.setDisabled(`Failed to initialize Sentry: ${error}`);\n }\n }\n\n // ============================================================================\n // Main Event Handlers\n // ============================================================================\n\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (!this.initialized) return;\n\n const { type, exportedSpan } = event;\n\n if (exportedSpan.isEvent) {\n this.handleEventSpan(exportedSpan);\n return;\n }\n\n // Skip MODEL_CHUNK and MODEL_STEP spans to simplify trace hierarchy.\n // We store them in skippedSpans to preserve parent-child relationships:\n // when a child span references a skipped span as parent, resolveParentSpanId()\n // walks up the chain to find the first non-skipped ancestor.\n if (exportedSpan.type === SpanType.MODEL_CHUNK || exportedSpan.type === SpanType.MODEL_STEP) {\n if (type === TracingEventType.SPAN_STARTED) {\n this.skippedSpans.set(exportedSpan.id, exportedSpan.parentSpanId || '');\n } else if (type === TracingEventType.SPAN_ENDED) {\n this.skippedSpans.delete(exportedSpan.id);\n }\n return;\n }\n\n switch (type) {\n case TracingEventType.SPAN_STARTED:\n await this.handleSpanStarted(exportedSpan);\n break;\n case TracingEventType.SPAN_UPDATED:\n await this.handleSpanUpdated(exportedSpan);\n break;\n case TracingEventType.SPAN_ENDED:\n await this.handleSpanEnded(exportedSpan);\n break;\n }\n }\n\n private handleEventSpan(span: AnyExportedSpan): void {\n Sentry.addBreadcrumb({\n type: 'default',\n category: span.type,\n message: span.name,\n level: span.errorInfo ? 'error' : 'info',\n data: {\n spanId: span.id,\n traceId: span.traceId,\n ...(span.input && { input: this.serializeValue(span.input) }),\n ...(span.output && { output: this.serializeValue(span.output) }),\n ...(span.metadata && { metadata: span.metadata }),\n ...(span.attributes && { attributes: span.attributes }),\n },\n timestamp: span.startTime.getTime() / 1000,\n });\n }\n\n private async handleSpanStarted(span: AnyExportedSpan): Promise<void> {\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n\n const sentrySpan = Sentry.startInactiveSpan({\n op: this.getOperationType(span),\n name: getGenAISpanName(span),\n startTime: span.startTime.getTime(),\n forceTransaction: span.isRootSpan,\n parentSpan: resolvedParentId ? this.spanMap.get(resolvedParentId)?.span : undefined,\n });\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n this.spanMap.set(span.id, {\n span: sentrySpan,\n spanType: span.type,\n });\n\n // Track tool calls as children of MODEL_GENERATION spans for gen_ai.response.tool_calls attribute\n if (span.type === SpanType.TOOL_CALL && resolvedParentId) {\n this.trackToolCallForParent(span, resolvedParentId);\n }\n }\n\n private async handleSpanUpdated(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span update');\n return;\n }\n // Attributes are set on SPAN_STARTED and finalized on SPAN_ENDED.\n // If dynamic updates become necessary, add spanData.span.setAttributes() here.\n }\n\n private async handleSpanEnded(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span end');\n return;\n }\n\n const { span: sentrySpan } = spanData;\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n if (span.type === SpanType.MODEL_GENERATION) {\n // Set gen_ai.response.tool_calls if this generation had tool calls\n this.applyToolCallsAttribute(spanData);\n\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n if (resolvedParentId) {\n const parentData = this.spanMap.get(resolvedParentId);\n if (parentData?.spanType === SpanType.AGENT_RUN) {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n parentData.generation = {\n model: modelAttr.model,\n output: span.output,\n usage: modelAttr.usage,\n };\n }\n }\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n // Apply token usage from the single child MODEL_GENERATION span\n // (there is only ever one MODEL_GENERATION span per AGENT_RUN)\n this.applyUsageFromGeneration(spanData);\n\n this.setGenerationResponseAttributes(spanData);\n }\n\n if (span.errorInfo) {\n sentrySpan.setStatus({\n code: 2,\n message: span.errorInfo.message,\n });\n\n Sentry.captureException(span.errorInfo.message, {\n contexts: {\n trace: { trace_id: span.traceId, span_id: span.id },\n span_info: {\n name: span.name,\n type: span.type,\n error_id: span.errorInfo.id,\n error_category: span.errorInfo.category,\n },\n },\n });\n }\n\n const endTime = span.endTime ? span.endTime.getTime() : undefined;\n sentrySpan.end(endTime);\n this.spanMap.delete(span.id);\n }\n\n // ============================================================================\n // Span Creation Helpers\n // ============================================================================\n\n private resolveParentSpanId(parentSpanId: string | undefined): string | undefined {\n if (!parentSpanId) return undefined;\n\n let currentParentId: string | undefined = parentSpanId;\n while (currentParentId && this.skippedSpans.has(currentParentId)) {\n currentParentId = this.skippedSpans.get(currentParentId);\n if (!currentParentId) break;\n }\n\n return currentParentId;\n }\n\n private getOperationType(span: AnyExportedSpan): string {\n const config = SPAN_TYPE_CONFIG[span.type];\n return config ? config.opType : 'ai.span';\n }\n\n private buildSpanAttributes(span: AnyExportedSpan): Record<string, any> {\n const attributes = getGenAIAttributes(span) as Record<string, any>;\n\n attributes[ATTRIBUTE_KEYS.SPAN_TYPE] = span.type;\n attributes[ATTRIBUTE_KEYS.ORIGIN] = 'auto.ai.mastra';\n\n if (span.metadata) {\n Object.entries(span.metadata).forEach(([key, value]) => {\n if (value !== undefined && value !== null && key !== 'langfuse') {\n attributes[`metadata.${key}`] = this.serializeValue(value);\n }\n });\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TAGS, span.tags?.join(','));\n\n this.addInputOutputAttributes(attributes, span);\n\n if (span.type === SpanType.MODEL_GENERATION) {\n this.addModelGenerationAttributes(attributes, span);\n }\n\n if (span.type === SpanType.TOOL_CALL) {\n this.addToolCallAttributes(attributes, span);\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n this.addAgentRunAttributes(attributes, span);\n }\n\n if (span.type === SpanType.WORKFLOW_RUN) {\n const workflowAttr = span.attributes as WorkflowRunAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STATUS, workflowAttr.status);\n }\n\n if (span.type === SpanType.WORKFLOW_STEP) {\n const stepAttr = span.attributes as WorkflowStepAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_STATUS, stepAttr.status);\n }\n\n return attributes;\n }\n\n // ============================================================================\n // Sentry-Specific Attribute Formatters\n // ============================================================================\n\n /**\n * Adds Sentry-specific input/output attributes that complement GenAI semantic conventions.\n * Adds 'input' and 'output' keys for Sentry UI compatibility.\n */\n private addInputOutputAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n if (span.input !== undefined) {\n attributes[ATTRIBUTE_KEYS.INPUT] = this.serializeValue(span.input);\n }\n\n if (span.output !== undefined) {\n attributes[ATTRIBUTE_KEYS.OUTPUT] = this.serializeValue(span.output);\n\n // Extract text for MODEL_GENERATION spans\n if (span.type === SpanType.MODEL_GENERATION) {\n const outputText = this.extractOutputText(span.output);\n if (outputText) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT] = outputText;\n }\n }\n }\n }\n\n /**\n * Adds Sentry-specific MODEL_GENERATION attributes that complement GenAI semantic conventions.\n */\n private addModelGenerationAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n\n if (modelAttr.streaming !== undefined) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_REQUEST_STREAM] = modelAttr.streaming;\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_STREAMING] = modelAttr.streaming;\n }\n\n this.setAttributeIfDefined(\n attributes,\n ATTRIBUTE_KEYS.GEN_AI_COMPLETION_START_TIME,\n modelAttr.completionStartTime?.toISOString(),\n );\n\n if (modelAttr.usage) {\n const totalTokens = (modelAttr.usage.inputTokens || 0) + (modelAttr.usage.outputTokens || 0);\n if (totalTokens > 0) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS] = totalTokens;\n }\n }\n }\n\n /**\n * Adds Sentry-specific TOOL_CALL attributes that complement GenAI semantic conventions.\n */\n private addToolCallAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const toolAttr = span.attributes as ToolCallAttributes;\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TOOL_SUCCESS, toolAttr.success);\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_TOOL_CALL_ID, span.metadata?.toolCallId);\n }\n\n /**\n * Adds Sentry-specific AGENT_RUN attributes that complement GenAI semantic conventions.\n */\n private addAgentRunAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const agentAttr = span.attributes as AgentRunAttributes;\n\n const agentName = this.getEntityName(span);\n if (agentName) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_PIPELINE_NAME] = agentName;\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_AGENT_PROMPT, agentAttr.prompt);\n }\n\n // ============================================================================\n // Token Usage Management\n // ============================================================================\n\n /**\n * Applies token usage from the MODEL_GENERATION span to the AGENT_RUN span attributes.\n * Reads usage directly from the generation field.\n * Called when AGENT_RUN spans end to set gen_ai.usage.* attributes.\n */\n private applyUsageFromGeneration(spanData: SpanData): void {\n const usage = spanData.generation?.usage;\n if (!usage) return;\n\n const inputTokens = usage.inputTokens || 0;\n const outputTokens = usage.outputTokens || 0;\n\n if (inputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_INPUT_TOKENS, inputTokens);\n }\n if (outputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_OUTPUT_TOKENS, outputTokens);\n }\n\n const totalTokens = inputTokens + outputTokens;\n if (totalTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS, totalTokens);\n }\n\n const cacheReadTokens = usage.inputDetails?.cacheRead || 0;\n const cacheWriteTokens = usage.inputDetails?.cacheWrite || 0;\n const reasoningTokens = usage.outputDetails?.reasoning || 0;\n\n if (cacheReadTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_READ_TOKENS, cacheReadTokens);\n }\n if (cacheWriteTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_WRITE_TOKENS, cacheWriteTokens);\n }\n if (reasoningTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_REASONING_TOKENS, reasoningTokens);\n }\n }\n\n /**\n * Sets gen_ai.response.model and gen_ai.response.text from the MODEL_GENERATION.\n * Only applies to AGENT_RUN spans.\n */\n private setGenerationResponseAttributes(spanData: SpanData): void {\n if (!spanData.generation) return;\n\n if (spanData.generation.model) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_MODEL, spanData.generation.model);\n }\n\n if (spanData.generation.output) {\n const outputText = this.extractOutputText(spanData.generation.output);\n if (outputText) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT, outputText);\n }\n }\n }\n\n /**\n * Tracks a TOOL_CALL span as a child of its parent MODEL_GENERATION span.\n * This builds the tool_calls array for gen_ai.response.tool_calls attribute.\n */\n private trackToolCallForParent(span: AnyExportedSpan, parentId: string): void {\n const parentSpanData = this.spanMap.get(parentId);\n if (!parentSpanData || parentSpanData.spanType !== SpanType.MODEL_GENERATION) {\n return;\n }\n\n const toolAttr = span.attributes as ToolCallAttributes;\n if (!parentSpanData.toolCalls) {\n parentSpanData.toolCalls = [];\n }\n\n parentSpanData.toolCalls.push({\n name: this.getEntityName(span),\n id: span.metadata?.toolCallId,\n type: toolAttr.toolType || 'function',\n });\n }\n\n /**\n * Applies the gen_ai.response.tool_calls attribute to MODEL_GENERATION spans.\n * Called when MODEL_GENERATION spans end if they have child tool calls.\n */\n private applyToolCallsAttribute(spanData: SpanData): void {\n if (!spanData.toolCalls || spanData.toolCalls.length === 0) {\n return;\n }\n\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TOOL_CALLS, JSON.stringify(spanData.toolCalls));\n }\n\n // ============================================================================\n // Utility Helpers\n // ============================================================================\n\n private logMissingSpan(span: AnyExportedSpan, operation: string): void {\n this.logger.warn(`Sentry exporter: No Sentry span found for ${operation}`, {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n });\n }\n\n private getEntityName(span: AnyExportedSpan): string {\n return span.entityName || span.entityId || 'unknown';\n }\n\n private extractOutputText(output: any): string | undefined {\n if (!output) return undefined;\n if (typeof output === 'string') return output;\n if (output.text && typeof output.text === 'string') return output.text;\n if (output.content && typeof output.content === 'string') return output.content;\n if (output.message?.content && typeof output.message.content === 'string') return output.message.content;\n return undefined;\n }\n\n private serializeValue(value: any): any {\n if (value === null || value === undefined) return value;\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return value;\n }\n\n private setAttributeIfDefined(attributes: Record<string, any>, key: string, value: any): void {\n if (value !== undefined && value !== null) {\n attributes[key] = value;\n }\n }\n\n // ============================================================================\n // Flush and Shutdown\n // ============================================================================\n\n /**\n * Force flush any buffered spans without shutting down the exporter.\n * This is useful in serverless environments where you need to ensure spans\n * are exported before the runtime instance is terminated.\n */\n async flush(): Promise<void> {\n if (!this.initialized) return;\n\n try {\n // Sentry.flush() sends any pending events to Sentry\n // The timeout is in milliseconds\n await Sentry.flush(2000);\n this.logger.debug('Sentry exporter: Flushed pending events');\n } catch (error) {\n this.logger.error('Sentry exporter: Error flushing events', { error });\n }\n }\n\n async shutdown(): Promise<void> {\n for (const [spanId, spanData] of this.spanMap.entries()) {\n try {\n spanData.span.end();\n } catch (error) {\n this.logger.error('Sentry exporter: Error ending span during shutdown', { spanId, error });\n }\n }\n\n this.spanMap.clear();\n this.skippedSpans.clear();\n\n if (this.initialized) {\n await Sentry.close(2000);\n }\n\n await super.shutdown();\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -51,19 +51,19 @@ var ATTRIBUTE_KEYS = {
51
51
  };
52
52
  var SentryExporter = class extends BaseExporter {
53
53
  name = "sentry";
54
- config;
54
+ sentryConfig;
55
55
  spanMap = /* @__PURE__ */ new Map();
56
56
  skippedSpans = /* @__PURE__ */ new Map();
57
57
  initialized = false;
58
58
  constructor(config = {}) {
59
59
  super(config);
60
- this.config = {
60
+ this.sentryConfig = {
61
61
  dsn: config.dsn ?? process.env.SENTRY_DSN ?? "",
62
62
  environment: config.environment ?? process.env.SENTRY_ENVIRONMENT ?? "production",
63
63
  tracesSampleRate: config.tracesSampleRate ?? 1,
64
64
  release: config.release ?? process.env.SENTRY_RELEASE ?? ""
65
65
  };
66
- if (!this.config.dsn) {
66
+ if (!this.sentryConfig.dsn) {
67
67
  const dsnSource = config.dsn ? "from config" : process.env.SENTRY_DSN ? "from env" : "missing";
68
68
  this.setDisabled(
69
69
  `Missing required DSN (dsn: ${dsnSource}). Set SENTRY_DSN environment variable or pass it in config.`
@@ -72,10 +72,10 @@ var SentryExporter = class extends BaseExporter {
72
72
  }
73
73
  try {
74
74
  Sentry.init({
75
- dsn: this.config.dsn,
76
- environment: this.config.environment,
77
- tracesSampleRate: this.config.tracesSampleRate,
78
- release: this.config.release,
75
+ dsn: this.sentryConfig.dsn,
76
+ environment: this.sentryConfig.environment,
77
+ tracesSampleRate: this.sentryConfig.tracesSampleRate,
78
+ release: this.sentryConfig.release,
79
79
  ...config.options
80
80
  });
81
81
  this.initialized = true;
@@ -433,8 +433,22 @@ var SentryExporter = class extends BaseExporter {
433
433
  }
434
434
  }
435
435
  // ============================================================================
436
- // Shutdown
436
+ // Flush and Shutdown
437
437
  // ============================================================================
438
+ /**
439
+ * Force flush any buffered spans without shutting down the exporter.
440
+ * This is useful in serverless environments where you need to ensure spans
441
+ * are exported before the runtime instance is terminated.
442
+ */
443
+ async flush() {
444
+ if (!this.initialized) return;
445
+ try {
446
+ await Sentry.flush(2e3);
447
+ this.logger.debug("Sentry exporter: Flushed pending events");
448
+ } catch (error) {
449
+ this.logger.error("Sentry exporter: Error flushing events", { error });
450
+ }
451
+ }
438
452
  async shutdown() {
439
453
  for (const [spanId, spanData] of this.spanMap.entries()) {
440
454
  try {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tracing.ts"],"names":["getGenAISpanName","getGenAIAttributes"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Sentry Exporter for Mastra Observability\n *\n * Sends observability data to Sentry for AI tracing and monitoring.\n * Uses Sentry's modern span model (v8+) with OpenTelemetry semantic conventions.\n *\n * Spans are hierarchically organized: AGENT_RUN -> MODEL_GENERATION -> TOOL_CALL\n * MODEL_STEP and MODEL_CHUNK spans are skipped to simplify the trace hierarchy.\n */\n\nimport type {\n TracingEvent,\n AnyExportedSpan,\n ModelGenerationAttributes,\n ToolCallAttributes,\n AgentRunAttributes,\n WorkflowRunAttributes,\n WorkflowStepAttributes,\n UsageStats,\n} from '@mastra/core/observability';\nimport { SpanType, TracingEventType } from '@mastra/core/observability';\nimport type { BaseExporterConfig } from '@mastra/observability';\nimport { BaseExporter } from '@mastra/observability';\nimport { getAttributes as getGenAIAttributes, getSpanName as getGenAISpanName } from '@mastra/otel-exporter';\nimport * as Sentry from '@sentry/node';\n\nconst SPAN_TYPE_CONFIG: Record<SpanType, { opType: string; opName: string }> = {\n [SpanType.AGENT_RUN]: { opType: 'gen_ai.invoke_agent', opName: 'invoke_agent' },\n [SpanType.MODEL_GENERATION]: { opType: 'gen_ai.chat', opName: 'chat' },\n [SpanType.TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.MCP_TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.WORKFLOW_RUN]: { opType: 'workflow.run', opName: 'workflow' },\n [SpanType.WORKFLOW_STEP]: { opType: 'workflow.step', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_PARALLEL]: { opType: 'workflow.parallel', opName: 'step' },\n [SpanType.WORKFLOW_LOOP]: { opType: 'workflow.loop', opName: 'step' },\n [SpanType.WORKFLOW_SLEEP]: { opType: 'workflow.sleep', opName: 'step' },\n [SpanType.WORKFLOW_WAIT_EVENT]: { opType: 'workflow.wait', opName: 'step' },\n [SpanType.PROCESSOR_RUN]: { opType: 'ai.processor', opName: 'step' },\n [SpanType.GENERIC]: { opType: 'ai.span', opName: 'span' },\n [SpanType.MODEL_STEP]: { opType: 'ai.span', opName: 'step' },\n [SpanType.MODEL_CHUNK]: { opType: 'ai.span', opName: 'step' },\n};\n\nconst ATTRIBUTE_KEYS = {\n SPAN_TYPE: 'ai.span.type',\n ORIGIN: 'sentry.origin',\n TAGS: 'tags',\n INPUT: 'input',\n OUTPUT: 'output',\n GEN_AI_REQUEST_STREAM: 'gen_ai.request.stream',\n GEN_AI_RESPONSE_MODEL: 'gen_ai.response.model',\n GEN_AI_RESPONSE_STREAMING: 'gen_ai.response.streaming',\n GEN_AI_RESPONSE_TOOL_CALLS: 'gen_ai.response.tool_calls',\n GEN_AI_RESPONSE_TEXT: 'gen_ai.response.text',\n GEN_AI_COMPLETION_START_TIME: 'gen_ai.completion_start_time',\n GEN_AI_TOOL_CALL_ID: 'gen_ai.tool.call.id',\n TOOL_SUCCESS: 'tool.success',\n GEN_AI_PIPELINE_NAME: 'gen_ai.pipeline.name',\n GEN_AI_AGENT_PROMPT: 'gen_ai.agent.prompt',\n WORKFLOW_ID: 'workflow.id',\n WORKFLOW_STATUS: 'workflow.status',\n WORKFLOW_STEP_ID: 'workflow.step.id',\n WORKFLOW_STEP_STATUS: 'workflow.step.status',\n GEN_AI_USAGE_INPUT_TOKENS: 'gen_ai.usage.input_tokens',\n GEN_AI_USAGE_OUTPUT_TOKENS: 'gen_ai.usage.output_tokens',\n GEN_AI_USAGE_TOTAL_TOKENS: 'gen_ai.usage.total_tokens',\n GEN_AI_USAGE_CACHE_READ_TOKENS: 'gen_ai.usage.cache_read_input_tokens',\n GEN_AI_USAGE_CACHE_WRITE_TOKENS: 'gen_ai.usage.cache_write_input_tokens',\n GEN_AI_USAGE_REASONING_TOKENS: 'gen_ai.usage.reasoning_tokens',\n} as const;\n\nexport interface SentryExporterConfig extends BaseExporterConfig {\n // Sentry SDK options (passed to Sentry.init())\n /** Data Source Name - tells the SDK where to send events */\n dsn?: string;\n /** Deployment environment (enables filtering issues and alerts by environment) */\n environment?: string;\n /** Percentage of transactions sent to Sentry (0.0 = 0%, 1.0 = 100%) */\n tracesSampleRate?: number;\n /** Version of your code deployed (helps identify regressions and track deployments) */\n release?: string;\n /** Additional Sentry SDK options (integrations, beforeSend, etc.) */\n options?: Partial<Sentry.NodeOptions>;\n}\n\n/**\n * Internal span tracking data.\n * generation tracks the single MODEL_GENERATION for AGENT_RUN response attributes.\n * toolCalls tracks child tool calls for MODEL_GENERATION spans.\n */\ntype SpanData = {\n span: Sentry.Span;\n spanType: SpanType;\n generation?: {\n model?: string;\n output?: any;\n usage?: UsageStats;\n };\n toolCalls?: Array<{\n name: string;\n id?: string;\n type?: string;\n }>;\n};\n\nexport class SentryExporter extends BaseExporter {\n name = 'sentry';\n private config: Required<Omit<SentryExporterConfig, 'logger' | 'logLevel' | 'options'>>;\n private spanMap = new Map<string, SpanData>();\n private skippedSpans = new Map<string, string>();\n private initialized = false;\n\n constructor(config: SentryExporterConfig = {}) {\n super(config);\n\n this.config = {\n dsn: config.dsn ?? process.env.SENTRY_DSN ?? '',\n environment: config.environment ?? process.env.SENTRY_ENVIRONMENT ?? 'production',\n tracesSampleRate: config.tracesSampleRate ?? 1.0,\n release: config.release ?? process.env.SENTRY_RELEASE ?? '',\n };\n\n if (!this.config.dsn) {\n const dsnSource = config.dsn ? 'from config' : process.env.SENTRY_DSN ? 'from env' : 'missing';\n this.setDisabled(\n `Missing required DSN (dsn: ${dsnSource}). Set SENTRY_DSN environment variable or pass it in config.`,\n );\n return;\n }\n\n try {\n Sentry.init({\n dsn: this.config.dsn,\n environment: this.config.environment,\n tracesSampleRate: this.config.tracesSampleRate,\n release: this.config.release,\n ...config.options,\n });\n this.initialized = true;\n } catch (error) {\n this.setDisabled(`Failed to initialize Sentry: ${error}`);\n }\n }\n\n // ============================================================================\n // Main Event Handlers\n // ============================================================================\n\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (!this.initialized) return;\n\n const { type, exportedSpan } = event;\n\n if (exportedSpan.isEvent) {\n this.handleEventSpan(exportedSpan);\n return;\n }\n\n // Skip MODEL_CHUNK and MODEL_STEP spans to simplify trace hierarchy.\n // We store them in skippedSpans to preserve parent-child relationships:\n // when a child span references a skipped span as parent, resolveParentSpanId()\n // walks up the chain to find the first non-skipped ancestor.\n if (exportedSpan.type === SpanType.MODEL_CHUNK || exportedSpan.type === SpanType.MODEL_STEP) {\n if (type === TracingEventType.SPAN_STARTED) {\n this.skippedSpans.set(exportedSpan.id, exportedSpan.parentSpanId || '');\n } else if (type === TracingEventType.SPAN_ENDED) {\n this.skippedSpans.delete(exportedSpan.id);\n }\n return;\n }\n\n switch (type) {\n case TracingEventType.SPAN_STARTED:\n await this.handleSpanStarted(exportedSpan);\n break;\n case TracingEventType.SPAN_UPDATED:\n await this.handleSpanUpdated(exportedSpan);\n break;\n case TracingEventType.SPAN_ENDED:\n await this.handleSpanEnded(exportedSpan);\n break;\n }\n }\n\n private handleEventSpan(span: AnyExportedSpan): void {\n Sentry.addBreadcrumb({\n type: 'default',\n category: span.type,\n message: span.name,\n level: span.errorInfo ? 'error' : 'info',\n data: {\n spanId: span.id,\n traceId: span.traceId,\n ...(span.input && { input: this.serializeValue(span.input) }),\n ...(span.output && { output: this.serializeValue(span.output) }),\n ...(span.metadata && { metadata: span.metadata }),\n ...(span.attributes && { attributes: span.attributes }),\n },\n timestamp: span.startTime.getTime() / 1000,\n });\n }\n\n private async handleSpanStarted(span: AnyExportedSpan): Promise<void> {\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n\n const sentrySpan = Sentry.startInactiveSpan({\n op: this.getOperationType(span),\n name: getGenAISpanName(span),\n startTime: span.startTime.getTime(),\n forceTransaction: span.isRootSpan,\n parentSpan: resolvedParentId ? this.spanMap.get(resolvedParentId)?.span : undefined,\n });\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n this.spanMap.set(span.id, {\n span: sentrySpan,\n spanType: span.type,\n });\n\n // Track tool calls as children of MODEL_GENERATION spans for gen_ai.response.tool_calls attribute\n if (span.type === SpanType.TOOL_CALL && resolvedParentId) {\n this.trackToolCallForParent(span, resolvedParentId);\n }\n }\n\n private async handleSpanUpdated(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span update');\n return;\n }\n // Attributes are set on SPAN_STARTED and finalized on SPAN_ENDED.\n // If dynamic updates become necessary, add spanData.span.setAttributes() here.\n }\n\n private async handleSpanEnded(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span end');\n return;\n }\n\n const { span: sentrySpan } = spanData;\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n if (span.type === SpanType.MODEL_GENERATION) {\n // Set gen_ai.response.tool_calls if this generation had tool calls\n this.applyToolCallsAttribute(spanData);\n\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n if (resolvedParentId) {\n const parentData = this.spanMap.get(resolvedParentId);\n if (parentData?.spanType === SpanType.AGENT_RUN) {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n parentData.generation = {\n model: modelAttr.model,\n output: span.output,\n usage: modelAttr.usage,\n };\n }\n }\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n // Apply token usage from the single child MODEL_GENERATION span\n // (there is only ever one MODEL_GENERATION span per AGENT_RUN)\n this.applyUsageFromGeneration(spanData);\n\n this.setGenerationResponseAttributes(spanData);\n }\n\n if (span.errorInfo) {\n sentrySpan.setStatus({\n code: 2,\n message: span.errorInfo.message,\n });\n\n Sentry.captureException(span.errorInfo.message, {\n contexts: {\n trace: { trace_id: span.traceId, span_id: span.id },\n span_info: {\n name: span.name,\n type: span.type,\n error_id: span.errorInfo.id,\n error_category: span.errorInfo.category,\n },\n },\n });\n }\n\n const endTime = span.endTime ? span.endTime.getTime() : undefined;\n sentrySpan.end(endTime);\n this.spanMap.delete(span.id);\n }\n\n // ============================================================================\n // Span Creation Helpers\n // ============================================================================\n\n private resolveParentSpanId(parentSpanId: string | undefined): string | undefined {\n if (!parentSpanId) return undefined;\n\n let currentParentId: string | undefined = parentSpanId;\n while (currentParentId && this.skippedSpans.has(currentParentId)) {\n currentParentId = this.skippedSpans.get(currentParentId);\n if (!currentParentId) break;\n }\n\n return currentParentId;\n }\n\n private getOperationType(span: AnyExportedSpan): string {\n const config = SPAN_TYPE_CONFIG[span.type];\n return config ? config.opType : 'ai.span';\n }\n\n private buildSpanAttributes(span: AnyExportedSpan): Record<string, any> {\n const attributes = getGenAIAttributes(span) as Record<string, any>;\n\n attributes[ATTRIBUTE_KEYS.SPAN_TYPE] = span.type;\n attributes[ATTRIBUTE_KEYS.ORIGIN] = 'auto.ai.mastra';\n\n if (span.metadata) {\n Object.entries(span.metadata).forEach(([key, value]) => {\n if (value !== undefined && value !== null && key !== 'langfuse') {\n attributes[`metadata.${key}`] = this.serializeValue(value);\n }\n });\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TAGS, span.tags?.join(','));\n\n this.addInputOutputAttributes(attributes, span);\n\n if (span.type === SpanType.MODEL_GENERATION) {\n this.addModelGenerationAttributes(attributes, span);\n }\n\n if (span.type === SpanType.TOOL_CALL) {\n this.addToolCallAttributes(attributes, span);\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n this.addAgentRunAttributes(attributes, span);\n }\n\n if (span.type === SpanType.WORKFLOW_RUN) {\n const workflowAttr = span.attributes as WorkflowRunAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STATUS, workflowAttr.status);\n }\n\n if (span.type === SpanType.WORKFLOW_STEP) {\n const stepAttr = span.attributes as WorkflowStepAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_STATUS, stepAttr.status);\n }\n\n return attributes;\n }\n\n // ============================================================================\n // Sentry-Specific Attribute Formatters\n // ============================================================================\n\n /**\n * Adds Sentry-specific input/output attributes that complement GenAI semantic conventions.\n * Adds 'input' and 'output' keys for Sentry UI compatibility.\n */\n private addInputOutputAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n if (span.input !== undefined) {\n attributes[ATTRIBUTE_KEYS.INPUT] = this.serializeValue(span.input);\n }\n\n if (span.output !== undefined) {\n attributes[ATTRIBUTE_KEYS.OUTPUT] = this.serializeValue(span.output);\n\n // Extract text for MODEL_GENERATION spans\n if (span.type === SpanType.MODEL_GENERATION) {\n const outputText = this.extractOutputText(span.output);\n if (outputText) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT] = outputText;\n }\n }\n }\n }\n\n /**\n * Adds Sentry-specific MODEL_GENERATION attributes that complement GenAI semantic conventions.\n */\n private addModelGenerationAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n\n if (modelAttr.streaming !== undefined) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_REQUEST_STREAM] = modelAttr.streaming;\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_STREAMING] = modelAttr.streaming;\n }\n\n this.setAttributeIfDefined(\n attributes,\n ATTRIBUTE_KEYS.GEN_AI_COMPLETION_START_TIME,\n modelAttr.completionStartTime?.toISOString(),\n );\n\n if (modelAttr.usage) {\n const totalTokens = (modelAttr.usage.inputTokens || 0) + (modelAttr.usage.outputTokens || 0);\n if (totalTokens > 0) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS] = totalTokens;\n }\n }\n }\n\n /**\n * Adds Sentry-specific TOOL_CALL attributes that complement GenAI semantic conventions.\n */\n private addToolCallAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const toolAttr = span.attributes as ToolCallAttributes;\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TOOL_SUCCESS, toolAttr.success);\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_TOOL_CALL_ID, span.metadata?.toolCallId);\n }\n\n /**\n * Adds Sentry-specific AGENT_RUN attributes that complement GenAI semantic conventions.\n */\n private addAgentRunAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const agentAttr = span.attributes as AgentRunAttributes;\n\n const agentName = this.getEntityName(span);\n if (agentName) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_PIPELINE_NAME] = agentName;\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_AGENT_PROMPT, agentAttr.prompt);\n }\n\n // ============================================================================\n // Token Usage Management\n // ============================================================================\n\n /**\n * Applies token usage from the MODEL_GENERATION span to the AGENT_RUN span attributes.\n * Reads usage directly from the generation field.\n * Called when AGENT_RUN spans end to set gen_ai.usage.* attributes.\n */\n private applyUsageFromGeneration(spanData: SpanData): void {\n const usage = spanData.generation?.usage;\n if (!usage) return;\n\n const inputTokens = usage.inputTokens || 0;\n const outputTokens = usage.outputTokens || 0;\n\n if (inputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_INPUT_TOKENS, inputTokens);\n }\n if (outputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_OUTPUT_TOKENS, outputTokens);\n }\n\n const totalTokens = inputTokens + outputTokens;\n if (totalTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS, totalTokens);\n }\n\n const cacheReadTokens = usage.inputDetails?.cacheRead || 0;\n const cacheWriteTokens = usage.inputDetails?.cacheWrite || 0;\n const reasoningTokens = usage.outputDetails?.reasoning || 0;\n\n if (cacheReadTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_READ_TOKENS, cacheReadTokens);\n }\n if (cacheWriteTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_WRITE_TOKENS, cacheWriteTokens);\n }\n if (reasoningTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_REASONING_TOKENS, reasoningTokens);\n }\n }\n\n /**\n * Sets gen_ai.response.model and gen_ai.response.text from the MODEL_GENERATION.\n * Only applies to AGENT_RUN spans.\n */\n private setGenerationResponseAttributes(spanData: SpanData): void {\n if (!spanData.generation) return;\n\n if (spanData.generation.model) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_MODEL, spanData.generation.model);\n }\n\n if (spanData.generation.output) {\n const outputText = this.extractOutputText(spanData.generation.output);\n if (outputText) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT, outputText);\n }\n }\n }\n\n /**\n * Tracks a TOOL_CALL span as a child of its parent MODEL_GENERATION span.\n * This builds the tool_calls array for gen_ai.response.tool_calls attribute.\n */\n private trackToolCallForParent(span: AnyExportedSpan, parentId: string): void {\n const parentSpanData = this.spanMap.get(parentId);\n if (!parentSpanData || parentSpanData.spanType !== SpanType.MODEL_GENERATION) {\n return;\n }\n\n const toolAttr = span.attributes as ToolCallAttributes;\n if (!parentSpanData.toolCalls) {\n parentSpanData.toolCalls = [];\n }\n\n parentSpanData.toolCalls.push({\n name: this.getEntityName(span),\n id: span.metadata?.toolCallId,\n type: toolAttr.toolType || 'function',\n });\n }\n\n /**\n * Applies the gen_ai.response.tool_calls attribute to MODEL_GENERATION spans.\n * Called when MODEL_GENERATION spans end if they have child tool calls.\n */\n private applyToolCallsAttribute(spanData: SpanData): void {\n if (!spanData.toolCalls || spanData.toolCalls.length === 0) {\n return;\n }\n\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TOOL_CALLS, JSON.stringify(spanData.toolCalls));\n }\n\n // ============================================================================\n // Utility Helpers\n // ============================================================================\n\n private logMissingSpan(span: AnyExportedSpan, operation: string): void {\n this.logger.warn(`Sentry exporter: No Sentry span found for ${operation}`, {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n });\n }\n\n private getEntityName(span: AnyExportedSpan): string {\n return span.entityName || span.entityId || 'unknown';\n }\n\n private extractOutputText(output: any): string | undefined {\n if (!output) return undefined;\n if (typeof output === 'string') return output;\n if (output.text && typeof output.text === 'string') return output.text;\n if (output.content && typeof output.content === 'string') return output.content;\n if (output.message?.content && typeof output.message.content === 'string') return output.message.content;\n return undefined;\n }\n\n private serializeValue(value: any): any {\n if (value === null || value === undefined) return value;\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return value;\n }\n\n private setAttributeIfDefined(attributes: Record<string, any>, key: string, value: any): void {\n if (value !== undefined && value !== null) {\n attributes[key] = value;\n }\n }\n\n // ============================================================================\n // Shutdown\n // ============================================================================\n\n async shutdown(): Promise<void> {\n for (const [spanId, spanData] of this.spanMap.entries()) {\n try {\n spanData.span.end();\n } catch (error) {\n this.logger.error('Sentry exporter: Error ending span during shutdown', { spanId, error });\n }\n }\n\n this.spanMap.clear();\n this.skippedSpans.clear();\n\n if (this.initialized) {\n await Sentry.close(2000);\n }\n\n await super.shutdown();\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/tracing.ts"],"names":["getGenAISpanName","getGenAIAttributes"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Sentry Exporter for Mastra Observability\n *\n * Sends observability data to Sentry for AI tracing and monitoring.\n * Uses Sentry's modern span model (v8+) with OpenTelemetry semantic conventions.\n *\n * Spans are hierarchically organized: AGENT_RUN -> MODEL_GENERATION -> TOOL_CALL\n * MODEL_STEP and MODEL_CHUNK spans are skipped to simplify the trace hierarchy.\n */\n\nimport type {\n TracingEvent,\n AnyExportedSpan,\n ModelGenerationAttributes,\n ToolCallAttributes,\n AgentRunAttributes,\n WorkflowRunAttributes,\n WorkflowStepAttributes,\n UsageStats,\n} from '@mastra/core/observability';\nimport { SpanType, TracingEventType } from '@mastra/core/observability';\nimport type { BaseExporterConfig } from '@mastra/observability';\nimport { BaseExporter } from '@mastra/observability';\nimport { getAttributes as getGenAIAttributes, getSpanName as getGenAISpanName } from '@mastra/otel-exporter';\nimport * as Sentry from '@sentry/node';\n\nconst SPAN_TYPE_CONFIG: Record<SpanType, { opType: string; opName: string }> = {\n [SpanType.AGENT_RUN]: { opType: 'gen_ai.invoke_agent', opName: 'invoke_agent' },\n [SpanType.MODEL_GENERATION]: { opType: 'gen_ai.chat', opName: 'chat' },\n [SpanType.TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.MCP_TOOL_CALL]: { opType: 'gen_ai.execute_tool', opName: 'execute_tool' },\n [SpanType.WORKFLOW_RUN]: { opType: 'workflow.run', opName: 'workflow' },\n [SpanType.WORKFLOW_STEP]: { opType: 'workflow.step', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_CONDITIONAL_EVAL]: { opType: 'workflow.conditional', opName: 'step' },\n [SpanType.WORKFLOW_PARALLEL]: { opType: 'workflow.parallel', opName: 'step' },\n [SpanType.WORKFLOW_LOOP]: { opType: 'workflow.loop', opName: 'step' },\n [SpanType.WORKFLOW_SLEEP]: { opType: 'workflow.sleep', opName: 'step' },\n [SpanType.WORKFLOW_WAIT_EVENT]: { opType: 'workflow.wait', opName: 'step' },\n [SpanType.PROCESSOR_RUN]: { opType: 'ai.processor', opName: 'step' },\n [SpanType.GENERIC]: { opType: 'ai.span', opName: 'span' },\n [SpanType.MODEL_STEP]: { opType: 'ai.span', opName: 'step' },\n [SpanType.MODEL_CHUNK]: { opType: 'ai.span', opName: 'step' },\n};\n\nconst ATTRIBUTE_KEYS = {\n SPAN_TYPE: 'ai.span.type',\n ORIGIN: 'sentry.origin',\n TAGS: 'tags',\n INPUT: 'input',\n OUTPUT: 'output',\n GEN_AI_REQUEST_STREAM: 'gen_ai.request.stream',\n GEN_AI_RESPONSE_MODEL: 'gen_ai.response.model',\n GEN_AI_RESPONSE_STREAMING: 'gen_ai.response.streaming',\n GEN_AI_RESPONSE_TOOL_CALLS: 'gen_ai.response.tool_calls',\n GEN_AI_RESPONSE_TEXT: 'gen_ai.response.text',\n GEN_AI_COMPLETION_START_TIME: 'gen_ai.completion_start_time',\n GEN_AI_TOOL_CALL_ID: 'gen_ai.tool.call.id',\n TOOL_SUCCESS: 'tool.success',\n GEN_AI_PIPELINE_NAME: 'gen_ai.pipeline.name',\n GEN_AI_AGENT_PROMPT: 'gen_ai.agent.prompt',\n WORKFLOW_ID: 'workflow.id',\n WORKFLOW_STATUS: 'workflow.status',\n WORKFLOW_STEP_ID: 'workflow.step.id',\n WORKFLOW_STEP_STATUS: 'workflow.step.status',\n GEN_AI_USAGE_INPUT_TOKENS: 'gen_ai.usage.input_tokens',\n GEN_AI_USAGE_OUTPUT_TOKENS: 'gen_ai.usage.output_tokens',\n GEN_AI_USAGE_TOTAL_TOKENS: 'gen_ai.usage.total_tokens',\n GEN_AI_USAGE_CACHE_READ_TOKENS: 'gen_ai.usage.cache_read_input_tokens',\n GEN_AI_USAGE_CACHE_WRITE_TOKENS: 'gen_ai.usage.cache_write_input_tokens',\n GEN_AI_USAGE_REASONING_TOKENS: 'gen_ai.usage.reasoning_tokens',\n} as const;\n\nexport interface SentryExporterConfig extends BaseExporterConfig {\n // Sentry SDK options (passed to Sentry.init())\n /** Data Source Name - tells the SDK where to send events */\n dsn?: string;\n /** Deployment environment (enables filtering issues and alerts by environment) */\n environment?: string;\n /** Percentage of transactions sent to Sentry (0.0 = 0%, 1.0 = 100%) */\n tracesSampleRate?: number;\n /** Version of your code deployed (helps identify regressions and track deployments) */\n release?: string;\n /** Additional Sentry SDK options (integrations, beforeSend, etc.) */\n options?: Partial<Sentry.NodeOptions>;\n}\n\n/**\n * Internal span tracking data.\n * generation tracks the single MODEL_GENERATION for AGENT_RUN response attributes.\n * toolCalls tracks child tool calls for MODEL_GENERATION spans.\n */\ntype SpanData = {\n span: Sentry.Span;\n spanType: SpanType;\n generation?: {\n model?: string;\n output?: any;\n usage?: UsageStats;\n };\n toolCalls?: Array<{\n name: string;\n id?: string;\n type?: string;\n }>;\n};\n\n/** Config type with Sentry-specific fields resolved */\ntype ResolvedSentryConfig = Required<\n Pick<SentryExporterConfig, 'dsn' | 'environment' | 'tracesSampleRate' | 'release'>\n>;\n\nexport class SentryExporter extends BaseExporter {\n name = 'sentry';\n private sentryConfig: ResolvedSentryConfig;\n private spanMap = new Map<string, SpanData>();\n private skippedSpans = new Map<string, string>();\n private initialized = false;\n\n constructor(config: SentryExporterConfig = {}) {\n super(config);\n\n this.sentryConfig = {\n dsn: config.dsn ?? process.env.SENTRY_DSN ?? '',\n environment: config.environment ?? process.env.SENTRY_ENVIRONMENT ?? 'production',\n tracesSampleRate: config.tracesSampleRate ?? 1.0,\n release: config.release ?? process.env.SENTRY_RELEASE ?? '',\n };\n\n if (!this.sentryConfig.dsn) {\n const dsnSource = config.dsn ? 'from config' : process.env.SENTRY_DSN ? 'from env' : 'missing';\n this.setDisabled(\n `Missing required DSN (dsn: ${dsnSource}). Set SENTRY_DSN environment variable or pass it in config.`,\n );\n return;\n }\n\n try {\n Sentry.init({\n dsn: this.sentryConfig.dsn,\n environment: this.sentryConfig.environment,\n tracesSampleRate: this.sentryConfig.tracesSampleRate,\n release: this.sentryConfig.release,\n ...config.options,\n });\n this.initialized = true;\n } catch (error) {\n this.setDisabled(`Failed to initialize Sentry: ${error}`);\n }\n }\n\n // ============================================================================\n // Main Event Handlers\n // ============================================================================\n\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (!this.initialized) return;\n\n const { type, exportedSpan } = event;\n\n if (exportedSpan.isEvent) {\n this.handleEventSpan(exportedSpan);\n return;\n }\n\n // Skip MODEL_CHUNK and MODEL_STEP spans to simplify trace hierarchy.\n // We store them in skippedSpans to preserve parent-child relationships:\n // when a child span references a skipped span as parent, resolveParentSpanId()\n // walks up the chain to find the first non-skipped ancestor.\n if (exportedSpan.type === SpanType.MODEL_CHUNK || exportedSpan.type === SpanType.MODEL_STEP) {\n if (type === TracingEventType.SPAN_STARTED) {\n this.skippedSpans.set(exportedSpan.id, exportedSpan.parentSpanId || '');\n } else if (type === TracingEventType.SPAN_ENDED) {\n this.skippedSpans.delete(exportedSpan.id);\n }\n return;\n }\n\n switch (type) {\n case TracingEventType.SPAN_STARTED:\n await this.handleSpanStarted(exportedSpan);\n break;\n case TracingEventType.SPAN_UPDATED:\n await this.handleSpanUpdated(exportedSpan);\n break;\n case TracingEventType.SPAN_ENDED:\n await this.handleSpanEnded(exportedSpan);\n break;\n }\n }\n\n private handleEventSpan(span: AnyExportedSpan): void {\n Sentry.addBreadcrumb({\n type: 'default',\n category: span.type,\n message: span.name,\n level: span.errorInfo ? 'error' : 'info',\n data: {\n spanId: span.id,\n traceId: span.traceId,\n ...(span.input && { input: this.serializeValue(span.input) }),\n ...(span.output && { output: this.serializeValue(span.output) }),\n ...(span.metadata && { metadata: span.metadata }),\n ...(span.attributes && { attributes: span.attributes }),\n },\n timestamp: span.startTime.getTime() / 1000,\n });\n }\n\n private async handleSpanStarted(span: AnyExportedSpan): Promise<void> {\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n\n const sentrySpan = Sentry.startInactiveSpan({\n op: this.getOperationType(span),\n name: getGenAISpanName(span),\n startTime: span.startTime.getTime(),\n forceTransaction: span.isRootSpan,\n parentSpan: resolvedParentId ? this.spanMap.get(resolvedParentId)?.span : undefined,\n });\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n this.spanMap.set(span.id, {\n span: sentrySpan,\n spanType: span.type,\n });\n\n // Track tool calls as children of MODEL_GENERATION spans for gen_ai.response.tool_calls attribute\n if (span.type === SpanType.TOOL_CALL && resolvedParentId) {\n this.trackToolCallForParent(span, resolvedParentId);\n }\n }\n\n private async handleSpanUpdated(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span update');\n return;\n }\n // Attributes are set on SPAN_STARTED and finalized on SPAN_ENDED.\n // If dynamic updates become necessary, add spanData.span.setAttributes() here.\n }\n\n private async handleSpanEnded(span: AnyExportedSpan): Promise<void> {\n const spanData = this.spanMap.get(span.id);\n if (!spanData) {\n this.logMissingSpan(span, 'span end');\n return;\n }\n\n const { span: sentrySpan } = spanData;\n\n sentrySpan.setAttributes(this.buildSpanAttributes(span));\n\n if (span.type === SpanType.MODEL_GENERATION) {\n // Set gen_ai.response.tool_calls if this generation had tool calls\n this.applyToolCallsAttribute(spanData);\n\n const resolvedParentId = this.resolveParentSpanId(span.parentSpanId);\n if (resolvedParentId) {\n const parentData = this.spanMap.get(resolvedParentId);\n if (parentData?.spanType === SpanType.AGENT_RUN) {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n parentData.generation = {\n model: modelAttr.model,\n output: span.output,\n usage: modelAttr.usage,\n };\n }\n }\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n // Apply token usage from the single child MODEL_GENERATION span\n // (there is only ever one MODEL_GENERATION span per AGENT_RUN)\n this.applyUsageFromGeneration(spanData);\n\n this.setGenerationResponseAttributes(spanData);\n }\n\n if (span.errorInfo) {\n sentrySpan.setStatus({\n code: 2,\n message: span.errorInfo.message,\n });\n\n Sentry.captureException(span.errorInfo.message, {\n contexts: {\n trace: { trace_id: span.traceId, span_id: span.id },\n span_info: {\n name: span.name,\n type: span.type,\n error_id: span.errorInfo.id,\n error_category: span.errorInfo.category,\n },\n },\n });\n }\n\n const endTime = span.endTime ? span.endTime.getTime() : undefined;\n sentrySpan.end(endTime);\n this.spanMap.delete(span.id);\n }\n\n // ============================================================================\n // Span Creation Helpers\n // ============================================================================\n\n private resolveParentSpanId(parentSpanId: string | undefined): string | undefined {\n if (!parentSpanId) return undefined;\n\n let currentParentId: string | undefined = parentSpanId;\n while (currentParentId && this.skippedSpans.has(currentParentId)) {\n currentParentId = this.skippedSpans.get(currentParentId);\n if (!currentParentId) break;\n }\n\n return currentParentId;\n }\n\n private getOperationType(span: AnyExportedSpan): string {\n const config = SPAN_TYPE_CONFIG[span.type];\n return config ? config.opType : 'ai.span';\n }\n\n private buildSpanAttributes(span: AnyExportedSpan): Record<string, any> {\n const attributes = getGenAIAttributes(span) as Record<string, any>;\n\n attributes[ATTRIBUTE_KEYS.SPAN_TYPE] = span.type;\n attributes[ATTRIBUTE_KEYS.ORIGIN] = 'auto.ai.mastra';\n\n if (span.metadata) {\n Object.entries(span.metadata).forEach(([key, value]) => {\n if (value !== undefined && value !== null && key !== 'langfuse') {\n attributes[`metadata.${key}`] = this.serializeValue(value);\n }\n });\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TAGS, span.tags?.join(','));\n\n this.addInputOutputAttributes(attributes, span);\n\n if (span.type === SpanType.MODEL_GENERATION) {\n this.addModelGenerationAttributes(attributes, span);\n }\n\n if (span.type === SpanType.TOOL_CALL) {\n this.addToolCallAttributes(attributes, span);\n }\n\n if (span.type === SpanType.AGENT_RUN) {\n this.addAgentRunAttributes(attributes, span);\n }\n\n if (span.type === SpanType.WORKFLOW_RUN) {\n const workflowAttr = span.attributes as WorkflowRunAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STATUS, workflowAttr.status);\n }\n\n if (span.type === SpanType.WORKFLOW_STEP) {\n const stepAttr = span.attributes as WorkflowStepAttributes;\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_ID, this.getEntityName(span));\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.WORKFLOW_STEP_STATUS, stepAttr.status);\n }\n\n return attributes;\n }\n\n // ============================================================================\n // Sentry-Specific Attribute Formatters\n // ============================================================================\n\n /**\n * Adds Sentry-specific input/output attributes that complement GenAI semantic conventions.\n * Adds 'input' and 'output' keys for Sentry UI compatibility.\n */\n private addInputOutputAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n if (span.input !== undefined) {\n attributes[ATTRIBUTE_KEYS.INPUT] = this.serializeValue(span.input);\n }\n\n if (span.output !== undefined) {\n attributes[ATTRIBUTE_KEYS.OUTPUT] = this.serializeValue(span.output);\n\n // Extract text for MODEL_GENERATION spans\n if (span.type === SpanType.MODEL_GENERATION) {\n const outputText = this.extractOutputText(span.output);\n if (outputText) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT] = outputText;\n }\n }\n }\n }\n\n /**\n * Adds Sentry-specific MODEL_GENERATION attributes that complement GenAI semantic conventions.\n */\n private addModelGenerationAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const modelAttr = span.attributes as ModelGenerationAttributes;\n\n if (modelAttr.streaming !== undefined) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_REQUEST_STREAM] = modelAttr.streaming;\n attributes[ATTRIBUTE_KEYS.GEN_AI_RESPONSE_STREAMING] = modelAttr.streaming;\n }\n\n this.setAttributeIfDefined(\n attributes,\n ATTRIBUTE_KEYS.GEN_AI_COMPLETION_START_TIME,\n modelAttr.completionStartTime?.toISOString(),\n );\n\n if (modelAttr.usage) {\n const totalTokens = (modelAttr.usage.inputTokens || 0) + (modelAttr.usage.outputTokens || 0);\n if (totalTokens > 0) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS] = totalTokens;\n }\n }\n }\n\n /**\n * Adds Sentry-specific TOOL_CALL attributes that complement GenAI semantic conventions.\n */\n private addToolCallAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const toolAttr = span.attributes as ToolCallAttributes;\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.TOOL_SUCCESS, toolAttr.success);\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_TOOL_CALL_ID, span.metadata?.toolCallId);\n }\n\n /**\n * Adds Sentry-specific AGENT_RUN attributes that complement GenAI semantic conventions.\n */\n private addAgentRunAttributes(attributes: Record<string, any>, span: AnyExportedSpan): void {\n const agentAttr = span.attributes as AgentRunAttributes;\n\n const agentName = this.getEntityName(span);\n if (agentName) {\n attributes[ATTRIBUTE_KEYS.GEN_AI_PIPELINE_NAME] = agentName;\n }\n\n this.setAttributeIfDefined(attributes, ATTRIBUTE_KEYS.GEN_AI_AGENT_PROMPT, agentAttr.prompt);\n }\n\n // ============================================================================\n // Token Usage Management\n // ============================================================================\n\n /**\n * Applies token usage from the MODEL_GENERATION span to the AGENT_RUN span attributes.\n * Reads usage directly from the generation field.\n * Called when AGENT_RUN spans end to set gen_ai.usage.* attributes.\n */\n private applyUsageFromGeneration(spanData: SpanData): void {\n const usage = spanData.generation?.usage;\n if (!usage) return;\n\n const inputTokens = usage.inputTokens || 0;\n const outputTokens = usage.outputTokens || 0;\n\n if (inputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_INPUT_TOKENS, inputTokens);\n }\n if (outputTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_OUTPUT_TOKENS, outputTokens);\n }\n\n const totalTokens = inputTokens + outputTokens;\n if (totalTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_TOTAL_TOKENS, totalTokens);\n }\n\n const cacheReadTokens = usage.inputDetails?.cacheRead || 0;\n const cacheWriteTokens = usage.inputDetails?.cacheWrite || 0;\n const reasoningTokens = usage.outputDetails?.reasoning || 0;\n\n if (cacheReadTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_READ_TOKENS, cacheReadTokens);\n }\n if (cacheWriteTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_CACHE_WRITE_TOKENS, cacheWriteTokens);\n }\n if (reasoningTokens > 0) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_USAGE_REASONING_TOKENS, reasoningTokens);\n }\n }\n\n /**\n * Sets gen_ai.response.model and gen_ai.response.text from the MODEL_GENERATION.\n * Only applies to AGENT_RUN spans.\n */\n private setGenerationResponseAttributes(spanData: SpanData): void {\n if (!spanData.generation) return;\n\n if (spanData.generation.model) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_MODEL, spanData.generation.model);\n }\n\n if (spanData.generation.output) {\n const outputText = this.extractOutputText(spanData.generation.output);\n if (outputText) {\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TEXT, outputText);\n }\n }\n }\n\n /**\n * Tracks a TOOL_CALL span as a child of its parent MODEL_GENERATION span.\n * This builds the tool_calls array for gen_ai.response.tool_calls attribute.\n */\n private trackToolCallForParent(span: AnyExportedSpan, parentId: string): void {\n const parentSpanData = this.spanMap.get(parentId);\n if (!parentSpanData || parentSpanData.spanType !== SpanType.MODEL_GENERATION) {\n return;\n }\n\n const toolAttr = span.attributes as ToolCallAttributes;\n if (!parentSpanData.toolCalls) {\n parentSpanData.toolCalls = [];\n }\n\n parentSpanData.toolCalls.push({\n name: this.getEntityName(span),\n id: span.metadata?.toolCallId,\n type: toolAttr.toolType || 'function',\n });\n }\n\n /**\n * Applies the gen_ai.response.tool_calls attribute to MODEL_GENERATION spans.\n * Called when MODEL_GENERATION spans end if they have child tool calls.\n */\n private applyToolCallsAttribute(spanData: SpanData): void {\n if (!spanData.toolCalls || spanData.toolCalls.length === 0) {\n return;\n }\n\n spanData.span.setAttribute(ATTRIBUTE_KEYS.GEN_AI_RESPONSE_TOOL_CALLS, JSON.stringify(spanData.toolCalls));\n }\n\n // ============================================================================\n // Utility Helpers\n // ============================================================================\n\n private logMissingSpan(span: AnyExportedSpan, operation: string): void {\n this.logger.warn(`Sentry exporter: No Sentry span found for ${operation}`, {\n traceId: span.traceId,\n spanId: span.id,\n spanName: span.name,\n });\n }\n\n private getEntityName(span: AnyExportedSpan): string {\n return span.entityName || span.entityId || 'unknown';\n }\n\n private extractOutputText(output: any): string | undefined {\n if (!output) return undefined;\n if (typeof output === 'string') return output;\n if (output.text && typeof output.text === 'string') return output.text;\n if (output.content && typeof output.content === 'string') return output.content;\n if (output.message?.content && typeof output.message.content === 'string') return output.message.content;\n return undefined;\n }\n\n private serializeValue(value: any): any {\n if (value === null || value === undefined) return value;\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return value;\n }\n\n private setAttributeIfDefined(attributes: Record<string, any>, key: string, value: any): void {\n if (value !== undefined && value !== null) {\n attributes[key] = value;\n }\n }\n\n // ============================================================================\n // Flush and Shutdown\n // ============================================================================\n\n /**\n * Force flush any buffered spans without shutting down the exporter.\n * This is useful in serverless environments where you need to ensure spans\n * are exported before the runtime instance is terminated.\n */\n async flush(): Promise<void> {\n if (!this.initialized) return;\n\n try {\n // Sentry.flush() sends any pending events to Sentry\n // The timeout is in milliseconds\n await Sentry.flush(2000);\n this.logger.debug('Sentry exporter: Flushed pending events');\n } catch (error) {\n this.logger.error('Sentry exporter: Error flushing events', { error });\n }\n }\n\n async shutdown(): Promise<void> {\n for (const [spanId, spanData] of this.spanMap.entries()) {\n try {\n spanData.span.end();\n } catch (error) {\n this.logger.error('Sentry exporter: Error ending span during shutdown', { spanId, error });\n }\n }\n\n this.spanMap.clear();\n this.skippedSpans.clear();\n\n if (this.initialized) {\n await Sentry.close(2000);\n }\n\n await super.shutdown();\n }\n}\n"]}
package/dist/tracing.d.ts CHANGED
@@ -25,7 +25,7 @@ export interface SentryExporterConfig extends BaseExporterConfig {
25
25
  }
26
26
  export declare class SentryExporter extends BaseExporter {
27
27
  name: string;
28
- private config;
28
+ private sentryConfig;
29
29
  private spanMap;
30
30
  private skippedSpans;
31
31
  private initialized;
@@ -81,6 +81,12 @@ export declare class SentryExporter extends BaseExporter {
81
81
  private extractOutputText;
82
82
  private serializeValue;
83
83
  private setAttributeIfDefined;
84
+ /**
85
+ * Force flush any buffered spans without shutting down the exporter.
86
+ * This is useful in serverless environments where you need to ensure spans
87
+ * are exported before the runtime instance is terminated.
88
+ */
89
+ flush(): Promise<void>;
84
90
  shutdown(): Promise<void>;
85
91
  }
86
92
  //# sourceMappingURL=tracing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EAQb,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAiDvC,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;CACvC;AAsBD,qBAAa,cAAe,SAAQ,YAAY;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAA0E;IACxF,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,GAAE,oBAAyB;cAoC7B,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCvE,OAAO,CAAC,eAAe;YAkBT,iBAAiB;YAwBjB,iBAAiB;YAUjB,eAAe;IAiE7B,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,mBAAmB;IAiD3B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAsBpC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAkChC;;;OAGG;IACH,OAAO,CAAC,+BAA+B;IAevC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,qBAAqB;IAUvB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBhC"}
1
+ {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EAQb,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAiDvC,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAE9D,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;CACvC;AA2BD,qBAAa,cAAe,SAAQ,YAAY;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,GAAE,oBAAyB;cAoC7B,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCvE,OAAO,CAAC,eAAe;YAkBT,iBAAiB;YAwBjB,iBAAiB;YAUjB,eAAe;IAiE7B,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,mBAAmB;IAiD3B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAkBhC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAsBpC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAe7B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAkChC;;;OAGG;IACH,OAAO,CAAC,+BAA+B;IAevC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,qBAAqB;IAU7B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAatB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAkBhC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/sentry",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.4",
4
4
  "description": "Sentry AI observability exporter for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,30 +22,23 @@
22
22
  },
23
23
  "./package.json": "./package.json"
24
24
  },
25
- "scripts": {
26
- "build": "tsup --silent --config tsup.config.ts",
27
- "build:watch": "pnpm build --watch",
28
- "test": "vitest run",
29
- "test:watch": "vitest watch",
30
- "lint": "eslint ."
31
- },
32
25
  "license": "Apache-2.0",
33
26
  "dependencies": {
34
- "@mastra/observability": "workspace:*",
35
- "@mastra/otel-exporter": "workspace:*",
36
- "@sentry/node": "^10.32.1"
27
+ "@sentry/node": "^10.32.1",
28
+ "@mastra/otel-exporter": "1.0.0-beta.15",
29
+ "@mastra/observability": "1.0.0-beta.13"
37
30
  },
38
31
  "devDependencies": {
39
- "@internal/lint": "workspace:*",
40
- "@internal/types-builder": "workspace:*",
41
- "@mastra/core": "workspace:*",
42
32
  "@types/node": "22.13.17",
43
- "@vitest/coverage-v8": "catalog:",
44
- "@vitest/ui": "catalog:",
33
+ "@vitest/coverage-v8": "4.0.12",
34
+ "@vitest/ui": "4.0.12",
45
35
  "eslint": "^9.37.0",
46
36
  "tsup": "^8.5.0",
47
- "typescript": "catalog:",
48
- "vitest": "catalog:"
37
+ "typescript": "^5.9.3",
38
+ "vitest": "4.0.16",
39
+ "@internal/lint": "0.0.53",
40
+ "@internal/types-builder": "0.0.28",
41
+ "@mastra/core": "1.0.0-beta.24"
49
42
  },
50
43
  "peerDependencies": {
51
44
  "@mastra/core": ">=1.0.0-0 <2.0.0-0"
@@ -61,5 +54,12 @@
61
54
  },
62
55
  "engines": {
63
56
  "node": ">=22.13.0"
57
+ },
58
+ "scripts": {
59
+ "build": "tsup --silent --config tsup.config.ts",
60
+ "build:watch": "pnpm build --watch",
61
+ "test": "vitest run",
62
+ "test:watch": "vitest watch",
63
+ "lint": "eslint ."
64
64
  }
65
- }
65
+ }