@mastra/otel-bridge 1.4.3 → 1.4.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 +18 -0
- package/dist/index.cjs +266 -270
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +264 -267
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @mastra/otel-bridge
|
|
2
2
|
|
|
3
|
+
## 1.4.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`ce93a3c`](https://github.com/mastra-ai/mastra/commit/ce93a3c114ea1cbfbd576f3db41d7c26c9844f5b), [`5718a22`](https://github.com/mastra-ai/mastra/commit/5718a229281dcfd36bcd1f42a242e3717e510a33), [`a211d09`](https://github.com/mastra-ai/mastra/commit/a211d09185dc65a746534914cf38b67f21ee9bac), [`0dca9d0`](https://github.com/mastra-ai/mastra/commit/0dca9d0b1356024a53b72ea6f040db528b126caa), [`6218217`](https://github.com/mastra-ai/mastra/commit/62182171b6cfca0b099f1c6a77a2e65e7639ab86), [`5807d3a`](https://github.com/mastra-ai/mastra/commit/5807d3ae1d259b8b7d6df7e5bf2b485c694af9c8), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`05db566`](https://github.com/mastra-ai/mastra/commit/05db566fcbdcbf33d0bffca0c72ec30129e2e3ca), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`5718a22`](https://github.com/mastra-ai/mastra/commit/5718a229281dcfd36bcd1f42a242e3717e510a33), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`d1b7e3a`](https://github.com/mastra-ai/mastra/commit/d1b7e3a978a309a5653eeaa490d2d6c7c53bd093), [`29c584a`](https://github.com/mastra-ai/mastra/commit/29c584a13a88831e5ed1fdeb0ff8e82eae180433), [`c093146`](https://github.com/mastra-ai/mastra/commit/c0931466404d3c521308ea119cb165bb7e695155), [`8124754`](https://github.com/mastra-ai/mastra/commit/8124754ae89fbc69f8136d1df4a91904d0f84c4e), [`d12b2e4`](https://github.com/mastra-ai/mastra/commit/d12b2e4023fd9e3d3e93a9169f5088bcee2a849c), [`d1b7e3a`](https://github.com/mastra-ai/mastra/commit/d1b7e3a978a309a5653eeaa490d2d6c7c53bd093)]:
|
|
8
|
+
- @mastra/core@1.54.0
|
|
9
|
+
- @mastra/observability@1.16.3
|
|
10
|
+
- @mastra/otel-exporter@1.3.6
|
|
11
|
+
|
|
12
|
+
## 1.4.4-alpha.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [[`ce93a3c`](https://github.com/mastra-ai/mastra/commit/ce93a3c114ea1cbfbd576f3db41d7c26c9844f5b), [`5718a22`](https://github.com/mastra-ai/mastra/commit/5718a229281dcfd36bcd1f42a242e3717e510a33), [`5807d3a`](https://github.com/mastra-ai/mastra/commit/5807d3ae1d259b8b7d6df7e5bf2b485c694af9c8), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`5718a22`](https://github.com/mastra-ai/mastra/commit/5718a229281dcfd36bcd1f42a242e3717e510a33), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`d1b7e3a`](https://github.com/mastra-ai/mastra/commit/d1b7e3a978a309a5653eeaa490d2d6c7c53bd093), [`c093146`](https://github.com/mastra-ai/mastra/commit/c0931466404d3c521308ea119cb165bb7e695155), [`d1b7e3a`](https://github.com/mastra-ai/mastra/commit/d1b7e3a978a309a5653eeaa490d2d6c7c53bd093)]:
|
|
17
|
+
- @mastra/core@1.54.0-alpha.1
|
|
18
|
+
- @mastra/observability@1.16.3-alpha.0
|
|
19
|
+
- @mastra/otel-exporter@1.3.6-alpha.0
|
|
20
|
+
|
|
3
21
|
## 1.4.3
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -1,273 +1,269 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
this.otelSpanMap.clear();
|
|
267
|
-
this.logger.info("[OtelBridge] Shutdown complete");
|
|
268
|
-
}
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let _mastra_core_observability = require("@mastra/core/observability");
|
|
3
|
+
let _mastra_observability = require("@mastra/observability");
|
|
4
|
+
let _mastra_otel_exporter = require("@mastra/otel-exporter");
|
|
5
|
+
let _opentelemetry_api = require("@opentelemetry/api");
|
|
6
|
+
let _opentelemetry_api_logs = require("@opentelemetry/api-logs");
|
|
7
|
+
//#region src/bridge.ts
|
|
8
|
+
/**
|
|
9
|
+
* OpenTelemetry Bridge implementation
|
|
10
|
+
*
|
|
11
|
+
* Creates real OTEL spans when Mastra spans are created, maintaining proper
|
|
12
|
+
* context propagation for nested instrumentation.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { OtelBridge } from '@mastra/otel-bridge';
|
|
17
|
+
* import { Mastra } from '@mastra/core';
|
|
18
|
+
*
|
|
19
|
+
* const mastra = new Mastra({
|
|
20
|
+
* agents: { myAgent },
|
|
21
|
+
* observability: {
|
|
22
|
+
* configs: {
|
|
23
|
+
* default: {
|
|
24
|
+
* serviceName: 'my-service',
|
|
25
|
+
* bridge: new OtelBridge(),
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
var OtelBridge = class extends _mastra_observability.BaseExporter {
|
|
33
|
+
name = "otel";
|
|
34
|
+
tracerProvider;
|
|
35
|
+
loggerProvider;
|
|
36
|
+
otelTracer;
|
|
37
|
+
otelLogger;
|
|
38
|
+
otelSpanMap = /* @__PURE__ */ new Map();
|
|
39
|
+
spanConverter;
|
|
40
|
+
constructor(config = {}) {
|
|
41
|
+
super(config);
|
|
42
|
+
this.tracerProvider = config.tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
|
|
43
|
+
this.otelTracer = this.tracerProvider.getTracer("@mastra/otel-bridge", "1.0.0");
|
|
44
|
+
this.loggerProvider = config.loggerProvider ?? _opentelemetry_api_logs.logs.getLoggerProvider();
|
|
45
|
+
this.otelLogger = this.loggerProvider.getLogger("@mastra/otel-bridge", "1.0.0");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Handle Mastra tracing events
|
|
49
|
+
*
|
|
50
|
+
* Ships OTEL spans when Mastra spans end.
|
|
51
|
+
* This maintains proper span hierarchy and allows OTEL-instrumented code within
|
|
52
|
+
* Mastra spans to have correct parent-child relationships.
|
|
53
|
+
* Note: OTEL spans are created when registerSpan is called when the span is first created.
|
|
54
|
+
*/
|
|
55
|
+
async _exportTracingEvent(event) {
|
|
56
|
+
if (event.type === _mastra_core_observability.TracingEventType.SPAN_ENDED) await this.handleSpanEnded(event);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Forward Mastra log events into the globally-registered OTEL LoggerProvider.
|
|
60
|
+
*
|
|
61
|
+
* If the user has not registered a LoggerProvider (e.g. via @opentelemetry/sdk-logs
|
|
62
|
+
* or NodeSDK's logRecordProcessor option), the API returns a no-op logger and
|
|
63
|
+
* emit() is a silent no-op — the bridge degrades gracefully.
|
|
64
|
+
*
|
|
65
|
+
* Trace correlation:
|
|
66
|
+
* - If the log carries a spanId we have an OTEL span for, emit under that span's
|
|
67
|
+
* stored context so the log nests beneath it in the trace.
|
|
68
|
+
* - Else if the log carries traceId+spanId, attach a SpanContext built from those
|
|
69
|
+
* IDs so backends still correlate by ID.
|
|
70
|
+
* - Else emit under whatever context is currently active.
|
|
71
|
+
*/
|
|
72
|
+
async onLogEvent(event) {
|
|
73
|
+
if (this.isDisabled) return;
|
|
74
|
+
try {
|
|
75
|
+
const params = (0, _mastra_otel_exporter.convertLog)(event.log);
|
|
76
|
+
const attributes = { ...params.attributes };
|
|
77
|
+
if (params.traceId) attributes["mastra.traceId"] = params.traceId;
|
|
78
|
+
if (params.spanId) attributes["mastra.spanId"] = params.spanId;
|
|
79
|
+
const logContext = this.resolveLogContext(params.traceId, params.spanId);
|
|
80
|
+
this.otelLogger.emit({
|
|
81
|
+
timestamp: params.timestamp,
|
|
82
|
+
severityNumber: params.severityNumber,
|
|
83
|
+
severityText: params.severityText,
|
|
84
|
+
body: params.body,
|
|
85
|
+
attributes,
|
|
86
|
+
context: logContext
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
this.logger.error("[OtelBridge] Failed to emit log:", error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Pick the OTEL Context to emit a log under so trace correlation is correct.
|
|
94
|
+
*/
|
|
95
|
+
resolveLogContext(traceId, spanId) {
|
|
96
|
+
if (spanId) {
|
|
97
|
+
const entry = this.otelSpanMap.get(spanId);
|
|
98
|
+
if (entry) return entry.otelContext;
|
|
99
|
+
}
|
|
100
|
+
if (traceId && spanId) {
|
|
101
|
+
const candidate = {
|
|
102
|
+
traceId,
|
|
103
|
+
spanId,
|
|
104
|
+
traceFlags: _opentelemetry_api.TraceFlags.SAMPLED,
|
|
105
|
+
isRemote: false
|
|
106
|
+
};
|
|
107
|
+
if ((0, _opentelemetry_api.isSpanContextValid)(candidate)) return _opentelemetry_api.trace.setSpanContext(_opentelemetry_api.context.active(), candidate);
|
|
108
|
+
}
|
|
109
|
+
return _opentelemetry_api.context.active();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Initialize with tracing configuration
|
|
113
|
+
*/
|
|
114
|
+
init(options) {
|
|
115
|
+
this.spanConverter = new _mastra_otel_exporter.SpanConverter({
|
|
116
|
+
packageName: "@mastra/otel-bridge",
|
|
117
|
+
serviceName: options.config?.serviceName,
|
|
118
|
+
format: "GenAI_v1_38_0"
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create a span in the bridge's tracing system.
|
|
123
|
+
* Called during Mastra span construction to get bridge-generated identifiers.
|
|
124
|
+
*
|
|
125
|
+
* @param options - Span creation options from Mastra
|
|
126
|
+
* @returns Span identifiers (spanId, traceId, parentSpanId) from bridge, or undefined if creation fails
|
|
127
|
+
*/
|
|
128
|
+
createSpan(options) {
|
|
129
|
+
try {
|
|
130
|
+
let parentOtelContext = _opentelemetry_api.context.active();
|
|
131
|
+
const externalParentId = (0, _mastra_observability.getExternalParentId)(options);
|
|
132
|
+
if (externalParentId) {
|
|
133
|
+
const parentEntry = this.otelSpanMap.get(externalParentId);
|
|
134
|
+
if (parentEntry) parentOtelContext = parentEntry.otelContext;
|
|
135
|
+
}
|
|
136
|
+
const otelSpan = this.otelTracer.startSpan(options.name, { kind: (0, _mastra_otel_exporter.getSpanKind)(options.type) }, parentOtelContext);
|
|
137
|
+
const spanContext = _opentelemetry_api.trace.setSpan(parentOtelContext, otelSpan);
|
|
138
|
+
const otelSpanContext = otelSpan.spanContext();
|
|
139
|
+
if (!(0, _opentelemetry_api.isSpanContextValid)(otelSpanContext)) {
|
|
140
|
+
otelSpan.end();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const spanId = otelSpanContext.spanId;
|
|
144
|
+
const traceId = otelSpanContext.traceId;
|
|
145
|
+
this.otelSpanMap.set(spanId, {
|
|
146
|
+
otelSpan,
|
|
147
|
+
otelContext: spanContext
|
|
148
|
+
});
|
|
149
|
+
const parentSpanContext = _opentelemetry_api.trace.getSpan(parentOtelContext)?.spanContext();
|
|
150
|
+
const parentSpanId = parentSpanContext && (0, _opentelemetry_api.isSpanContextValid)(parentSpanContext) ? parentSpanContext.spanId : void 0;
|
|
151
|
+
this.logger.debug(`[OtelBridge.createSpan] Created span [spanId=${spanId}] [traceId=${traceId}] [parentSpanId=${parentSpanId}] [type=${options.type}] [mapSize=${this.otelSpanMap.size}]`);
|
|
152
|
+
return {
|
|
153
|
+
spanId,
|
|
154
|
+
traceId,
|
|
155
|
+
parentSpanId
|
|
156
|
+
};
|
|
157
|
+
} catch (error) {
|
|
158
|
+
this.logger.error("[OtelBridge] Failed to create span:", error);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Handle SPAN_ENDED event
|
|
164
|
+
*
|
|
165
|
+
* Retrieves the OTEL span created at SPAN_STARTED, sets all final attributes,
|
|
166
|
+
* events, and status, then ends the span. Cleans up the span map entry.
|
|
167
|
+
*/
|
|
168
|
+
async handleSpanEnded(event) {
|
|
169
|
+
try {
|
|
170
|
+
const mastraSpan = event.exportedSpan;
|
|
171
|
+
const entry = this.otelSpanMap.get(mastraSpan.id);
|
|
172
|
+
if (!entry) {
|
|
173
|
+
this.logger.warn(`[OtelBridge] No OTEL span found for Mastra span [id=${mastraSpan.id}].`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.otelSpanMap.delete(mastraSpan.id);
|
|
177
|
+
if (!this.spanConverter) return;
|
|
178
|
+
const { otelSpan } = entry;
|
|
179
|
+
this.logger.debug(`[OtelBridge] Ending OTEL span [mastraId=${mastraSpan.id}] [name=${mastraSpan.name}]`);
|
|
180
|
+
const readableSpan = await this.spanConverter.convertSpan(mastraSpan);
|
|
181
|
+
otelSpan.updateName(readableSpan.name);
|
|
182
|
+
for (const [key, value] of Object.entries(readableSpan.attributes)) if (value !== void 0 && value !== null && typeof value !== "object") otelSpan.setAttribute(key, value);
|
|
183
|
+
otelSpan.setStatus(readableSpan.status);
|
|
184
|
+
for (const event of readableSpan.events) if (event.name === "exception" && event.attributes) {
|
|
185
|
+
const error = new Error(event.attributes["exception.message"]);
|
|
186
|
+
otelSpan.recordException(error);
|
|
187
|
+
}
|
|
188
|
+
otelSpan.end(mastraSpan.endTime);
|
|
189
|
+
this.logger.debug(`[OtelBridge] Completed OTEL span [mastraId=${mastraSpan.id}] [traceId=${otelSpan.spanContext().traceId}]`);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
this.logger.error("[OtelBridge] Failed to handle SPAN_ENDED:", error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Execute a function (sync or async) within the OTEL context of a Mastra span.
|
|
196
|
+
* Retrieves the stored OTEL context for the span and executes the function within it.
|
|
197
|
+
*
|
|
198
|
+
* This is the core implementation used by both executeInContext and executeInContextSync.
|
|
199
|
+
*
|
|
200
|
+
* @param spanId - The ID of the Mastra span to use as context
|
|
201
|
+
* @param fn - The function to execute within the span context
|
|
202
|
+
* @returns The result of the function execution
|
|
203
|
+
*/
|
|
204
|
+
executeWithSpanContext(spanId, fn) {
|
|
205
|
+
const entry = this.otelSpanMap.get(spanId);
|
|
206
|
+
this.logger.debug(`[OtelBridge.executeWithSpanContext] spanId=${spanId}, inMap=${!!entry}, storedOtelSpan=${entry?.otelSpan.spanContext().spanId || "none"}`);
|
|
207
|
+
const spanContext = entry?.otelContext;
|
|
208
|
+
if (spanContext) return _opentelemetry_api.context.with(spanContext, fn);
|
|
209
|
+
return fn();
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Execute an async function within the OTEL context of a Mastra span.
|
|
213
|
+
*
|
|
214
|
+
* @param spanId - The ID of the Mastra span to use as context
|
|
215
|
+
* @param fn - The async function to execute within the span context
|
|
216
|
+
* @returns The result of the function execution
|
|
217
|
+
*/
|
|
218
|
+
executeInContext(spanId, fn) {
|
|
219
|
+
return this.executeWithSpanContext(spanId, fn);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Execute a synchronous function within the OTEL context of a Mastra span.
|
|
223
|
+
*
|
|
224
|
+
* @param spanId - The ID of the Mastra span to use as context
|
|
225
|
+
* @param fn - The synchronous function to execute within the span context
|
|
226
|
+
* @returns The result of the function execution
|
|
227
|
+
*/
|
|
228
|
+
executeInContextSync(spanId, fn) {
|
|
229
|
+
return this.executeWithSpanContext(spanId, fn);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Force flush any buffered spans without shutting down the bridge.
|
|
233
|
+
*
|
|
234
|
+
* Attempts to flush the underlying OTEL tracer provider if it supports
|
|
235
|
+
* the forceFlush operation. This is useful in serverless environments
|
|
236
|
+
* where you need to ensure all spans are exported before the runtime
|
|
237
|
+
* instance is terminated.
|
|
238
|
+
*/
|
|
239
|
+
async flush() {
|
|
240
|
+
await this.flushProvider(this.tracerProvider, "tracer");
|
|
241
|
+
await this.flushProvider(this.loggerProvider, "logger");
|
|
242
|
+
}
|
|
243
|
+
async flushProvider(provider, label) {
|
|
244
|
+
try {
|
|
245
|
+
if (provider && typeof provider === "object" && "forceFlush" in provider && typeof provider.forceFlush === "function") {
|
|
246
|
+
await provider.forceFlush();
|
|
247
|
+
this.logger.debug(`[OtelBridge] Flushed ${label} provider`);
|
|
248
|
+
} else this.logger.debug(`[OtelBridge] ${label === "tracer" ? "Tracer" : "Logger"} provider does not support forceFlush`);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
this.logger.error(`[OtelBridge] Failed to flush ${label} provider:`, error);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Shutdown the bridge and clean up resources
|
|
255
|
+
*/
|
|
256
|
+
async shutdown() {
|
|
257
|
+
await this.flush();
|
|
258
|
+
for (const [spanId, { otelSpan }] of this.otelSpanMap.entries()) {
|
|
259
|
+
this.logger.warn(`[OtelBridge] Force-ending span that was not properly closed [id=${spanId}]`);
|
|
260
|
+
otelSpan.end();
|
|
261
|
+
}
|
|
262
|
+
this.otelSpanMap.clear();
|
|
263
|
+
this.logger.info("[OtelBridge] Shutdown complete");
|
|
264
|
+
}
|
|
269
265
|
};
|
|
270
|
-
|
|
266
|
+
//#endregion
|
|
271
267
|
exports.OtelBridge = OtelBridge;
|
|
272
|
-
|
|
268
|
+
|
|
273
269
|
//# sourceMappingURL=index.cjs.map
|