@mastra/otel-bridge 1.0.0-beta.1 → 1.0.0-beta.3

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,52 @@
1
1
  # @mastra/otel-bridge
2
2
 
3
+ ## 1.0.0-beta.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`72df8ae`](https://github.com/mastra-ai/mastra/commit/72df8ae595584cdd7747d5c39ffaca45e4507227), [`9198899`](https://github.com/mastra-ai/mastra/commit/91988995c427b185c33714b7f3be955367911324), [`653e65a`](https://github.com/mastra-ai/mastra/commit/653e65ae1f9502c2958a32f47a5a2df11e612a92), [`c6fd6fe`](https://github.com/mastra-ai/mastra/commit/c6fd6fedd09e9cf8004b03a80925f5e94826ad7e), [`0bed332`](https://github.com/mastra-ai/mastra/commit/0bed332843f627202c6520eaf671771313cd20f3)]:
8
+ - @mastra/core@1.0.0-beta.9
9
+ - @mastra/otel-exporter@1.0.0-beta.4
10
+
11
+ ## 1.0.0-beta.2
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated OtelExporters, Bridge, and Arize packages to better implement GenAI v1.38.0 Otel Semantic Conventions. See: ([#10591](https://github.com/mastra-ai/mastra/pull/10591))
16
+ https://github.com/open-telemetry/semantic-conventions/blob/v1.38.0/docs/gen-ai/README.md
17
+
18
+ - feat(observability): Add tags support to OtelExporter, OtelBridge, and ArizeExporter ([#10843](https://github.com/mastra-ai/mastra/pull/10843))
19
+
20
+ This change adds support for the `tracingOptions.tags` feature to the OpenTelemetry-based exporters and bridge. Tags are now included as span attributes when present on root spans, following the same pattern as Braintrust and Langfuse exporters.
21
+
22
+ **Changes:**
23
+ - **OtelExporter**: Tags are now included as `mastra.tags` span attribute for root spans
24
+ - **OtelBridge**: Tags flow through the SpanConverter and are included in native OTEL spans as `mastra.tags`
25
+ - **ArizeExporter**: Tags are mapped to the native OpenInference `tag.tags` semantic convention
26
+
27
+ **Implementation Details:**
28
+ - Tags are only included on root spans (by design)
29
+ - Tags are stored as JSON-stringified arrays for maximum backend compatibility (many OTEL backends have limited native array support)
30
+ - Empty or undefined tag arrays are not included in span attributes
31
+
32
+ **Usage:**
33
+
34
+ ```typescript
35
+ const result = await agent.generate({
36
+ messages: [{ role: 'user', content: 'Hello' }],
37
+ tracingOptions: {
38
+ tags: ['production', 'experiment-v2'],
39
+ },
40
+ });
41
+ ```
42
+
43
+ Fixes #10771
44
+
45
+ - Updated dependencies [[`6c59a40`](https://github.com/mastra-ai/mastra/commit/6c59a40e0ad160467bd13d63a8a287028d75b02d), [`3076c67`](https://github.com/mastra-ai/mastra/commit/3076c6778b18988ae7d5c4c5c466366974b2d63f), [`85d7ee1`](https://github.com/mastra-ai/mastra/commit/85d7ee18ff4e14d625a8a30ec6656bb49804989b), [`c6c1092`](https://github.com/mastra-ai/mastra/commit/c6c1092f8fbf76109303f69e000e96fd1960c4ce), [`81dc110`](https://github.com/mastra-ai/mastra/commit/81dc11008d147cf5bdc8996ead1aa61dbdebb6fc), [`7aedb74`](https://github.com/mastra-ai/mastra/commit/7aedb74883adf66af38e270e4068fd42e7a37036), [`8f02d80`](https://github.com/mastra-ai/mastra/commit/8f02d800777397e4b45d7f1ad041988a8b0c6630), [`d7aad50`](https://github.com/mastra-ai/mastra/commit/d7aad501ce61646b76b4b511e558ac4eea9884d0), [`ce0a73a`](https://github.com/mastra-ai/mastra/commit/ce0a73abeaa75b10ca38f9e40a255a645d50ebfb), [`a02e542`](https://github.com/mastra-ai/mastra/commit/a02e542d23179bad250b044b17ff023caa61739f), [`a372c64`](https://github.com/mastra-ai/mastra/commit/a372c640ad1fd12e8f0613cebdc682fc156b4d95), [`db500e8`](https://github.com/mastra-ai/mastra/commit/db500e8b8c5b4df9bd3590a7da6e007c08f94945), [`8846867`](https://github.com/mastra-ai/mastra/commit/8846867ffa9a3746767618e314bebac08eb77d87), [`0bada2f`](https://github.com/mastra-ai/mastra/commit/0bada2f2c1234932cf30c1c47a719ffb64b801c5), [`42a42cf`](https://github.com/mastra-ai/mastra/commit/42a42cf3132b9786feecbb8c13c583dce5b0e198), [`cc60ff6`](https://github.com/mastra-ai/mastra/commit/cc60ff616541a3b0fb531a7e469bf9ae7bb90528), [`ae08bf0`](https://github.com/mastra-ai/mastra/commit/ae08bf0ebc6a4e4da992b711c4a389c32ba84cf4), [`21735a7`](https://github.com/mastra-ai/mastra/commit/21735a7ef306963554a69a89b44f06c3bcd85141), [`1d877b8`](https://github.com/mastra-ai/mastra/commit/1d877b8d7b536a251c1a7a18db7ddcf4f68d6f8b)]:
46
+ - @mastra/observability@1.0.0-beta.3
47
+ - @mastra/core@1.0.0-beta.7
48
+ - @mastra/otel-exporter@1.0.0-beta.3
49
+
3
50
  ## 1.0.0-beta.1
4
51
 
5
52
  ### Minor Changes
package/dist/bridge.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * nested within OTEL spans from auto-instrumentation, and any OTEL-instrumented
12
12
  * operations within Mastra spans maintain the correct hierarchy.
13
13
  */
14
- import type { ObservabilityBridge, TracingEvent, CreateSpanOptions, SpanType, SpanIds } from '@mastra/core/observability';
14
+ import type { ObservabilityBridge, TracingEvent, CreateSpanOptions, SpanType, SpanIds, InitExporterOptions } from '@mastra/core/observability';
15
15
  import { BaseExporter } from '@mastra/observability';
16
16
  /**
17
17
  * Configuration for the OtelBridge
@@ -45,7 +45,7 @@ export declare class OtelBridge extends BaseExporter implements ObservabilityBri
45
45
  name: string;
46
46
  private otelTracer;
47
47
  private otelSpanMap;
48
- private spanConverter;
48
+ private spanConverter?;
49
49
  constructor(config?: OtelBridgeConfig);
50
50
  /**
51
51
  * Handle Mastra tracing events
@@ -56,6 +56,10 @@ export declare class OtelBridge extends BaseExporter implements ObservabilityBri
56
56
  * Note: OTEL spans are created when registerSpan is called when the span is first created.
57
57
  */
58
58
  protected _exportTracingEvent(event: TracingEvent): Promise<void>;
59
+ /**
60
+ * Initialize with tracing configuration
61
+ */
62
+ init(options: InitExporterOptions): void;
59
63
  /**
60
64
  * Create a span in the bridge's tracing system.
61
65
  * Called during Mastra span construction to get bridge-generated identifiers.
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACR,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAuB,MAAM,uBAAuB,CAAC;AAK1E;;GAEG;AAEH,MAAM,MAAM,gBAAgB,GAAG,EAE9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,UAAW,SAAQ,YAAa,YAAW,mBAAmB;IACzE,IAAI,SAAU;IACd,OAAO,CAAC,UAAU,CAAuD;IACzE,OAAO,CAAC,WAAW,CAAuE;IAC1F,OAAO,CAAC,aAAa,CAAuB;gBAEhC,MAAM,GAAE,gBAAqB;IAIzC;;;;;;;OAOG;cACa,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAAG,OAAO,GAAG,SAAS;IAoDrE;;;;;OAKG;YACW,eAAe;IAoD7B;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIrE;;;;;;OAMG;IACH,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAIvD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAShC"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACP,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAuB,MAAM,uBAAuB,CAAC;AAK1E;;GAEG;AAEH,MAAM,MAAM,gBAAgB,GAAG,EAE9B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,UAAW,SAAQ,YAAa,YAAW,mBAAmB;IACzE,IAAI,SAAU;IACd,OAAO,CAAC,UAAU,CAAuD;IACzE,OAAO,CAAC,WAAW,CAAuE;IAC1F,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAE1B,MAAM,GAAE,gBAAqB;IAIzC;;;;;;;OAOG;cACa,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,mBAAmB;IAQjC;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAAG,OAAO,GAAG,SAAS;IAmDrE;;;;;OAKG;YACW,eAAe;IAwD7B;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIrE;;;;;;OAMG;IACH,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAIvD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAShC"}
package/dist/index.cjs CHANGED
@@ -10,7 +10,7 @@ var OtelBridge = class extends observability.BaseExporter {
10
10
  name = "otel";
11
11
  otelTracer = api.trace.getTracer("@mastra/otel-bridge", "1.0.0");
12
12
  otelSpanMap = /* @__PURE__ */ new Map();
13
- spanConverter = new otelExporter.SpanConverter();
13
+ spanConverter;
14
14
  constructor(config = {}) {
15
15
  super(config);
16
16
  }
@@ -27,6 +27,16 @@ var OtelBridge = class extends observability.BaseExporter {
27
27
  await this.handleSpanEnded(event);
28
28
  }
29
29
  }
30
+ /**
31
+ * Initialize with tracing configuration
32
+ */
33
+ init(options) {
34
+ this.spanConverter = new otelExporter.SpanConverter({
35
+ packageName: "@mastra/otel-bridge",
36
+ serviceName: options.config?.serviceName,
37
+ format: "GenAI_v1_38_0"
38
+ });
39
+ }
30
40
  /**
31
41
  * Create a span in the bridge's tracing system.
32
42
  * Called during Mastra span construction to get bridge-generated identifiers.
@@ -44,11 +54,10 @@ var OtelBridge = class extends observability.BaseExporter {
44
54
  parentOtelContext = parentEntry.otelContext;
45
55
  }
46
56
  }
47
- const isRootSpan = !options.parent;
48
57
  const otelSpan = this.otelTracer.startSpan(
49
58
  options.name,
50
59
  {
51
- kind: otelExporter.getSpanKind(options.type, isRootSpan)
60
+ kind: otelExporter.getSpanKind(options.type)
52
61
  },
53
62
  parentOtelContext
54
63
  );
@@ -83,9 +92,12 @@ var OtelBridge = class extends observability.BaseExporter {
83
92
  return;
84
93
  }
85
94
  this.otelSpanMap.delete(mastraSpan.id);
95
+ if (!this.spanConverter) {
96
+ return;
97
+ }
86
98
  const { otelSpan } = entry;
87
99
  this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);
88
- const readableSpan = this.spanConverter.convertSpan(mastraSpan);
100
+ const readableSpan = await this.spanConverter.convertSpan(mastraSpan);
89
101
  otelSpan.updateName(readableSpan.name);
90
102
  for (const [key, value] of Object.entries(readableSpan.attributes)) {
91
103
  if (value !== void 0 && value !== null && typeof value !== "object") {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bridge.ts"],"names":["BaseExporter","otelTrace","SpanConverter","TracingEventType","otelContext","getExternalParentId","getSpanKind","event"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * OpenTelemetry Bridge for Mastra Observability\n *\n * This bridge enables bidirectional integration with OpenTelemetry infrastructure:\n * 1. Reads OTEL trace context from active spans (via AsyncLocalStorage)\n * 2. Creates real OTEL spans when Mastra spans are created\n * 3. Maintains span context for proper parent-child relationships\n * 4. Allows OTEL-instrumented code (DB, HTTP clients) in tools/workflows to have correct parents\n *\n * This creates complete distributed traces where Mastra spans are properly\n * nested within OTEL spans from auto-instrumentation, and any OTEL-instrumented\n * operations within Mastra spans maintain the correct hierarchy.\n */\n\nimport type {\n ObservabilityBridge,\n TracingEvent,\n CreateSpanOptions,\n SpanType,\n SpanIds,\n} from '@mastra/core/observability';\nimport { TracingEventType } from '@mastra/core/observability';\nimport { BaseExporter, getExternalParentId } from '@mastra/observability';\nimport { SpanConverter, getSpanKind } from '@mastra/otel-exporter';\nimport { trace as otelTrace, context as otelContext } from '@opentelemetry/api';\nimport type { Span as OtelSpan, Context as OtelContext } from '@opentelemetry/api';\n\n/**\n * Configuration for the OtelBridge\n */\n\nexport type OtelBridgeConfig = {\n // Currently no configuration options - placeholder for future options\n};\n\n/**\n * OpenTelemetry Bridge implementation\n *\n * Creates real OTEL spans when Mastra spans are created, maintaining proper\n * context propagation for nested instrumentation.\n *\n * @example\n * ```typescript\n * import { OtelBridge } from '@mastra/otel-bridge';\n * import { Mastra } from '@mastra/core';\n *\n * const mastra = new Mastra({\n * agents: { myAgent },\n * observability: {\n * configs: {\n * default: {\n * serviceName: 'my-service',\n * bridge: new OtelBridge(),\n * }\n * }\n * }\n * });\n * ```\n */\nexport class OtelBridge extends BaseExporter implements ObservabilityBridge {\n name = 'otel';\n private otelTracer = otelTrace.getTracer('@mastra/otel-bridge', '1.0.0');\n private otelSpanMap = new Map<string, { otelSpan: OtelSpan; otelContext: OtelContext }>();\n private spanConverter = new SpanConverter();\n\n constructor(config: OtelBridgeConfig = {}) {\n super(config);\n }\n\n /**\n * Handle Mastra tracing events\n *\n * Ships OTEL spans when Mastra spans end.\n * This maintains proper span hierarchy and allows OTEL-instrumented code within\n * Mastra spans to have correct parent-child relationships.\n * Note: OTEL spans are created when registerSpan is called when the span is first created.\n */\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (event.type === TracingEventType.SPAN_ENDED) {\n await this.handleSpanEnded(event);\n }\n }\n\n /**\n * Create a span in the bridge's tracing system.\n * Called during Mastra span construction to get bridge-generated identifiers.\n *\n * @param options - Span creation options from Mastra\n * @returns Span identifiers (spanId, traceId, parentSpanId) from bridge, or undefined if creation fails\n */\n createSpan(options: CreateSpanOptions<SpanType>): SpanIds | undefined {\n try {\n // Determine parent context\n let parentOtelContext = otelContext.active();\n\n // Get external parent ID (walks up chain to find non-internal parent)\n const externalParentId = getExternalParentId(options);\n if (externalParentId) {\n // Look up external parent's OTEL span from map\n const parentEntry = this.otelSpanMap.get(externalParentId);\n if (parentEntry) {\n parentOtelContext = parentEntry.otelContext;\n }\n }\n\n // Create OTEL span with SpanKind (must be set at creation, immutable)\n const isRootSpan = !options.parent;\n const otelSpan = this.otelTracer.startSpan(\n options.name,\n {\n kind: getSpanKind(options.type, isRootSpan),\n },\n parentOtelContext,\n );\n\n // Create context with this span active\n const spanContext = otelTrace.setSpan(parentOtelContext, otelSpan);\n\n // Get OTEL span identifiers\n const otelSpanContext = otelSpan.spanContext();\n const spanId = otelSpanContext.spanId;\n const traceId = otelSpanContext.traceId;\n\n // Store for later retrieval (for executeWithSpanContext and event handling)\n this.otelSpanMap.set(spanId, { otelSpan, otelContext: spanContext });\n\n // Get parentSpanId from parent context if available\n const parentSpan = otelTrace.getSpan(parentOtelContext);\n const parentSpanId = parentSpan?.spanContext().spanId;\n\n this.logger.debug(\n `[OtelBridge.createSpan] Created span [spanId=${spanId}] [traceId=${traceId}] ` +\n `[parentSpanId=${parentSpanId}] [type=${options.type}] [mapSize=${this.otelSpanMap.size}]`,\n );\n\n return { spanId, traceId, parentSpanId };\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to create span:', error);\n return undefined;\n }\n }\n\n /**\n * Handle SPAN_ENDED event\n *\n * Retrieves the OTEL span created at SPAN_STARTED, sets all final attributes,\n * events, and status, then ends the span. Cleans up the span map entry.\n */\n private async handleSpanEnded(event: TracingEvent): Promise<void> {\n try {\n const mastraSpan = event.exportedSpan;\n const entry = this.otelSpanMap.get(mastraSpan.id);\n\n if (!entry) {\n this.logger.warn(`[OtelBridge] No OTEL span found for Mastra span [id=${mastraSpan.id}].`);\n return;\n }\n\n // Remove from map immediately to prevent memory leak\n this.otelSpanMap.delete(mastraSpan.id);\n\n const { otelSpan } = entry;\n\n this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);\n\n // Use SpanConverter to get consistent span formatting with otel-exporter\n const readableSpan = this.spanConverter.convertSpan(mastraSpan);\n\n // Update span name to match the converter's formatting\n otelSpan.updateName(readableSpan.name);\n\n // Set all attributes from the converter (includes OTEL semantic conventions)\n for (const [key, value] of Object.entries(readableSpan.attributes)) {\n if (value !== undefined && value !== null && typeof value !== 'object') {\n otelSpan.setAttribute(key, value);\n }\n }\n\n // Set status from the converter\n otelSpan.setStatus(readableSpan.status);\n\n // Add exception events if present\n for (const event of readableSpan.events) {\n if (event.name === 'exception' && event.attributes) {\n const error = new Error(event.attributes['exception.message'] as string);\n otelSpan.recordException(error);\n }\n }\n\n // End the span with the actual end time\n otelSpan.end(mastraSpan.endTime);\n\n this.logger.debug(\n `[OtelBridge] Completed OTEL span [mastraId=${mastraSpan.id}] [traceId=${otelSpan.spanContext().traceId}]`,\n );\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to handle SPAN_ENDED:', error);\n }\n }\n\n /**\n * Execute a function (sync or async) within the OTEL context of a Mastra span.\n * Retrieves the stored OTEL context for the span and executes the function within it.\n *\n * This is the core implementation used by both executeInContext and executeInContextSync.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The function to execute within the span context\n * @returns The result of the function execution\n */\n private executeWithSpanContext<T>(spanId: string, fn: () => T): T {\n const entry = this.otelSpanMap.get(spanId);\n\n this.logger.debug(\n `[OtelBridge.executeWithSpanContext] spanId=${spanId}, ` +\n `inMap=${!!entry}, ` +\n `storedOtelSpan=${entry?.otelSpan.spanContext().spanId || 'none'}`,\n );\n\n const spanContext = entry?.otelContext;\n if (spanContext) {\n return otelContext.with(spanContext, fn);\n }\n return fn();\n }\n\n /**\n * Execute an async function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The async function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContext<T>(spanId: string, fn: () => Promise<T>): Promise<T> {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Execute a synchronous function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The synchronous function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContextSync<T>(spanId: string, fn: () => T): T {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Shutdown the bridge and clean up resources\n */\n async shutdown(): Promise<void> {\n // End any remaining spans\n for (const [spanId, { otelSpan }] of this.otelSpanMap.entries()) {\n this.logger.warn(`[OtelBridge] Force-ending span that was not properly closed [id=${spanId}]`);\n otelSpan.end();\n }\n this.otelSpanMap.clear();\n this.logger.info('[OtelBridge] Shutdown complete');\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/bridge.ts"],"names":["BaseExporter","otelTrace","TracingEventType","SpanConverter","otelContext","getExternalParentId","getSpanKind","event"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * OpenTelemetry Bridge for Mastra Observability\n *\n * This bridge enables bidirectional integration with OpenTelemetry infrastructure:\n * 1. Reads OTEL trace context from active spans (via AsyncLocalStorage)\n * 2. Creates real OTEL spans when Mastra spans are created\n * 3. Maintains span context for proper parent-child relationships\n * 4. Allows OTEL-instrumented code (DB, HTTP clients) in tools/workflows to have correct parents\n *\n * This creates complete distributed traces where Mastra spans are properly\n * nested within OTEL spans from auto-instrumentation, and any OTEL-instrumented\n * operations within Mastra spans maintain the correct hierarchy.\n */\n\nimport type {\n ObservabilityBridge,\n TracingEvent,\n CreateSpanOptions,\n SpanType,\n SpanIds,\n InitExporterOptions,\n} from '@mastra/core/observability';\nimport { TracingEventType } from '@mastra/core/observability';\nimport { BaseExporter, getExternalParentId } from '@mastra/observability';\nimport { SpanConverter, getSpanKind } from '@mastra/otel-exporter';\nimport { trace as otelTrace, context as otelContext } from '@opentelemetry/api';\nimport type { Span as OtelSpan, Context as OtelContext } from '@opentelemetry/api';\n\n/**\n * Configuration for the OtelBridge\n */\n\nexport type OtelBridgeConfig = {\n // Currently no configuration options - placeholder for future options\n};\n\n/**\n * OpenTelemetry Bridge implementation\n *\n * Creates real OTEL spans when Mastra spans are created, maintaining proper\n * context propagation for nested instrumentation.\n *\n * @example\n * ```typescript\n * import { OtelBridge } from '@mastra/otel-bridge';\n * import { Mastra } from '@mastra/core';\n *\n * const mastra = new Mastra({\n * agents: { myAgent },\n * observability: {\n * configs: {\n * default: {\n * serviceName: 'my-service',\n * bridge: new OtelBridge(),\n * }\n * }\n * }\n * });\n * ```\n */\nexport class OtelBridge extends BaseExporter implements ObservabilityBridge {\n name = 'otel';\n private otelTracer = otelTrace.getTracer('@mastra/otel-bridge', '1.0.0');\n private otelSpanMap = new Map<string, { otelSpan: OtelSpan; otelContext: OtelContext }>();\n private spanConverter?: SpanConverter;\n\n constructor(config: OtelBridgeConfig = {}) {\n super(config);\n }\n\n /**\n * Handle Mastra tracing events\n *\n * Ships OTEL spans when Mastra spans end.\n * This maintains proper span hierarchy and allows OTEL-instrumented code within\n * Mastra spans to have correct parent-child relationships.\n * Note: OTEL spans are created when registerSpan is called when the span is first created.\n */\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (event.type === TracingEventType.SPAN_ENDED) {\n await this.handleSpanEnded(event);\n }\n }\n\n /**\n * Initialize with tracing configuration\n */\n init(options: InitExporterOptions) {\n this.spanConverter = new SpanConverter({\n packageName: '@mastra/otel-bridge',\n serviceName: options.config?.serviceName,\n format: 'GenAI_v1_38_0',\n });\n }\n\n /**\n * Create a span in the bridge's tracing system.\n * Called during Mastra span construction to get bridge-generated identifiers.\n *\n * @param options - Span creation options from Mastra\n * @returns Span identifiers (spanId, traceId, parentSpanId) from bridge, or undefined if creation fails\n */\n createSpan(options: CreateSpanOptions<SpanType>): SpanIds | undefined {\n try {\n // Determine parent context\n let parentOtelContext = otelContext.active();\n\n // Get external parent ID (walks up chain to find non-internal parent)\n const externalParentId = getExternalParentId(options);\n if (externalParentId) {\n // Look up external parent's OTEL span from map\n const parentEntry = this.otelSpanMap.get(externalParentId);\n if (parentEntry) {\n parentOtelContext = parentEntry.otelContext;\n }\n }\n\n // Create OTEL span with SpanKind (must be set at creation, immutable)\n const otelSpan = this.otelTracer.startSpan(\n options.name,\n {\n kind: getSpanKind(options.type),\n },\n parentOtelContext,\n );\n\n // Create context with this span active\n const spanContext = otelTrace.setSpan(parentOtelContext, otelSpan);\n\n // Get OTEL span identifiers\n const otelSpanContext = otelSpan.spanContext();\n const spanId = otelSpanContext.spanId;\n const traceId = otelSpanContext.traceId;\n\n // Store for later retrieval (for executeWithSpanContext and event handling)\n this.otelSpanMap.set(spanId, { otelSpan, otelContext: spanContext });\n\n // Get parentSpanId from parent context if available\n const parentSpan = otelTrace.getSpan(parentOtelContext);\n const parentSpanId = parentSpan?.spanContext().spanId;\n\n this.logger.debug(\n `[OtelBridge.createSpan] Created span [spanId=${spanId}] [traceId=${traceId}] ` +\n `[parentSpanId=${parentSpanId}] [type=${options.type}] [mapSize=${this.otelSpanMap.size}]`,\n );\n\n return { spanId, traceId, parentSpanId };\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to create span:', error);\n return undefined;\n }\n }\n\n /**\n * Handle SPAN_ENDED event\n *\n * Retrieves the OTEL span created at SPAN_STARTED, sets all final attributes,\n * events, and status, then ends the span. Cleans up the span map entry.\n */\n private async handleSpanEnded(event: TracingEvent): Promise<void> {\n try {\n const mastraSpan = event.exportedSpan;\n const entry = this.otelSpanMap.get(mastraSpan.id);\n\n if (!entry) {\n this.logger.warn(`[OtelBridge] No OTEL span found for Mastra span [id=${mastraSpan.id}].`);\n return;\n }\n\n // Remove from map immediately to prevent memory leak\n this.otelSpanMap.delete(mastraSpan.id);\n\n if (!this.spanConverter) {\n return;\n }\n\n const { otelSpan } = entry;\n\n this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);\n\n // Use SpanConverter to get consistent span formatting with otel-exporter\n const readableSpan = await this.spanConverter!.convertSpan(mastraSpan);\n\n // Update span name to match the converter's formatting\n otelSpan.updateName(readableSpan.name);\n\n // Set all attributes from the converter (includes OTEL semantic conventions)\n for (const [key, value] of Object.entries(readableSpan.attributes)) {\n if (value !== undefined && value !== null && typeof value !== 'object') {\n otelSpan.setAttribute(key, value);\n }\n }\n\n // Set status from the converter\n otelSpan.setStatus(readableSpan.status);\n\n // Add exception events if present\n for (const event of readableSpan.events) {\n if (event.name === 'exception' && event.attributes) {\n const error = new Error(event.attributes['exception.message'] as string);\n otelSpan.recordException(error);\n }\n }\n\n // End the span with the actual end time\n otelSpan.end(mastraSpan.endTime);\n\n this.logger.debug(\n `[OtelBridge] Completed OTEL span [mastraId=${mastraSpan.id}] [traceId=${otelSpan.spanContext().traceId}]`,\n );\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to handle SPAN_ENDED:', error);\n }\n }\n\n /**\n * Execute a function (sync or async) within the OTEL context of a Mastra span.\n * Retrieves the stored OTEL context for the span and executes the function within it.\n *\n * This is the core implementation used by both executeInContext and executeInContextSync.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The function to execute within the span context\n * @returns The result of the function execution\n */\n private executeWithSpanContext<T>(spanId: string, fn: () => T): T {\n const entry = this.otelSpanMap.get(spanId);\n\n this.logger.debug(\n `[OtelBridge.executeWithSpanContext] spanId=${spanId}, ` +\n `inMap=${!!entry}, ` +\n `storedOtelSpan=${entry?.otelSpan.spanContext().spanId || 'none'}`,\n );\n\n const spanContext = entry?.otelContext;\n if (spanContext) {\n return otelContext.with(spanContext, fn);\n }\n return fn();\n }\n\n /**\n * Execute an async function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The async function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContext<T>(spanId: string, fn: () => Promise<T>): Promise<T> {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Execute a synchronous function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The synchronous function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContextSync<T>(spanId: string, fn: () => T): T {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Shutdown the bridge and clean up resources\n */\n async shutdown(): Promise<void> {\n // End any remaining spans\n for (const [spanId, { otelSpan }] of this.otelSpanMap.entries()) {\n this.logger.warn(`[OtelBridge] Force-ending span that was not properly closed [id=${spanId}]`);\n otelSpan.end();\n }\n this.otelSpanMap.clear();\n this.logger.info('[OtelBridge] Shutdown complete');\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ var OtelBridge = class extends BaseExporter {
8
8
  name = "otel";
9
9
  otelTracer = trace.getTracer("@mastra/otel-bridge", "1.0.0");
10
10
  otelSpanMap = /* @__PURE__ */ new Map();
11
- spanConverter = new SpanConverter();
11
+ spanConverter;
12
12
  constructor(config = {}) {
13
13
  super(config);
14
14
  }
@@ -25,6 +25,16 @@ var OtelBridge = class extends BaseExporter {
25
25
  await this.handleSpanEnded(event);
26
26
  }
27
27
  }
28
+ /**
29
+ * Initialize with tracing configuration
30
+ */
31
+ init(options) {
32
+ this.spanConverter = new SpanConverter({
33
+ packageName: "@mastra/otel-bridge",
34
+ serviceName: options.config?.serviceName,
35
+ format: "GenAI_v1_38_0"
36
+ });
37
+ }
28
38
  /**
29
39
  * Create a span in the bridge's tracing system.
30
40
  * Called during Mastra span construction to get bridge-generated identifiers.
@@ -42,11 +52,10 @@ var OtelBridge = class extends BaseExporter {
42
52
  parentOtelContext = parentEntry.otelContext;
43
53
  }
44
54
  }
45
- const isRootSpan = !options.parent;
46
55
  const otelSpan = this.otelTracer.startSpan(
47
56
  options.name,
48
57
  {
49
- kind: getSpanKind(options.type, isRootSpan)
58
+ kind: getSpanKind(options.type)
50
59
  },
51
60
  parentOtelContext
52
61
  );
@@ -81,9 +90,12 @@ var OtelBridge = class extends BaseExporter {
81
90
  return;
82
91
  }
83
92
  this.otelSpanMap.delete(mastraSpan.id);
93
+ if (!this.spanConverter) {
94
+ return;
95
+ }
84
96
  const { otelSpan } = entry;
85
97
  this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);
86
- const readableSpan = this.spanConverter.convertSpan(mastraSpan);
98
+ const readableSpan = await this.spanConverter.convertSpan(mastraSpan);
87
99
  otelSpan.updateName(readableSpan.name);
88
100
  for (const [key, value] of Object.entries(readableSpan.attributes)) {
89
101
  if (value !== void 0 && value !== null && typeof value !== "object") {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bridge.ts"],"names":["otelTrace","otelContext","event"],"mappings":";;;;;;AA2DO,IAAM,UAAA,GAAN,cAAyB,YAAA,CAA4C;AAAA,EAC1E,IAAA,GAAO,MAAA;AAAA,EACC,UAAA,GAAaA,KAAA,CAAU,SAAA,CAAU,qBAAA,EAAuB,OAAO,CAAA;AAAA,EAC/D,WAAA,uBAAkB,GAAA,EAA8D;AAAA,EAChF,aAAA,GAAgB,IAAI,aAAA,EAAc;AAAA,EAE1C,WAAA,CAAY,MAAA,GAA2B,EAAC,EAAG;AACzC,IAAA,KAAA,CAAM,MAAM,CAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAgB,oBAAoB,KAAA,EAAoC;AACtE,IAAA,IAAI,KAAA,CAAM,IAAA,KAAS,gBAAA,CAAiB,UAAA,EAAY;AAC9C,MAAA,MAAM,IAAA,CAAK,gBAAgB,KAAK,CAAA;AAAA,IAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,OAAA,EAA2D;AACpE,IAAA,IAAI;AAEF,MAAA,IAAI,iBAAA,GAAoBC,QAAY,MAAA,EAAO;AAG3C,MAAA,MAAM,gBAAA,GAAmB,oBAAoB,OAAO,CAAA;AACpD,MAAA,IAAI,gBAAA,EAAkB;AAEpB,QAAA,MAAM,WAAA,GAAc,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,gBAAgB,CAAA;AACzD,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,iBAAA,GAAoB,WAAA,CAAY,WAAA;AAAA,QAClC;AAAA,MACF;AAGA,MAAA,MAAM,UAAA,GAAa,CAAC,OAAA,CAAQ,MAAA;AAC5B,MAAA,MAAM,QAAA,GAAW,KAAK,UAAA,CAAW,SAAA;AAAA,QAC/B,OAAA,CAAQ,IAAA;AAAA,QACR;AAAA,UACE,IAAA,EAAM,WAAA,CAAY,OAAA,CAAQ,IAAA,EAAM,UAAU;AAAA,SAC5C;AAAA,QACA;AAAA,OACF;AAGA,MAAA,MAAM,WAAA,GAAcD,KAAA,CAAU,OAAA,CAAQ,iBAAA,EAAmB,QAAQ,CAAA;AAGjE,MAAA,MAAM,eAAA,GAAkB,SAAS,WAAA,EAAY;AAC7C,MAAA,MAAM,SAAS,eAAA,CAAgB,MAAA;AAC/B,MAAA,MAAM,UAAU,eAAA,CAAgB,OAAA;AAGhC,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,MAAA,EAAQ,EAAE,QAAA,EAAU,WAAA,EAAa,aAAa,CAAA;AAGnE,MAAA,MAAM,UAAA,GAAaA,KAAA,CAAU,OAAA,CAAQ,iBAAiB,CAAA;AACtD,MAAA,MAAM,YAAA,GAAe,UAAA,EAAY,WAAA,EAAY,CAAE,MAAA;AAE/C,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,6CAAA,EAAgD,MAAM,CAAA,WAAA,EAAc,OAAO,CAAA,gBAAA,EACxD,YAAY,CAAA,QAAA,EAAW,OAAA,CAAQ,IAAI,CAAA,WAAA,EAAc,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA,CAAA;AAAA,OAC3F;AAEA,MAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,YAAA,EAAa;AAAA,IACzC,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,qCAAA,EAAuC,KAAK,CAAA;AAC9D,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,gBAAgB,KAAA,EAAoC;AAChE,IAAA,IAAI;AACF,MAAA,MAAM,aAAa,KAAA,CAAM,YAAA;AACzB,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,WAAW,EAAE,CAAA;AAEhD,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,CAAA,oDAAA,EAAuD,UAAA,CAAW,EAAE,CAAA,EAAA,CAAI,CAAA;AACzF,QAAA;AAAA,MACF;AAGA,MAAA,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,UAAA,CAAW,EAAE,CAAA;AAErC,MAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AAErB,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,wCAAA,EAA2C,UAAA,CAAW,EAAE,CAAA,QAAA,EAAW,UAAA,CAAW,IAAI,CAAA,CAAA,CAAG,CAAA;AAGvG,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,aAAA,CAAc,WAAA,CAAY,UAAU,CAAA;AAG9D,MAAA,QAAA,CAAS,UAAA,CAAW,aAAa,IAAI,CAAA;AAGrC,MAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,YAAA,CAAa,UAAU,CAAA,EAAG;AAClE,QAAA,IAAI,UAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,OAAO,UAAU,QAAA,EAAU;AACtE,UAAA,QAAA,CAAS,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,QAClC;AAAA,MACF;AAGA,MAAA,QAAA,CAAS,SAAA,CAAU,aAAa,MAAM,CAAA;AAGtC,MAAA,KAAA,MAAWE,MAAAA,IAAS,aAAa,MAAA,EAAQ;AACvC,QAAA,IAAIA,MAAAA,CAAM,IAAA,KAAS,WAAA,IAAeA,MAAAA,CAAM,UAAA,EAAY;AAClD,UAAA,MAAM,QAAQ,IAAI,KAAA,CAAMA,MAAAA,CAAM,UAAA,CAAW,mBAAmB,CAAW,CAAA;AACvE,UAAA,QAAA,CAAS,gBAAgB,KAAK,CAAA;AAAA,QAChC;AAAA,MACF;AAGA,MAAA,QAAA,CAAS,GAAA,CAAI,WAAW,OAAO,CAAA;AAE/B,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,8CAA8C,UAAA,CAAW,EAAE,cAAc,QAAA,CAAS,WAAA,GAAc,OAAO,CAAA,CAAA;AAAA,OACzG;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,2CAAA,EAA6C,KAAK,CAAA;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,sBAAA,CAA0B,QAAgB,EAAA,EAAgB;AAChE,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,MAAM,CAAA;AAEzC,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MACV,CAAA,2CAAA,EAA8C,MAAM,CAAA,QAAA,EACzC,CAAC,CAAC,KAAK,CAAA,iBAAA,EACE,KAAA,EAAO,QAAA,CAAS,WAAA,EAAY,CAAE,MAAA,IAAU,MAAM,CAAA;AAAA,KACpE;AAEA,IAAA,MAAM,cAAc,KAAA,EAAO,WAAA;AAC3B,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,OAAOD,OAAA,CAAY,IAAA,CAAK,WAAA,EAAa,EAAE,CAAA;AAAA,IACzC;AACA,IAAA,OAAO,EAAA,EAAG;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,gBAAA,CAAoB,QAAgB,EAAA,EAAkC;AACpE,IAAA,OAAO,IAAA,CAAK,sBAAA,CAAuB,MAAA,EAAQ,EAAE,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBAAA,CAAwB,QAAgB,EAAA,EAAgB;AACtD,IAAA,OAAO,IAAA,CAAK,sBAAA,CAAuB,MAAA,EAAQ,EAAE,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,GAA0B;AAE9B,IAAA,KAAA,MAAW,CAAC,QAAQ,EAAE,QAAA,EAAU,CAAA,IAAK,IAAA,CAAK,WAAA,CAAY,OAAA,EAAQ,EAAG;AAC/D,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,CAAA,gEAAA,EAAmE,MAAM,CAAA,CAAA,CAAG,CAAA;AAC7F,MAAA,QAAA,CAAS,GAAA,EAAI;AAAA,IACf;AACA,IAAA,IAAA,CAAK,YAAY,KAAA,EAAM;AACvB,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,gCAAgC,CAAA;AAAA,EACnD;AACF","file":"index.js","sourcesContent":["/**\n * OpenTelemetry Bridge for Mastra Observability\n *\n * This bridge enables bidirectional integration with OpenTelemetry infrastructure:\n * 1. Reads OTEL trace context from active spans (via AsyncLocalStorage)\n * 2. Creates real OTEL spans when Mastra spans are created\n * 3. Maintains span context for proper parent-child relationships\n * 4. Allows OTEL-instrumented code (DB, HTTP clients) in tools/workflows to have correct parents\n *\n * This creates complete distributed traces where Mastra spans are properly\n * nested within OTEL spans from auto-instrumentation, and any OTEL-instrumented\n * operations within Mastra spans maintain the correct hierarchy.\n */\n\nimport type {\n ObservabilityBridge,\n TracingEvent,\n CreateSpanOptions,\n SpanType,\n SpanIds,\n} from '@mastra/core/observability';\nimport { TracingEventType } from '@mastra/core/observability';\nimport { BaseExporter, getExternalParentId } from '@mastra/observability';\nimport { SpanConverter, getSpanKind } from '@mastra/otel-exporter';\nimport { trace as otelTrace, context as otelContext } from '@opentelemetry/api';\nimport type { Span as OtelSpan, Context as OtelContext } from '@opentelemetry/api';\n\n/**\n * Configuration for the OtelBridge\n */\n\nexport type OtelBridgeConfig = {\n // Currently no configuration options - placeholder for future options\n};\n\n/**\n * OpenTelemetry Bridge implementation\n *\n * Creates real OTEL spans when Mastra spans are created, maintaining proper\n * context propagation for nested instrumentation.\n *\n * @example\n * ```typescript\n * import { OtelBridge } from '@mastra/otel-bridge';\n * import { Mastra } from '@mastra/core';\n *\n * const mastra = new Mastra({\n * agents: { myAgent },\n * observability: {\n * configs: {\n * default: {\n * serviceName: 'my-service',\n * bridge: new OtelBridge(),\n * }\n * }\n * }\n * });\n * ```\n */\nexport class OtelBridge extends BaseExporter implements ObservabilityBridge {\n name = 'otel';\n private otelTracer = otelTrace.getTracer('@mastra/otel-bridge', '1.0.0');\n private otelSpanMap = new Map<string, { otelSpan: OtelSpan; otelContext: OtelContext }>();\n private spanConverter = new SpanConverter();\n\n constructor(config: OtelBridgeConfig = {}) {\n super(config);\n }\n\n /**\n * Handle Mastra tracing events\n *\n * Ships OTEL spans when Mastra spans end.\n * This maintains proper span hierarchy and allows OTEL-instrumented code within\n * Mastra spans to have correct parent-child relationships.\n * Note: OTEL spans are created when registerSpan is called when the span is first created.\n */\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (event.type === TracingEventType.SPAN_ENDED) {\n await this.handleSpanEnded(event);\n }\n }\n\n /**\n * Create a span in the bridge's tracing system.\n * Called during Mastra span construction to get bridge-generated identifiers.\n *\n * @param options - Span creation options from Mastra\n * @returns Span identifiers (spanId, traceId, parentSpanId) from bridge, or undefined if creation fails\n */\n createSpan(options: CreateSpanOptions<SpanType>): SpanIds | undefined {\n try {\n // Determine parent context\n let parentOtelContext = otelContext.active();\n\n // Get external parent ID (walks up chain to find non-internal parent)\n const externalParentId = getExternalParentId(options);\n if (externalParentId) {\n // Look up external parent's OTEL span from map\n const parentEntry = this.otelSpanMap.get(externalParentId);\n if (parentEntry) {\n parentOtelContext = parentEntry.otelContext;\n }\n }\n\n // Create OTEL span with SpanKind (must be set at creation, immutable)\n const isRootSpan = !options.parent;\n const otelSpan = this.otelTracer.startSpan(\n options.name,\n {\n kind: getSpanKind(options.type, isRootSpan),\n },\n parentOtelContext,\n );\n\n // Create context with this span active\n const spanContext = otelTrace.setSpan(parentOtelContext, otelSpan);\n\n // Get OTEL span identifiers\n const otelSpanContext = otelSpan.spanContext();\n const spanId = otelSpanContext.spanId;\n const traceId = otelSpanContext.traceId;\n\n // Store for later retrieval (for executeWithSpanContext and event handling)\n this.otelSpanMap.set(spanId, { otelSpan, otelContext: spanContext });\n\n // Get parentSpanId from parent context if available\n const parentSpan = otelTrace.getSpan(parentOtelContext);\n const parentSpanId = parentSpan?.spanContext().spanId;\n\n this.logger.debug(\n `[OtelBridge.createSpan] Created span [spanId=${spanId}] [traceId=${traceId}] ` +\n `[parentSpanId=${parentSpanId}] [type=${options.type}] [mapSize=${this.otelSpanMap.size}]`,\n );\n\n return { spanId, traceId, parentSpanId };\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to create span:', error);\n return undefined;\n }\n }\n\n /**\n * Handle SPAN_ENDED event\n *\n * Retrieves the OTEL span created at SPAN_STARTED, sets all final attributes,\n * events, and status, then ends the span. Cleans up the span map entry.\n */\n private async handleSpanEnded(event: TracingEvent): Promise<void> {\n try {\n const mastraSpan = event.exportedSpan;\n const entry = this.otelSpanMap.get(mastraSpan.id);\n\n if (!entry) {\n this.logger.warn(`[OtelBridge] No OTEL span found for Mastra span [id=${mastraSpan.id}].`);\n return;\n }\n\n // Remove from map immediately to prevent memory leak\n this.otelSpanMap.delete(mastraSpan.id);\n\n const { otelSpan } = entry;\n\n this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);\n\n // Use SpanConverter to get consistent span formatting with otel-exporter\n const readableSpan = this.spanConverter.convertSpan(mastraSpan);\n\n // Update span name to match the converter's formatting\n otelSpan.updateName(readableSpan.name);\n\n // Set all attributes from the converter (includes OTEL semantic conventions)\n for (const [key, value] of Object.entries(readableSpan.attributes)) {\n if (value !== undefined && value !== null && typeof value !== 'object') {\n otelSpan.setAttribute(key, value);\n }\n }\n\n // Set status from the converter\n otelSpan.setStatus(readableSpan.status);\n\n // Add exception events if present\n for (const event of readableSpan.events) {\n if (event.name === 'exception' && event.attributes) {\n const error = new Error(event.attributes['exception.message'] as string);\n otelSpan.recordException(error);\n }\n }\n\n // End the span with the actual end time\n otelSpan.end(mastraSpan.endTime);\n\n this.logger.debug(\n `[OtelBridge] Completed OTEL span [mastraId=${mastraSpan.id}] [traceId=${otelSpan.spanContext().traceId}]`,\n );\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to handle SPAN_ENDED:', error);\n }\n }\n\n /**\n * Execute a function (sync or async) within the OTEL context of a Mastra span.\n * Retrieves the stored OTEL context for the span and executes the function within it.\n *\n * This is the core implementation used by both executeInContext and executeInContextSync.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The function to execute within the span context\n * @returns The result of the function execution\n */\n private executeWithSpanContext<T>(spanId: string, fn: () => T): T {\n const entry = this.otelSpanMap.get(spanId);\n\n this.logger.debug(\n `[OtelBridge.executeWithSpanContext] spanId=${spanId}, ` +\n `inMap=${!!entry}, ` +\n `storedOtelSpan=${entry?.otelSpan.spanContext().spanId || 'none'}`,\n );\n\n const spanContext = entry?.otelContext;\n if (spanContext) {\n return otelContext.with(spanContext, fn);\n }\n return fn();\n }\n\n /**\n * Execute an async function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The async function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContext<T>(spanId: string, fn: () => Promise<T>): Promise<T> {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Execute a synchronous function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The synchronous function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContextSync<T>(spanId: string, fn: () => T): T {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Shutdown the bridge and clean up resources\n */\n async shutdown(): Promise<void> {\n // End any remaining spans\n for (const [spanId, { otelSpan }] of this.otelSpanMap.entries()) {\n this.logger.warn(`[OtelBridge] Force-ending span that was not properly closed [id=${spanId}]`);\n otelSpan.end();\n }\n this.otelSpanMap.clear();\n this.logger.info('[OtelBridge] Shutdown complete');\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/bridge.ts"],"names":["otelTrace","otelContext","event"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * OpenTelemetry Bridge for Mastra Observability\n *\n * This bridge enables bidirectional integration with OpenTelemetry infrastructure:\n * 1. Reads OTEL trace context from active spans (via AsyncLocalStorage)\n * 2. Creates real OTEL spans when Mastra spans are created\n * 3. Maintains span context for proper parent-child relationships\n * 4. Allows OTEL-instrumented code (DB, HTTP clients) in tools/workflows to have correct parents\n *\n * This creates complete distributed traces where Mastra spans are properly\n * nested within OTEL spans from auto-instrumentation, and any OTEL-instrumented\n * operations within Mastra spans maintain the correct hierarchy.\n */\n\nimport type {\n ObservabilityBridge,\n TracingEvent,\n CreateSpanOptions,\n SpanType,\n SpanIds,\n InitExporterOptions,\n} from '@mastra/core/observability';\nimport { TracingEventType } from '@mastra/core/observability';\nimport { BaseExporter, getExternalParentId } from '@mastra/observability';\nimport { SpanConverter, getSpanKind } from '@mastra/otel-exporter';\nimport { trace as otelTrace, context as otelContext } from '@opentelemetry/api';\nimport type { Span as OtelSpan, Context as OtelContext } from '@opentelemetry/api';\n\n/**\n * Configuration for the OtelBridge\n */\n\nexport type OtelBridgeConfig = {\n // Currently no configuration options - placeholder for future options\n};\n\n/**\n * OpenTelemetry Bridge implementation\n *\n * Creates real OTEL spans when Mastra spans are created, maintaining proper\n * context propagation for nested instrumentation.\n *\n * @example\n * ```typescript\n * import { OtelBridge } from '@mastra/otel-bridge';\n * import { Mastra } from '@mastra/core';\n *\n * const mastra = new Mastra({\n * agents: { myAgent },\n * observability: {\n * configs: {\n * default: {\n * serviceName: 'my-service',\n * bridge: new OtelBridge(),\n * }\n * }\n * }\n * });\n * ```\n */\nexport class OtelBridge extends BaseExporter implements ObservabilityBridge {\n name = 'otel';\n private otelTracer = otelTrace.getTracer('@mastra/otel-bridge', '1.0.0');\n private otelSpanMap = new Map<string, { otelSpan: OtelSpan; otelContext: OtelContext }>();\n private spanConverter?: SpanConverter;\n\n constructor(config: OtelBridgeConfig = {}) {\n super(config);\n }\n\n /**\n * Handle Mastra tracing events\n *\n * Ships OTEL spans when Mastra spans end.\n * This maintains proper span hierarchy and allows OTEL-instrumented code within\n * Mastra spans to have correct parent-child relationships.\n * Note: OTEL spans are created when registerSpan is called when the span is first created.\n */\n protected async _exportTracingEvent(event: TracingEvent): Promise<void> {\n if (event.type === TracingEventType.SPAN_ENDED) {\n await this.handleSpanEnded(event);\n }\n }\n\n /**\n * Initialize with tracing configuration\n */\n init(options: InitExporterOptions) {\n this.spanConverter = new SpanConverter({\n packageName: '@mastra/otel-bridge',\n serviceName: options.config?.serviceName,\n format: 'GenAI_v1_38_0',\n });\n }\n\n /**\n * Create a span in the bridge's tracing system.\n * Called during Mastra span construction to get bridge-generated identifiers.\n *\n * @param options - Span creation options from Mastra\n * @returns Span identifiers (spanId, traceId, parentSpanId) from bridge, or undefined if creation fails\n */\n createSpan(options: CreateSpanOptions<SpanType>): SpanIds | undefined {\n try {\n // Determine parent context\n let parentOtelContext = otelContext.active();\n\n // Get external parent ID (walks up chain to find non-internal parent)\n const externalParentId = getExternalParentId(options);\n if (externalParentId) {\n // Look up external parent's OTEL span from map\n const parentEntry = this.otelSpanMap.get(externalParentId);\n if (parentEntry) {\n parentOtelContext = parentEntry.otelContext;\n }\n }\n\n // Create OTEL span with SpanKind (must be set at creation, immutable)\n const otelSpan = this.otelTracer.startSpan(\n options.name,\n {\n kind: getSpanKind(options.type),\n },\n parentOtelContext,\n );\n\n // Create context with this span active\n const spanContext = otelTrace.setSpan(parentOtelContext, otelSpan);\n\n // Get OTEL span identifiers\n const otelSpanContext = otelSpan.spanContext();\n const spanId = otelSpanContext.spanId;\n const traceId = otelSpanContext.traceId;\n\n // Store for later retrieval (for executeWithSpanContext and event handling)\n this.otelSpanMap.set(spanId, { otelSpan, otelContext: spanContext });\n\n // Get parentSpanId from parent context if available\n const parentSpan = otelTrace.getSpan(parentOtelContext);\n const parentSpanId = parentSpan?.spanContext().spanId;\n\n this.logger.debug(\n `[OtelBridge.createSpan] Created span [spanId=${spanId}] [traceId=${traceId}] ` +\n `[parentSpanId=${parentSpanId}] [type=${options.type}] [mapSize=${this.otelSpanMap.size}]`,\n );\n\n return { spanId, traceId, parentSpanId };\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to create span:', error);\n return undefined;\n }\n }\n\n /**\n * Handle SPAN_ENDED event\n *\n * Retrieves the OTEL span created at SPAN_STARTED, sets all final attributes,\n * events, and status, then ends the span. Cleans up the span map entry.\n */\n private async handleSpanEnded(event: TracingEvent): Promise<void> {\n try {\n const mastraSpan = event.exportedSpan;\n const entry = this.otelSpanMap.get(mastraSpan.id);\n\n if (!entry) {\n this.logger.warn(`[OtelBridge] No OTEL span found for Mastra span [id=${mastraSpan.id}].`);\n return;\n }\n\n // Remove from map immediately to prevent memory leak\n this.otelSpanMap.delete(mastraSpan.id);\n\n if (!this.spanConverter) {\n return;\n }\n\n const { otelSpan } = entry;\n\n this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);\n\n // Use SpanConverter to get consistent span formatting with otel-exporter\n const readableSpan = await this.spanConverter!.convertSpan(mastraSpan);\n\n // Update span name to match the converter's formatting\n otelSpan.updateName(readableSpan.name);\n\n // Set all attributes from the converter (includes OTEL semantic conventions)\n for (const [key, value] of Object.entries(readableSpan.attributes)) {\n if (value !== undefined && value !== null && typeof value !== 'object') {\n otelSpan.setAttribute(key, value);\n }\n }\n\n // Set status from the converter\n otelSpan.setStatus(readableSpan.status);\n\n // Add exception events if present\n for (const event of readableSpan.events) {\n if (event.name === 'exception' && event.attributes) {\n const error = new Error(event.attributes['exception.message'] as string);\n otelSpan.recordException(error);\n }\n }\n\n // End the span with the actual end time\n otelSpan.end(mastraSpan.endTime);\n\n this.logger.debug(\n `[OtelBridge] Completed OTEL span [mastraId=${mastraSpan.id}] [traceId=${otelSpan.spanContext().traceId}]`,\n );\n } catch (error) {\n this.logger.error('[OtelBridge] Failed to handle SPAN_ENDED:', error);\n }\n }\n\n /**\n * Execute a function (sync or async) within the OTEL context of a Mastra span.\n * Retrieves the stored OTEL context for the span and executes the function within it.\n *\n * This is the core implementation used by both executeInContext and executeInContextSync.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The function to execute within the span context\n * @returns The result of the function execution\n */\n private executeWithSpanContext<T>(spanId: string, fn: () => T): T {\n const entry = this.otelSpanMap.get(spanId);\n\n this.logger.debug(\n `[OtelBridge.executeWithSpanContext] spanId=${spanId}, ` +\n `inMap=${!!entry}, ` +\n `storedOtelSpan=${entry?.otelSpan.spanContext().spanId || 'none'}`,\n );\n\n const spanContext = entry?.otelContext;\n if (spanContext) {\n return otelContext.with(spanContext, fn);\n }\n return fn();\n }\n\n /**\n * Execute an async function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The async function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContext<T>(spanId: string, fn: () => Promise<T>): Promise<T> {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Execute a synchronous function within the OTEL context of a Mastra span.\n *\n * @param spanId - The ID of the Mastra span to use as context\n * @param fn - The synchronous function to execute within the span context\n * @returns The result of the function execution\n */\n executeInContextSync<T>(spanId: string, fn: () => T): T {\n return this.executeWithSpanContext(spanId, fn);\n }\n\n /**\n * Shutdown the bridge and clean up resources\n */\n async shutdown(): Promise<void> {\n // End any remaining spans\n for (const [spanId, { otelSpan }] of this.otelSpanMap.entries()) {\n this.logger.warn(`[OtelBridge] Force-ending span that was not properly closed [id=${spanId}]`);\n otelSpan.end();\n }\n this.otelSpanMap.clear();\n this.logger.info('[OtelBridge] Shutdown complete');\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/otel-bridge",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "OpenTelemetry observability bridge for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,8 +25,8 @@
25
25
  "license": "Apache-2.0",
26
26
  "dependencies": {
27
27
  "@opentelemetry/api": "^1.9.0",
28
- "@mastra/observability": "1.0.0-beta.2",
29
- "@mastra/otel-exporter": "1.0.0-beta.2"
28
+ "@mastra/observability": "1.0.0-beta.3",
29
+ "@mastra/otel-exporter": "1.0.0-beta.4"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@microsoft/api-extractor": "^7.52.8",
@@ -36,8 +36,8 @@
36
36
  "typescript": "^5.8.3",
37
37
  "vitest": "^3.2.4",
38
38
  "@internal/lint": "0.0.53",
39
- "@mastra/core": "1.0.0-beta.6",
40
- "@internal/types-builder": "0.0.28"
39
+ "@internal/types-builder": "0.0.28",
40
+ "@mastra/core": "1.0.0-beta.9"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@mastra/core": ">=1.0.0-0 <2.0.0-0",