@mastra/observability 1.7.3 → 1.8.0-alpha.1
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 +71 -0
- package/dist/bus/observability-bus.d.ts +6 -2
- package/dist/bus/observability-bus.d.ts.map +1 -1
- package/dist/config.d.ts +65 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/exporters/cloud.d.ts +23 -2
- package/dist/exporters/cloud.d.ts.map +1 -1
- package/dist/exporters/test.d.ts.map +1 -1
- package/dist/index.cjs +792 -339
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +792 -341
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/spans/serialization.d.ts +8 -0
- package/dist/spans/serialization.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -13855,17 +13855,36 @@ var serializationOptionsSchema = external_exports.object({
|
|
|
13855
13855
|
maxArrayLength: external_exports.number().int().positive().optional(),
|
|
13856
13856
|
maxObjectKeys: external_exports.number().int().positive().optional()
|
|
13857
13857
|
}).optional();
|
|
13858
|
-
var
|
|
13859
|
-
|
|
13858
|
+
var LOG_LEVELS = ["debug", "info", "warn", "error", "fatal"];
|
|
13859
|
+
var cardinalityConfigSchema = external_exports.object({
|
|
13860
|
+
blockedLabels: external_exports.array(external_exports.string()).optional(),
|
|
13861
|
+
blockUUIDs: external_exports.boolean().optional()
|
|
13862
|
+
}).optional();
|
|
13863
|
+
var loggingConfigSchema = external_exports.object({
|
|
13864
|
+
enabled: external_exports.boolean().optional(),
|
|
13865
|
+
level: external_exports.enum(LOG_LEVELS).optional()
|
|
13866
|
+
}).optional();
|
|
13867
|
+
var spanFilterSchema = external_exports.function({
|
|
13868
|
+
input: external_exports.tuple([external_exports.any()]),
|
|
13869
|
+
output: external_exports.boolean()
|
|
13870
|
+
}).optional();
|
|
13871
|
+
var observabilityInstanceConfigFields = {
|
|
13860
13872
|
serviceName: external_exports.string().min(1, "Service name is required"),
|
|
13861
13873
|
sampling: samplingStrategySchema.optional(),
|
|
13862
13874
|
exporters: external_exports.array(external_exports.any()).optional(),
|
|
13863
13875
|
bridge: external_exports.any().optional(),
|
|
13864
13876
|
spanOutputProcessors: external_exports.array(external_exports.any()).optional(),
|
|
13865
13877
|
includeInternalSpans: external_exports.boolean().optional(),
|
|
13878
|
+
excludeSpanTypes: external_exports.array(external_exports.nativeEnum(observability.SpanType)).optional(),
|
|
13879
|
+
spanFilter: spanFilterSchema,
|
|
13866
13880
|
requestContextKeys: external_exports.array(external_exports.string()).optional(),
|
|
13867
13881
|
serializationOptions: serializationOptionsSchema,
|
|
13868
|
-
cardinality:
|
|
13882
|
+
cardinality: cardinalityConfigSchema,
|
|
13883
|
+
logging: loggingConfigSchema
|
|
13884
|
+
};
|
|
13885
|
+
var observabilityInstanceConfigSchema = external_exports.object({
|
|
13886
|
+
name: external_exports.string().min(1, "Name is required"),
|
|
13887
|
+
...observabilityInstanceConfigFields
|
|
13869
13888
|
}).refine(
|
|
13870
13889
|
(data) => {
|
|
13871
13890
|
const hasExporters = data.exporters && data.exporters.length > 0;
|
|
@@ -13876,16 +13895,7 @@ var observabilityInstanceConfigSchema = external_exports.object({
|
|
|
13876
13895
|
message: "At least one exporter or a bridge is required"
|
|
13877
13896
|
}
|
|
13878
13897
|
);
|
|
13879
|
-
var observabilityConfigValueSchema = external_exports.object(
|
|
13880
|
-
serviceName: external_exports.string().min(1, "Service name is required"),
|
|
13881
|
-
sampling: samplingStrategySchema.optional(),
|
|
13882
|
-
exporters: external_exports.array(external_exports.any()).optional(),
|
|
13883
|
-
bridge: external_exports.any().optional(),
|
|
13884
|
-
spanOutputProcessors: external_exports.array(external_exports.any()).optional(),
|
|
13885
|
-
includeInternalSpans: external_exports.boolean().optional(),
|
|
13886
|
-
requestContextKeys: external_exports.array(external_exports.string()).optional(),
|
|
13887
|
-
serializationOptions: serializationOptionsSchema
|
|
13888
|
-
}).refine(
|
|
13898
|
+
var observabilityConfigValueSchema = external_exports.object(observabilityInstanceConfigFields).refine(
|
|
13889
13899
|
(data) => {
|
|
13890
13900
|
const hasExporters = data.exporters && data.exporters.length > 0;
|
|
13891
13901
|
const hasBridge = !!data.bridge;
|
|
@@ -15034,18 +15044,144 @@ function chainFormatters(formatters) {
|
|
|
15034
15044
|
return currentSpan;
|
|
15035
15045
|
};
|
|
15036
15046
|
}
|
|
15047
|
+
var SIGNAL_PUBLISH_SUFFIXES = {
|
|
15048
|
+
traces: "/spans/publish",
|
|
15049
|
+
logs: "/logs/publish",
|
|
15050
|
+
metrics: "/metrics/publish",
|
|
15051
|
+
scores: "/scores/publish",
|
|
15052
|
+
feedback: "/feedback/publish"
|
|
15053
|
+
};
|
|
15054
|
+
var SIGNAL_PUBLISH_PATHS = {
|
|
15055
|
+
traces: "/ai/spans/publish",
|
|
15056
|
+
logs: "/ai/logs/publish",
|
|
15057
|
+
metrics: "/ai/metrics/publish",
|
|
15058
|
+
scores: "/ai/scores/publish",
|
|
15059
|
+
feedback: "/ai/feedback/publish"
|
|
15060
|
+
};
|
|
15061
|
+
var SIGNAL_PAYLOAD_KEYS = {
|
|
15062
|
+
traces: "spans",
|
|
15063
|
+
logs: "logs",
|
|
15064
|
+
metrics: "metrics",
|
|
15065
|
+
scores: "scores",
|
|
15066
|
+
feedback: "feedback"
|
|
15067
|
+
};
|
|
15068
|
+
var DEFAULT_CLOUD_ENDPOINT = "https://api.mastra.ai";
|
|
15069
|
+
function trimTrailingSlashes(value) {
|
|
15070
|
+
let end = value.length;
|
|
15071
|
+
while (end > 0 && value.charCodeAt(end - 1) === 47) {
|
|
15072
|
+
end--;
|
|
15073
|
+
}
|
|
15074
|
+
return end === value.length ? value : value.slice(0, end);
|
|
15075
|
+
}
|
|
15076
|
+
function createInvalidEndpointError(endpoint, text, cause) {
|
|
15077
|
+
return new error$1.MastraError(
|
|
15078
|
+
{
|
|
15079
|
+
id: `CLOUD_EXPORTER_INVALID_ENDPOINT`,
|
|
15080
|
+
text,
|
|
15081
|
+
domain: error$1.ErrorDomain.MASTRA_OBSERVABILITY,
|
|
15082
|
+
category: error$1.ErrorCategory.USER,
|
|
15083
|
+
details: {
|
|
15084
|
+
endpoint
|
|
15085
|
+
}
|
|
15086
|
+
},
|
|
15087
|
+
cause
|
|
15088
|
+
);
|
|
15089
|
+
}
|
|
15090
|
+
function resolveBaseEndpoint(baseEndpoint) {
|
|
15091
|
+
const normalizedEndpoint = trimTrailingSlashes(baseEndpoint);
|
|
15092
|
+
const invalidText = 'CloudExporter endpoint must be a base origin like "https://collector.example.com" with no path, search, or hash.';
|
|
15093
|
+
try {
|
|
15094
|
+
const parsedEndpoint = new URL(normalizedEndpoint);
|
|
15095
|
+
if (parsedEndpoint.pathname !== "/" || parsedEndpoint.search || parsedEndpoint.hash) {
|
|
15096
|
+
throw createInvalidEndpointError(baseEndpoint, invalidText);
|
|
15097
|
+
}
|
|
15098
|
+
return trimTrailingSlashes(parsedEndpoint.origin);
|
|
15099
|
+
} catch (error48) {
|
|
15100
|
+
if (error48 instanceof error$1.MastraError) {
|
|
15101
|
+
throw error48;
|
|
15102
|
+
}
|
|
15103
|
+
throw createInvalidEndpointError(baseEndpoint, invalidText, error48);
|
|
15104
|
+
}
|
|
15105
|
+
}
|
|
15106
|
+
function buildSignalEndpoint(baseEndpoint, signal) {
|
|
15107
|
+
return `${baseEndpoint}${SIGNAL_PUBLISH_PATHS[signal]}`;
|
|
15108
|
+
}
|
|
15109
|
+
function resolveExplicitSignalEndpoint(signal, endpoint) {
|
|
15110
|
+
const normalizedEndpoint = trimTrailingSlashes(endpoint);
|
|
15111
|
+
const invalidText = `CloudExporter ${signal}Endpoint must be a base origin like "https://collector.example.com" or a full ${signal} publish URL ending in "${SIGNAL_PUBLISH_SUFFIXES[signal]}".`;
|
|
15112
|
+
try {
|
|
15113
|
+
const parsedEndpoint = new URL(normalizedEndpoint);
|
|
15114
|
+
if (parsedEndpoint.search || parsedEndpoint.hash) {
|
|
15115
|
+
throw createInvalidEndpointError(endpoint, invalidText);
|
|
15116
|
+
}
|
|
15117
|
+
const normalizedOrigin = trimTrailingSlashes(parsedEndpoint.origin);
|
|
15118
|
+
const normalizedPathname = trimTrailingSlashes(parsedEndpoint.pathname);
|
|
15119
|
+
if (!normalizedPathname || normalizedPathname === "/") {
|
|
15120
|
+
return buildSignalEndpoint(normalizedOrigin, signal);
|
|
15121
|
+
}
|
|
15122
|
+
if (normalizedPathname.endsWith(SIGNAL_PUBLISH_SUFFIXES[signal])) {
|
|
15123
|
+
return `${normalizedOrigin}${normalizedPathname}`;
|
|
15124
|
+
}
|
|
15125
|
+
throw createInvalidEndpointError(endpoint, invalidText);
|
|
15126
|
+
} catch (error48) {
|
|
15127
|
+
if (error48 instanceof error$1.MastraError) {
|
|
15128
|
+
throw error48;
|
|
15129
|
+
}
|
|
15130
|
+
throw createInvalidEndpointError(endpoint, invalidText, error48);
|
|
15131
|
+
}
|
|
15132
|
+
}
|
|
15133
|
+
function deriveSignalEndpointFromTracesEndpoint(signal, tracesEndpoint) {
|
|
15134
|
+
if (signal === "traces") {
|
|
15135
|
+
return tracesEndpoint;
|
|
15136
|
+
}
|
|
15137
|
+
const normalizedTracesEndpoint = trimTrailingSlashes(tracesEndpoint);
|
|
15138
|
+
const invalidText = 'CloudExporter tracesEndpoint must be a base origin like "https://collector.example.com" or a full traces publish URL ending in "/spans/publish".';
|
|
15139
|
+
try {
|
|
15140
|
+
const parsedEndpoint = new URL(normalizedTracesEndpoint);
|
|
15141
|
+
const normalizedOrigin = trimTrailingSlashes(parsedEndpoint.origin);
|
|
15142
|
+
const normalizedPathname = trimTrailingSlashes(parsedEndpoint.pathname);
|
|
15143
|
+
if (!normalizedPathname.endsWith(SIGNAL_PUBLISH_SUFFIXES.traces)) {
|
|
15144
|
+
throw createInvalidEndpointError(tracesEndpoint, invalidText);
|
|
15145
|
+
}
|
|
15146
|
+
const basePath = normalizedPathname.slice(0, -SIGNAL_PUBLISH_SUFFIXES.traces.length);
|
|
15147
|
+
return `${normalizedOrigin}${basePath}${SIGNAL_PUBLISH_SUFFIXES[signal]}`;
|
|
15148
|
+
} catch (error48) {
|
|
15149
|
+
if (error48 instanceof error$1.MastraError) {
|
|
15150
|
+
throw error48;
|
|
15151
|
+
}
|
|
15152
|
+
throw createInvalidEndpointError(tracesEndpoint, invalidText, error48);
|
|
15153
|
+
}
|
|
15154
|
+
}
|
|
15037
15155
|
var CloudExporter = class extends BaseExporter {
|
|
15038
15156
|
name = "mastra-cloud-observability-exporter";
|
|
15039
15157
|
cloudConfig;
|
|
15040
15158
|
buffer;
|
|
15041
15159
|
flushTimer = null;
|
|
15160
|
+
inFlightFlushes = /* @__PURE__ */ new Set();
|
|
15042
15161
|
constructor(config2 = {}) {
|
|
15043
15162
|
super(config2);
|
|
15044
15163
|
const accessToken = config2.accessToken ?? process.env.MASTRA_CLOUD_ACCESS_TOKEN;
|
|
15045
15164
|
if (!accessToken) {
|
|
15046
15165
|
this.setDisabled("MASTRA_CLOUD_ACCESS_TOKEN environment variable not set.");
|
|
15047
15166
|
}
|
|
15048
|
-
const
|
|
15167
|
+
const tracesEndpointOverride = config2.tracesEndpoint ?? process.env.MASTRA_CLOUD_TRACES_ENDPOINT;
|
|
15168
|
+
let baseEndpoint;
|
|
15169
|
+
let tracesEndpoint;
|
|
15170
|
+
if (tracesEndpointOverride) {
|
|
15171
|
+
tracesEndpoint = resolveExplicitSignalEndpoint("traces", tracesEndpointOverride);
|
|
15172
|
+
} else {
|
|
15173
|
+
baseEndpoint = resolveBaseEndpoint(config2.endpoint ?? DEFAULT_CLOUD_ENDPOINT);
|
|
15174
|
+
tracesEndpoint = buildSignalEndpoint(baseEndpoint, "traces");
|
|
15175
|
+
}
|
|
15176
|
+
const resolveConfiguredSignalEndpoint = (signal, explicitEndpoint) => {
|
|
15177
|
+
if (explicitEndpoint) {
|
|
15178
|
+
return resolveExplicitSignalEndpoint(signal, explicitEndpoint);
|
|
15179
|
+
}
|
|
15180
|
+
if (tracesEndpointOverride) {
|
|
15181
|
+
return deriveSignalEndpointFromTracesEndpoint(signal, tracesEndpoint);
|
|
15182
|
+
}
|
|
15183
|
+
return buildSignalEndpoint(baseEndpoint, signal);
|
|
15184
|
+
};
|
|
15049
15185
|
this.cloudConfig = {
|
|
15050
15186
|
logger: this.logger,
|
|
15051
15187
|
logLevel: config2.logLevel ?? logger.LogLevel.INFO,
|
|
@@ -15053,10 +15189,18 @@ var CloudExporter = class extends BaseExporter {
|
|
|
15053
15189
|
maxBatchWaitMs: config2.maxBatchWaitMs ?? 5e3,
|
|
15054
15190
|
maxRetries: config2.maxRetries ?? 3,
|
|
15055
15191
|
accessToken: accessToken || "",
|
|
15056
|
-
|
|
15192
|
+
tracesEndpoint,
|
|
15193
|
+
logsEndpoint: resolveConfiguredSignalEndpoint("logs", config2.logsEndpoint),
|
|
15194
|
+
metricsEndpoint: resolveConfiguredSignalEndpoint("metrics", config2.metricsEndpoint),
|
|
15195
|
+
scoresEndpoint: resolveConfiguredSignalEndpoint("scores", config2.scoresEndpoint),
|
|
15196
|
+
feedbackEndpoint: resolveConfiguredSignalEndpoint("feedback", config2.feedbackEndpoint)
|
|
15057
15197
|
};
|
|
15058
15198
|
this.buffer = {
|
|
15059
15199
|
spans: [],
|
|
15200
|
+
logs: [],
|
|
15201
|
+
metrics: [],
|
|
15202
|
+
scores: [],
|
|
15203
|
+
feedback: [],
|
|
15060
15204
|
totalSize: 0
|
|
15061
15205
|
};
|
|
15062
15206
|
}
|
|
@@ -15065,45 +15209,111 @@ var CloudExporter = class extends BaseExporter {
|
|
|
15065
15209
|
return;
|
|
15066
15210
|
}
|
|
15067
15211
|
this.addToBuffer(event);
|
|
15068
|
-
|
|
15069
|
-
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15073
|
-
});
|
|
15074
|
-
} else if (this.buffer.totalSize === 1) {
|
|
15075
|
-
this.scheduleFlush();
|
|
15212
|
+
await this.handleBufferedEvent();
|
|
15213
|
+
}
|
|
15214
|
+
async onLogEvent(event) {
|
|
15215
|
+
if (this.isDisabled) {
|
|
15216
|
+
return;
|
|
15076
15217
|
}
|
|
15218
|
+
this.addLogToBuffer(event);
|
|
15219
|
+
await this.handleBufferedEvent();
|
|
15077
15220
|
}
|
|
15078
|
-
|
|
15079
|
-
if (this.
|
|
15080
|
-
|
|
15221
|
+
async onMetricEvent(event) {
|
|
15222
|
+
if (this.isDisabled) {
|
|
15223
|
+
return;
|
|
15224
|
+
}
|
|
15225
|
+
this.addMetricToBuffer(event);
|
|
15226
|
+
await this.handleBufferedEvent();
|
|
15227
|
+
}
|
|
15228
|
+
async onScoreEvent(event) {
|
|
15229
|
+
if (this.isDisabled) {
|
|
15230
|
+
return;
|
|
15231
|
+
}
|
|
15232
|
+
this.addScoreToBuffer(event);
|
|
15233
|
+
await this.handleBufferedEvent();
|
|
15234
|
+
}
|
|
15235
|
+
async onFeedbackEvent(event) {
|
|
15236
|
+
if (this.isDisabled) {
|
|
15237
|
+
return;
|
|
15081
15238
|
}
|
|
15239
|
+
this.addFeedbackToBuffer(event);
|
|
15240
|
+
await this.handleBufferedEvent();
|
|
15241
|
+
}
|
|
15242
|
+
addToBuffer(event) {
|
|
15243
|
+
this.markBufferStart();
|
|
15082
15244
|
const spanRecord = this.formatSpan(event.exportedSpan);
|
|
15083
15245
|
this.buffer.spans.push(spanRecord);
|
|
15084
15246
|
this.buffer.totalSize++;
|
|
15085
15247
|
}
|
|
15248
|
+
addLogToBuffer(event) {
|
|
15249
|
+
this.markBufferStart();
|
|
15250
|
+
this.buffer.logs.push(this.formatLog(event.log));
|
|
15251
|
+
this.buffer.totalSize++;
|
|
15252
|
+
}
|
|
15253
|
+
addMetricToBuffer(event) {
|
|
15254
|
+
this.markBufferStart();
|
|
15255
|
+
this.buffer.metrics.push(this.formatMetric(event.metric));
|
|
15256
|
+
this.buffer.totalSize++;
|
|
15257
|
+
}
|
|
15258
|
+
addScoreToBuffer(event) {
|
|
15259
|
+
this.markBufferStart();
|
|
15260
|
+
this.buffer.scores.push(this.formatScore(event.score));
|
|
15261
|
+
this.buffer.totalSize++;
|
|
15262
|
+
}
|
|
15263
|
+
addFeedbackToBuffer(event) {
|
|
15264
|
+
this.markBufferStart();
|
|
15265
|
+
this.buffer.feedback.push(this.formatFeedback(event.feedback));
|
|
15266
|
+
this.buffer.totalSize++;
|
|
15267
|
+
}
|
|
15268
|
+
markBufferStart() {
|
|
15269
|
+
if (this.buffer.totalSize === 0) {
|
|
15270
|
+
this.buffer.firstEventTime = /* @__PURE__ */ new Date();
|
|
15271
|
+
}
|
|
15272
|
+
}
|
|
15086
15273
|
formatSpan(span) {
|
|
15087
15274
|
const spanRecord = {
|
|
15088
|
-
|
|
15275
|
+
...span,
|
|
15089
15276
|
spanId: span.id,
|
|
15090
|
-
parentSpanId: span.parentSpanId ?? null,
|
|
15091
|
-
name: span.name,
|
|
15092
15277
|
spanType: span.type,
|
|
15093
|
-
attributes: span.attributes ?? null,
|
|
15094
|
-
metadata: span.metadata ?? null,
|
|
15095
|
-
requestContext: span.requestContext ?? null,
|
|
15096
15278
|
startedAt: span.startTime,
|
|
15097
15279
|
endedAt: span.endTime ?? null,
|
|
15098
|
-
|
|
15099
|
-
output: span.output ?? null,
|
|
15100
|
-
error: span.errorInfo,
|
|
15101
|
-
isEvent: span.isEvent,
|
|
15280
|
+
error: span.errorInfo ?? null,
|
|
15102
15281
|
createdAt: /* @__PURE__ */ new Date(),
|
|
15103
15282
|
updatedAt: null
|
|
15104
15283
|
};
|
|
15105
15284
|
return spanRecord;
|
|
15106
15285
|
}
|
|
15286
|
+
formatLog(log) {
|
|
15287
|
+
return {
|
|
15288
|
+
...log
|
|
15289
|
+
};
|
|
15290
|
+
}
|
|
15291
|
+
formatMetric(metric) {
|
|
15292
|
+
return {
|
|
15293
|
+
...metric
|
|
15294
|
+
};
|
|
15295
|
+
}
|
|
15296
|
+
formatScore(score) {
|
|
15297
|
+
return {
|
|
15298
|
+
...score
|
|
15299
|
+
};
|
|
15300
|
+
}
|
|
15301
|
+
formatFeedback(feedback) {
|
|
15302
|
+
return {
|
|
15303
|
+
...feedback
|
|
15304
|
+
};
|
|
15305
|
+
}
|
|
15306
|
+
async handleBufferedEvent() {
|
|
15307
|
+
if (this.shouldFlush()) {
|
|
15308
|
+
void this.flush().catch((error48) => {
|
|
15309
|
+
this.logger.error("Batch flush failed", {
|
|
15310
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
15311
|
+
});
|
|
15312
|
+
});
|
|
15313
|
+
} else if (this.buffer.totalSize === 1) {
|
|
15314
|
+
this.scheduleFlush();
|
|
15315
|
+
}
|
|
15316
|
+
}
|
|
15107
15317
|
shouldFlush() {
|
|
15108
15318
|
if (this.buffer.totalSize >= this.cloudConfig.maxBatchSize) {
|
|
15109
15319
|
return true;
|
|
@@ -15121,7 +15331,7 @@ var CloudExporter = class extends BaseExporter {
|
|
|
15121
15331
|
clearTimeout(this.flushTimer);
|
|
15122
15332
|
}
|
|
15123
15333
|
this.flushTimer = setTimeout(() => {
|
|
15124
|
-
this.flush().catch((error48) => {
|
|
15334
|
+
void this.flush().catch((error48) => {
|
|
15125
15335
|
const mastraError = new error$1.MastraError(
|
|
15126
15336
|
{
|
|
15127
15337
|
id: `CLOUD_EXPORTER_FAILED_TO_SCHEDULE_FLUSH`,
|
|
@@ -15145,49 +15355,91 @@ var CloudExporter = class extends BaseExporter {
|
|
|
15145
15355
|
}
|
|
15146
15356
|
const startTime = Date.now();
|
|
15147
15357
|
const spansCopy = [...this.buffer.spans];
|
|
15358
|
+
const logsCopy = [...this.buffer.logs];
|
|
15359
|
+
const metricsCopy = [...this.buffer.metrics];
|
|
15360
|
+
const scoresCopy = [...this.buffer.scores];
|
|
15361
|
+
const feedbackCopy = [...this.buffer.feedback];
|
|
15362
|
+
const batchSize = this.buffer.totalSize;
|
|
15148
15363
|
const flushReason = this.buffer.totalSize >= this.cloudConfig.maxBatchSize ? "size" : "time";
|
|
15149
15364
|
this.resetBuffer();
|
|
15150
|
-
|
|
15151
|
-
|
|
15152
|
-
|
|
15365
|
+
const results = await Promise.all([
|
|
15366
|
+
this.flushSignalBatch("traces", spansCopy),
|
|
15367
|
+
this.flushSignalBatch("logs", logsCopy),
|
|
15368
|
+
this.flushSignalBatch("metrics", metricsCopy),
|
|
15369
|
+
this.flushSignalBatch("scores", scoresCopy),
|
|
15370
|
+
this.flushSignalBatch("feedback", feedbackCopy)
|
|
15371
|
+
]);
|
|
15372
|
+
const failedSignals = results.filter((result) => !result.succeeded).map((result) => result.signal);
|
|
15373
|
+
const elapsed = Date.now() - startTime;
|
|
15374
|
+
if (failedSignals.length === 0) {
|
|
15153
15375
|
this.logger.debug("Batch flushed successfully", {
|
|
15154
|
-
batchSize
|
|
15376
|
+
batchSize,
|
|
15155
15377
|
flushReason,
|
|
15156
15378
|
durationMs: elapsed
|
|
15157
15379
|
});
|
|
15380
|
+
return;
|
|
15381
|
+
}
|
|
15382
|
+
this.logger.warn("Batch flush completed with dropped signal batches", {
|
|
15383
|
+
batchSize,
|
|
15384
|
+
flushReason,
|
|
15385
|
+
durationMs: elapsed,
|
|
15386
|
+
failedSignals
|
|
15387
|
+
});
|
|
15388
|
+
}
|
|
15389
|
+
/**
|
|
15390
|
+
* Uploads a signal batch to the configured cloud API using fetchWithRetry.
|
|
15391
|
+
*/
|
|
15392
|
+
async batchUpload(signal, records) {
|
|
15393
|
+
const headers = {
|
|
15394
|
+
Authorization: `Bearer ${this.cloudConfig.accessToken}`,
|
|
15395
|
+
"Content-Type": "application/json"
|
|
15396
|
+
};
|
|
15397
|
+
const endpointMap = {
|
|
15398
|
+
traces: this.cloudConfig.tracesEndpoint,
|
|
15399
|
+
logs: this.cloudConfig.logsEndpoint,
|
|
15400
|
+
metrics: this.cloudConfig.metricsEndpoint,
|
|
15401
|
+
scores: this.cloudConfig.scoresEndpoint,
|
|
15402
|
+
feedback: this.cloudConfig.feedbackEndpoint
|
|
15403
|
+
};
|
|
15404
|
+
const options = {
|
|
15405
|
+
method: "POST",
|
|
15406
|
+
headers,
|
|
15407
|
+
body: JSON.stringify({ [SIGNAL_PAYLOAD_KEYS[signal]]: records })
|
|
15408
|
+
};
|
|
15409
|
+
await utils.fetchWithRetry(endpointMap[signal], options, this.cloudConfig.maxRetries);
|
|
15410
|
+
}
|
|
15411
|
+
async flushSignalBatch(signal, records) {
|
|
15412
|
+
if (records.length === 0) {
|
|
15413
|
+
return { signal, succeeded: true };
|
|
15414
|
+
}
|
|
15415
|
+
try {
|
|
15416
|
+
await this.batchUpload(signal, records);
|
|
15417
|
+
return { signal, succeeded: true };
|
|
15158
15418
|
} catch (error48) {
|
|
15419
|
+
const errorId = `CLOUD_EXPORTER_FAILED_TO_BATCH_UPLOAD_${signal.toUpperCase()}`;
|
|
15159
15420
|
const mastraError = new error$1.MastraError(
|
|
15160
15421
|
{
|
|
15161
|
-
id:
|
|
15422
|
+
id: errorId,
|
|
15162
15423
|
domain: error$1.ErrorDomain.MASTRA_OBSERVABILITY,
|
|
15163
15424
|
category: error$1.ErrorCategory.USER,
|
|
15164
15425
|
details: {
|
|
15165
|
-
|
|
15426
|
+
signal,
|
|
15427
|
+
droppedBatchSize: records.length
|
|
15166
15428
|
}
|
|
15167
15429
|
},
|
|
15168
15430
|
error48
|
|
15169
15431
|
);
|
|
15170
15432
|
this.logger.trackException(mastraError);
|
|
15171
15433
|
this.logger.error("Batch upload failed after all retries, dropping batch", mastraError);
|
|
15434
|
+
return { signal, succeeded: false };
|
|
15172
15435
|
}
|
|
15173
15436
|
}
|
|
15174
|
-
/**
|
|
15175
|
-
* Uploads spans to cloud API using fetchWithRetry for all retry logic
|
|
15176
|
-
*/
|
|
15177
|
-
async batchUpload(spans) {
|
|
15178
|
-
const headers = {
|
|
15179
|
-
Authorization: `Bearer ${this.cloudConfig.accessToken}`,
|
|
15180
|
-
"Content-Type": "application/json"
|
|
15181
|
-
};
|
|
15182
|
-
const options = {
|
|
15183
|
-
method: "POST",
|
|
15184
|
-
headers,
|
|
15185
|
-
body: JSON.stringify({ spans })
|
|
15186
|
-
};
|
|
15187
|
-
await utils.fetchWithRetry(this.cloudConfig.endpoint, options, this.cloudConfig.maxRetries);
|
|
15188
|
-
}
|
|
15189
15437
|
resetBuffer() {
|
|
15190
15438
|
this.buffer.spans = [];
|
|
15439
|
+
this.buffer.logs = [];
|
|
15440
|
+
this.buffer.metrics = [];
|
|
15441
|
+
this.buffer.scores = [];
|
|
15442
|
+
this.buffer.feedback = [];
|
|
15191
15443
|
this.buffer.firstEventTime = void 0;
|
|
15192
15444
|
this.buffer.totalSize = 0;
|
|
15193
15445
|
}
|
|
@@ -15200,11 +15452,21 @@ var CloudExporter = class extends BaseExporter {
|
|
|
15200
15452
|
if (this.isDisabled) {
|
|
15201
15453
|
return;
|
|
15202
15454
|
}
|
|
15203
|
-
|
|
15204
|
-
this.
|
|
15205
|
-
|
|
15206
|
-
|
|
15207
|
-
|
|
15455
|
+
while (this.buffer.totalSize > 0 || this.inFlightFlushes.size > 0) {
|
|
15456
|
+
if (this.buffer.totalSize > 0) {
|
|
15457
|
+
this.logger.debug("Flushing buffered events", {
|
|
15458
|
+
bufferedEvents: this.buffer.totalSize
|
|
15459
|
+
});
|
|
15460
|
+
const flushPromise = this.flushBuffer();
|
|
15461
|
+
this.inFlightFlushes.add(flushPromise);
|
|
15462
|
+
try {
|
|
15463
|
+
await flushPromise;
|
|
15464
|
+
} finally {
|
|
15465
|
+
this.inFlightFlushes.delete(flushPromise);
|
|
15466
|
+
}
|
|
15467
|
+
continue;
|
|
15468
|
+
}
|
|
15469
|
+
await Promise.allSettled([...this.inFlightFlushes]);
|
|
15208
15470
|
}
|
|
15209
15471
|
}
|
|
15210
15472
|
async shutdown() {
|
|
@@ -16442,6 +16704,9 @@ var TestExporter = class extends BaseExporter {
|
|
|
16442
16704
|
if (value instanceof Date) {
|
|
16443
16705
|
return "<date>";
|
|
16444
16706
|
}
|
|
16707
|
+
if (key === "createdAt" && typeof value === "number") {
|
|
16708
|
+
return "<date>";
|
|
16709
|
+
}
|
|
16445
16710
|
if (typeof value === "string") {
|
|
16446
16711
|
if (key === "traceId" && (uuidRegex.test(value) || hexId32Regex.test(value))) {
|
|
16447
16712
|
if (!traceIdMap.has(value)) {
|
|
@@ -16470,7 +16735,23 @@ var TestExporter = class extends BaseExporter {
|
|
|
16470
16735
|
if (value && typeof value === "object") {
|
|
16471
16736
|
const normalized = {};
|
|
16472
16737
|
for (const [k, v] of Object.entries(value)) {
|
|
16473
|
-
|
|
16738
|
+
if (key === "providerOptions" && k === "mastra" && v && typeof v === "object") {
|
|
16739
|
+
const mastraOptions = v;
|
|
16740
|
+
const remainingMastraOptions = Object.fromEntries(
|
|
16741
|
+
Object.entries(mastraOptions).filter(([mastraKey]) => mastraKey !== "createdAt")
|
|
16742
|
+
);
|
|
16743
|
+
if (Object.keys(remainingMastraOptions).length > 0) {
|
|
16744
|
+
normalized[k] = normalizeValue(remainingMastraOptions, k);
|
|
16745
|
+
}
|
|
16746
|
+
continue;
|
|
16747
|
+
}
|
|
16748
|
+
const normalizedValue = normalizeValue(v, k);
|
|
16749
|
+
if (normalizedValue !== void 0) {
|
|
16750
|
+
normalized[k] = normalizedValue;
|
|
16751
|
+
}
|
|
16752
|
+
}
|
|
16753
|
+
if (key === "providerOptions" && Object.keys(normalized).length === 0) {
|
|
16754
|
+
return void 0;
|
|
16474
16755
|
}
|
|
16475
16756
|
return normalized;
|
|
16476
16757
|
}
|
|
@@ -17044,69 +17325,436 @@ var BaseObservabilityEventBus = class _BaseObservabilityEventBus extends base.Ma
|
|
|
17044
17325
|
}
|
|
17045
17326
|
};
|
|
17046
17327
|
|
|
17047
|
-
// src/
|
|
17048
|
-
var
|
|
17049
|
-
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
|
|
17328
|
+
// src/spans/serialization.ts
|
|
17329
|
+
var DEFAULT_KEYS_TO_STRIP = /* @__PURE__ */ new Set([
|
|
17330
|
+
"logger",
|
|
17331
|
+
"experimental_providerMetadata",
|
|
17332
|
+
"providerMetadata",
|
|
17333
|
+
"steps",
|
|
17334
|
+
"tracingContext",
|
|
17335
|
+
"execute",
|
|
17336
|
+
// Tool execute functions
|
|
17337
|
+
"validate"
|
|
17338
|
+
// Schema validate functions
|
|
17339
|
+
]);
|
|
17340
|
+
var DEFAULT_DEEP_CLEAN_OPTIONS = Object.freeze({
|
|
17341
|
+
keysToStrip: DEFAULT_KEYS_TO_STRIP,
|
|
17342
|
+
maxDepth: 8,
|
|
17343
|
+
maxStringLength: 128 * 1024,
|
|
17344
|
+
// 128KB - sufficient for large LLM prompts/responses
|
|
17345
|
+
maxArrayLength: 50,
|
|
17346
|
+
maxObjectKeys: 50
|
|
17347
|
+
});
|
|
17348
|
+
function mergeSerializationOptions(userOptions) {
|
|
17349
|
+
if (!userOptions) {
|
|
17350
|
+
return DEFAULT_DEEP_CLEAN_OPTIONS;
|
|
17056
17351
|
}
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
|
|
17061
|
-
|
|
17062
|
-
|
|
17063
|
-
|
|
17064
|
-
|
|
17065
|
-
|
|
17066
|
-
|
|
17067
|
-
|
|
17352
|
+
return {
|
|
17353
|
+
keysToStrip: DEFAULT_KEYS_TO_STRIP,
|
|
17354
|
+
maxDepth: userOptions.maxDepth ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxDepth,
|
|
17355
|
+
maxStringLength: userOptions.maxStringLength ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxStringLength,
|
|
17356
|
+
maxArrayLength: userOptions.maxArrayLength ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxArrayLength,
|
|
17357
|
+
maxObjectKeys: userOptions.maxObjectKeys ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxObjectKeys
|
|
17358
|
+
};
|
|
17359
|
+
}
|
|
17360
|
+
function truncateString(s, maxChars) {
|
|
17361
|
+
if (s.length <= maxChars) {
|
|
17362
|
+
return s;
|
|
17068
17363
|
}
|
|
17069
|
-
|
|
17070
|
-
|
|
17071
|
-
|
|
17072
|
-
|
|
17073
|
-
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
if (index !== -1) {
|
|
17078
|
-
this.exporters.splice(index, 1);
|
|
17079
|
-
return true;
|
|
17080
|
-
}
|
|
17081
|
-
return false;
|
|
17364
|
+
return s.slice(0, maxChars) + "\u2026[truncated]";
|
|
17365
|
+
}
|
|
17366
|
+
function formatSerializationError(error48) {
|
|
17367
|
+
return `[${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`;
|
|
17368
|
+
}
|
|
17369
|
+
function getMapKeyType(key) {
|
|
17370
|
+
if (key === null) {
|
|
17371
|
+
return "null";
|
|
17082
17372
|
}
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
*/
|
|
17086
|
-
getExporters() {
|
|
17087
|
-
return [...this.exporters];
|
|
17373
|
+
if (key instanceof Date) {
|
|
17374
|
+
return "date";
|
|
17088
17375
|
}
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
* Only one bridge can be registered at a time; replacing an existing bridge
|
|
17092
|
-
* logs a warning.
|
|
17093
|
-
*
|
|
17094
|
-
* @param bridge - The bridge to register.
|
|
17095
|
-
*/
|
|
17096
|
-
registerBridge(bridge) {
|
|
17097
|
-
if (this.bridge) {
|
|
17098
|
-
this.logger.warn(`[ObservabilityBus] Replacing existing bridge with new bridge`);
|
|
17099
|
-
}
|
|
17100
|
-
this.bridge = bridge;
|
|
17376
|
+
if (Array.isArray(key)) {
|
|
17377
|
+
return "array";
|
|
17101
17378
|
}
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17109
|
-
|
|
17379
|
+
if (key instanceof Map) {
|
|
17380
|
+
return "map";
|
|
17381
|
+
}
|
|
17382
|
+
if (key instanceof Set) {
|
|
17383
|
+
return "set";
|
|
17384
|
+
}
|
|
17385
|
+
if (key instanceof Error) {
|
|
17386
|
+
return "error";
|
|
17387
|
+
}
|
|
17388
|
+
return typeof key;
|
|
17389
|
+
}
|
|
17390
|
+
function restoreSerializedMapKey(keyType, key) {
|
|
17391
|
+
switch (keyType) {
|
|
17392
|
+
case "undefined":
|
|
17393
|
+
return void 0;
|
|
17394
|
+
case "null":
|
|
17395
|
+
return null;
|
|
17396
|
+
case "bigint":
|
|
17397
|
+
return typeof key === "string" && key.endsWith("n") ? BigInt(key.slice(0, -1)) : key;
|
|
17398
|
+
case "date":
|
|
17399
|
+
return typeof key === "string" ? new Date(key) : key;
|
|
17400
|
+
default:
|
|
17401
|
+
return key;
|
|
17402
|
+
}
|
|
17403
|
+
}
|
|
17404
|
+
function isSerializedMap(value) {
|
|
17405
|
+
return typeof value === "object" && value !== null && value.__type === "Map" && Array.isArray(value.__map_entries);
|
|
17406
|
+
}
|
|
17407
|
+
function reconstructSerializedMap(value) {
|
|
17408
|
+
return new Map(
|
|
17409
|
+
value.__map_entries.map(([keyType, key, mapValue]) => [restoreSerializedMapKey(keyType, key), mapValue])
|
|
17410
|
+
);
|
|
17411
|
+
}
|
|
17412
|
+
function isJsonSchema(val) {
|
|
17413
|
+
if (typeof val !== "object" || val === null) return false;
|
|
17414
|
+
if (val.$schema && typeof val.$schema === "string" && val.$schema.includes("json-schema")) {
|
|
17415
|
+
return true;
|
|
17416
|
+
}
|
|
17417
|
+
if (val.type === "object" && val.properties && typeof val.properties === "object") {
|
|
17418
|
+
return true;
|
|
17419
|
+
}
|
|
17420
|
+
return false;
|
|
17421
|
+
}
|
|
17422
|
+
function compressJsonSchema(schema, depth = 0) {
|
|
17423
|
+
if (depth > 3) {
|
|
17424
|
+
return schema.type || "object";
|
|
17425
|
+
}
|
|
17426
|
+
const compositionKeys = ["oneOf", "anyOf", "allOf"].filter((key) => Array.isArray(schema[key]));
|
|
17427
|
+
if (compositionKeys.length > 0) {
|
|
17428
|
+
const compressed2 = {};
|
|
17429
|
+
for (const key of compositionKeys) {
|
|
17430
|
+
compressed2[key] = schema[key].map((entry) => compressJsonSchema(entry, depth + 1));
|
|
17431
|
+
}
|
|
17432
|
+
if (typeof schema.type === "string") {
|
|
17433
|
+
compressed2.type = schema.type;
|
|
17434
|
+
}
|
|
17435
|
+
return compressed2;
|
|
17436
|
+
}
|
|
17437
|
+
if (schema.type !== "object" || !schema.properties) {
|
|
17438
|
+
return schema.type || schema;
|
|
17439
|
+
}
|
|
17440
|
+
const required2 = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
17441
|
+
const compressed = {};
|
|
17442
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
17443
|
+
const prop = propSchema;
|
|
17444
|
+
let value = prop.type || "unknown";
|
|
17445
|
+
if (prop.type === "object" && prop.properties) {
|
|
17446
|
+
value = compressJsonSchema(prop, depth + 1);
|
|
17447
|
+
if (required2.has(key)) {
|
|
17448
|
+
compressed[key + " (required)"] = value;
|
|
17449
|
+
continue;
|
|
17450
|
+
}
|
|
17451
|
+
} else if (prop.type === "array" && prop.items) {
|
|
17452
|
+
if (prop.items.type === "object" && prop.items.properties) {
|
|
17453
|
+
value = [compressJsonSchema(prop.items, depth + 1)];
|
|
17454
|
+
} else {
|
|
17455
|
+
value = `${prop.items.type || "any"}[]`;
|
|
17456
|
+
}
|
|
17457
|
+
} else if (prop.enum) {
|
|
17458
|
+
value = prop.enum.map((v) => JSON.stringify(v)).join(" | ");
|
|
17459
|
+
}
|
|
17460
|
+
if (required2.has(key) && typeof value === "string") {
|
|
17461
|
+
value += " (required)";
|
|
17462
|
+
}
|
|
17463
|
+
compressed[key] = value;
|
|
17464
|
+
}
|
|
17465
|
+
return compressed;
|
|
17466
|
+
}
|
|
17467
|
+
function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
|
|
17468
|
+
const { keysToStrip, maxDepth, maxStringLength, maxArrayLength, maxObjectKeys } = options;
|
|
17469
|
+
const stripSet = keysToStrip instanceof Set ? keysToStrip : new Set(Array.isArray(keysToStrip) ? keysToStrip : Object.keys(keysToStrip));
|
|
17470
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
17471
|
+
function helper(val, depth) {
|
|
17472
|
+
if (depth > maxDepth) {
|
|
17473
|
+
return "[MaxDepth]";
|
|
17474
|
+
}
|
|
17475
|
+
if (val === null || val === void 0) {
|
|
17476
|
+
return val;
|
|
17477
|
+
}
|
|
17478
|
+
if (typeof val === "string") {
|
|
17479
|
+
return truncateString(val, maxStringLength);
|
|
17480
|
+
}
|
|
17481
|
+
if (typeof val === "number" || typeof val === "boolean") {
|
|
17482
|
+
return val;
|
|
17483
|
+
}
|
|
17484
|
+
if (typeof val === "bigint") {
|
|
17485
|
+
return `${val}n`;
|
|
17486
|
+
}
|
|
17487
|
+
if (typeof val === "function") {
|
|
17488
|
+
return "[Function]";
|
|
17489
|
+
}
|
|
17490
|
+
if (typeof val === "symbol") {
|
|
17491
|
+
return val.description ? `[Symbol(${val.description})]` : "[Symbol]";
|
|
17492
|
+
}
|
|
17493
|
+
if (val instanceof Date) {
|
|
17494
|
+
return val;
|
|
17495
|
+
}
|
|
17496
|
+
if (typeof val === "object") {
|
|
17497
|
+
if (ancestors.has(val)) {
|
|
17498
|
+
return "[Circular]";
|
|
17499
|
+
}
|
|
17500
|
+
ancestors.add(val);
|
|
17501
|
+
}
|
|
17502
|
+
try {
|
|
17503
|
+
if (val instanceof Error) {
|
|
17504
|
+
let errorName;
|
|
17505
|
+
let errorMessage;
|
|
17506
|
+
let errorStack;
|
|
17507
|
+
let rawCause;
|
|
17508
|
+
let causeReadFailed = false;
|
|
17509
|
+
try {
|
|
17510
|
+
errorName = val.name;
|
|
17511
|
+
} catch (error48) {
|
|
17512
|
+
errorName = formatSerializationError(error48);
|
|
17513
|
+
}
|
|
17514
|
+
try {
|
|
17515
|
+
errorMessage = val.message;
|
|
17516
|
+
} catch (error48) {
|
|
17517
|
+
errorMessage = formatSerializationError(error48);
|
|
17518
|
+
}
|
|
17519
|
+
try {
|
|
17520
|
+
errorStack = val.stack;
|
|
17521
|
+
} catch (error48) {
|
|
17522
|
+
errorStack = formatSerializationError(error48);
|
|
17523
|
+
}
|
|
17524
|
+
try {
|
|
17525
|
+
rawCause = val.cause;
|
|
17526
|
+
} catch (error48) {
|
|
17527
|
+
causeReadFailed = true;
|
|
17528
|
+
rawCause = formatSerializationError(error48);
|
|
17529
|
+
}
|
|
17530
|
+
const cleanedError = {
|
|
17531
|
+
name: typeof errorName === "string" ? truncateString(errorName, maxStringLength) : errorName,
|
|
17532
|
+
message: typeof errorMessage === "string" ? truncateString(errorMessage, maxStringLength) : errorMessage
|
|
17533
|
+
};
|
|
17534
|
+
if (typeof errorStack === "string") {
|
|
17535
|
+
cleanedError.stack = truncateString(errorStack, maxStringLength);
|
|
17536
|
+
} else if (errorStack !== void 0) {
|
|
17537
|
+
cleanedError.stack = errorStack;
|
|
17538
|
+
}
|
|
17539
|
+
if (causeReadFailed) {
|
|
17540
|
+
cleanedError.cause = rawCause;
|
|
17541
|
+
} else if (rawCause !== void 0) {
|
|
17542
|
+
try {
|
|
17543
|
+
cleanedError.cause = helper(rawCause, depth + 1);
|
|
17544
|
+
} catch (error48) {
|
|
17545
|
+
cleanedError.cause = formatSerializationError(error48);
|
|
17546
|
+
}
|
|
17547
|
+
}
|
|
17548
|
+
return cleanedError;
|
|
17549
|
+
}
|
|
17550
|
+
if (val instanceof Map) {
|
|
17551
|
+
const cleanedMap = { __type: "Map", __map_entries: [] };
|
|
17552
|
+
let mapKeyCount = 0;
|
|
17553
|
+
let omittedMapEntries = 0;
|
|
17554
|
+
for (const [mapKey, mapVal] of val) {
|
|
17555
|
+
if (typeof mapKey === "string" && stripSet.has(mapKey)) {
|
|
17556
|
+
continue;
|
|
17557
|
+
}
|
|
17558
|
+
if (mapKeyCount >= maxObjectKeys) {
|
|
17559
|
+
omittedMapEntries++;
|
|
17560
|
+
continue;
|
|
17561
|
+
}
|
|
17562
|
+
const mapKeyType = getMapKeyType(mapKey);
|
|
17563
|
+
let cleanedMapKey;
|
|
17564
|
+
let cleanedMapValue;
|
|
17565
|
+
try {
|
|
17566
|
+
cleanedMapKey = helper(mapKey, depth + 1);
|
|
17567
|
+
} catch (error48) {
|
|
17568
|
+
cleanedMapKey = formatSerializationError(error48);
|
|
17569
|
+
}
|
|
17570
|
+
try {
|
|
17571
|
+
cleanedMapValue = helper(mapVal, depth + 1);
|
|
17572
|
+
} catch (error48) {
|
|
17573
|
+
cleanedMapValue = formatSerializationError(error48);
|
|
17574
|
+
}
|
|
17575
|
+
cleanedMap.__map_entries.push([mapKeyType, cleanedMapKey, cleanedMapValue]);
|
|
17576
|
+
mapKeyCount++;
|
|
17577
|
+
}
|
|
17578
|
+
if (omittedMapEntries > 0) {
|
|
17579
|
+
cleanedMap.__truncated = `${omittedMapEntries} more keys omitted`;
|
|
17580
|
+
}
|
|
17581
|
+
return cleanedMap;
|
|
17582
|
+
}
|
|
17583
|
+
if (val instanceof Set) {
|
|
17584
|
+
const cleanedSet = [];
|
|
17585
|
+
let i = 0;
|
|
17586
|
+
const totalSetSize = val.size;
|
|
17587
|
+
for (const item of val) {
|
|
17588
|
+
if (i >= maxArrayLength) break;
|
|
17589
|
+
try {
|
|
17590
|
+
cleanedSet.push(helper(item, depth + 1));
|
|
17591
|
+
} catch (error48) {
|
|
17592
|
+
cleanedSet.push(formatSerializationError(error48));
|
|
17593
|
+
}
|
|
17594
|
+
i++;
|
|
17595
|
+
}
|
|
17596
|
+
if (totalSetSize > maxArrayLength) {
|
|
17597
|
+
cleanedSet.push(`[\u2026${totalSetSize - maxArrayLength} more items]`);
|
|
17598
|
+
}
|
|
17599
|
+
return cleanedSet;
|
|
17600
|
+
}
|
|
17601
|
+
if (Array.isArray(val)) {
|
|
17602
|
+
const cleaned2 = [];
|
|
17603
|
+
for (let i = 0; i < Math.min(val.length, maxArrayLength); i++) {
|
|
17604
|
+
try {
|
|
17605
|
+
cleaned2.push(helper(val[i], depth + 1));
|
|
17606
|
+
} catch (error48) {
|
|
17607
|
+
cleaned2.push(formatSerializationError(error48));
|
|
17608
|
+
}
|
|
17609
|
+
}
|
|
17610
|
+
if (val.length > maxArrayLength) {
|
|
17611
|
+
cleaned2.push(`[\u2026${val.length - maxArrayLength} more items]`);
|
|
17612
|
+
}
|
|
17613
|
+
return cleaned2;
|
|
17614
|
+
}
|
|
17615
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(val)) {
|
|
17616
|
+
return `[Buffer length=${val.length}]`;
|
|
17617
|
+
}
|
|
17618
|
+
if (ArrayBuffer.isView(val)) {
|
|
17619
|
+
const ctor = val.constructor?.name ?? "TypedArray";
|
|
17620
|
+
const byteLength = val.byteLength ?? "?";
|
|
17621
|
+
return `[${ctor} byteLength=${byteLength}]`;
|
|
17622
|
+
}
|
|
17623
|
+
if (val instanceof ArrayBuffer) {
|
|
17624
|
+
return `[ArrayBuffer byteLength=${val.byteLength}]`;
|
|
17625
|
+
}
|
|
17626
|
+
let serializeForSpan;
|
|
17627
|
+
try {
|
|
17628
|
+
serializeForSpan = val.serializeForSpan;
|
|
17629
|
+
} catch (error48) {
|
|
17630
|
+
return `[serializeForSpan failed: ${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`;
|
|
17631
|
+
}
|
|
17632
|
+
if (typeof serializeForSpan === "function") {
|
|
17633
|
+
try {
|
|
17634
|
+
return helper(serializeForSpan.call(val), depth);
|
|
17635
|
+
} catch (error48) {
|
|
17636
|
+
return `[serializeForSpan failed: ${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`;
|
|
17637
|
+
}
|
|
17638
|
+
}
|
|
17639
|
+
let looksLikeJsonSchema = false;
|
|
17640
|
+
try {
|
|
17641
|
+
looksLikeJsonSchema = isJsonSchema(val);
|
|
17642
|
+
} catch {
|
|
17643
|
+
looksLikeJsonSchema = false;
|
|
17644
|
+
}
|
|
17645
|
+
if (looksLikeJsonSchema) {
|
|
17646
|
+
try {
|
|
17647
|
+
const compressed = compressJsonSchema(val);
|
|
17648
|
+
return compressed === val ? "[JSONSchema]" : helper(compressed, depth);
|
|
17649
|
+
} catch {
|
|
17650
|
+
}
|
|
17651
|
+
}
|
|
17652
|
+
const cleaned = {};
|
|
17653
|
+
const keys = Object.keys(val).filter((key) => !stripSet.has(key));
|
|
17654
|
+
let keyCount = 0;
|
|
17655
|
+
for (const key of keys) {
|
|
17656
|
+
if (keyCount >= maxObjectKeys) {
|
|
17657
|
+
cleaned["__truncated"] = `${keys.length - keyCount} more keys omitted`;
|
|
17658
|
+
break;
|
|
17659
|
+
}
|
|
17660
|
+
try {
|
|
17661
|
+
cleaned[key] = helper(val[key], depth + 1);
|
|
17662
|
+
keyCount++;
|
|
17663
|
+
} catch (error48) {
|
|
17664
|
+
cleaned[key] = formatSerializationError(error48);
|
|
17665
|
+
keyCount++;
|
|
17666
|
+
}
|
|
17667
|
+
}
|
|
17668
|
+
return cleaned;
|
|
17669
|
+
} finally {
|
|
17670
|
+
if (typeof val === "object" && val !== null) {
|
|
17671
|
+
ancestors.delete(val);
|
|
17672
|
+
}
|
|
17673
|
+
}
|
|
17674
|
+
}
|
|
17675
|
+
return helper(value, 0);
|
|
17676
|
+
}
|
|
17677
|
+
|
|
17678
|
+
// src/bus/observability-bus.ts
|
|
17679
|
+
function cleanEvent(event, options) {
|
|
17680
|
+
switch (event.type) {
|
|
17681
|
+
case "log":
|
|
17682
|
+
return { type: "log", log: deepClean(event.log, options) };
|
|
17683
|
+
case "metric":
|
|
17684
|
+
return { type: "metric", metric: deepClean(event.metric, options) };
|
|
17685
|
+
case "score":
|
|
17686
|
+
return { type: "score", score: deepClean(event.score, options) };
|
|
17687
|
+
case "feedback":
|
|
17688
|
+
return { type: "feedback", feedback: deepClean(event.feedback, options) };
|
|
17689
|
+
default:
|
|
17690
|
+
return event;
|
|
17691
|
+
}
|
|
17692
|
+
}
|
|
17693
|
+
var MAX_FLUSH_ITERATIONS = 3;
|
|
17694
|
+
var ObservabilityBus = class extends BaseObservabilityEventBus {
|
|
17695
|
+
exporters = [];
|
|
17696
|
+
bridge;
|
|
17697
|
+
/** In-flight handler promises from routeToHandler. Self-cleaning via .finally(). */
|
|
17698
|
+
pendingHandlers = /* @__PURE__ */ new Set();
|
|
17699
|
+
/** Resolved deepClean options applied to non-tracing events before fan-out. */
|
|
17700
|
+
deepCleanOptions;
|
|
17701
|
+
constructor(opts) {
|
|
17702
|
+
super({ name: "ObservabilityBus" });
|
|
17703
|
+
this.deepCleanOptions = mergeSerializationOptions(opts?.serializationOptions);
|
|
17704
|
+
}
|
|
17705
|
+
/**
|
|
17706
|
+
* Register an exporter to receive routed events.
|
|
17707
|
+
* Duplicate registrations (same instance) are silently ignored.
|
|
17708
|
+
*
|
|
17709
|
+
* @param exporter - The exporter to register.
|
|
17710
|
+
*/
|
|
17711
|
+
registerExporter(exporter) {
|
|
17712
|
+
if (this.exporters.includes(exporter)) {
|
|
17713
|
+
return;
|
|
17714
|
+
}
|
|
17715
|
+
this.exporters.push(exporter);
|
|
17716
|
+
}
|
|
17717
|
+
/**
|
|
17718
|
+
* Unregister an exporter.
|
|
17719
|
+
*
|
|
17720
|
+
* @param exporter - The exporter instance to remove.
|
|
17721
|
+
* @returns `true` if the exporter was found and removed, `false` otherwise.
|
|
17722
|
+
*/
|
|
17723
|
+
unregisterExporter(exporter) {
|
|
17724
|
+
const index = this.exporters.indexOf(exporter);
|
|
17725
|
+
if (index !== -1) {
|
|
17726
|
+
this.exporters.splice(index, 1);
|
|
17727
|
+
return true;
|
|
17728
|
+
}
|
|
17729
|
+
return false;
|
|
17730
|
+
}
|
|
17731
|
+
/**
|
|
17732
|
+
* Get registered exporters (read-only snapshot).
|
|
17733
|
+
*/
|
|
17734
|
+
getExporters() {
|
|
17735
|
+
return [...this.exporters];
|
|
17736
|
+
}
|
|
17737
|
+
/**
|
|
17738
|
+
* Register a bridge to receive all routed events alongside exporters.
|
|
17739
|
+
* Only one bridge can be registered at a time; replacing an existing bridge
|
|
17740
|
+
* logs a warning.
|
|
17741
|
+
*
|
|
17742
|
+
* @param bridge - The bridge to register.
|
|
17743
|
+
*/
|
|
17744
|
+
registerBridge(bridge) {
|
|
17745
|
+
if (this.bridge) {
|
|
17746
|
+
this.logger.warn(`[ObservabilityBus] Replacing existing bridge with new bridge`);
|
|
17747
|
+
}
|
|
17748
|
+
this.bridge = bridge;
|
|
17749
|
+
}
|
|
17750
|
+
/**
|
|
17751
|
+
* Unregister the bridge.
|
|
17752
|
+
*
|
|
17753
|
+
* @returns `true` if a bridge was registered and removed, `false` otherwise.
|
|
17754
|
+
*/
|
|
17755
|
+
unregisterBridge() {
|
|
17756
|
+
if (this.bridge) {
|
|
17757
|
+
this.bridge = void 0;
|
|
17110
17758
|
return true;
|
|
17111
17759
|
}
|
|
17112
17760
|
return false;
|
|
@@ -17125,13 +17773,14 @@ var ObservabilityBus = class extends BaseObservabilityEventBus {
|
|
|
17125
17773
|
* and can be drained via flush().
|
|
17126
17774
|
*/
|
|
17127
17775
|
emit(event) {
|
|
17776
|
+
const cleaned = cleanEvent(event, this.deepCleanOptions);
|
|
17128
17777
|
for (const exporter of this.exporters) {
|
|
17129
|
-
this.trackPromise(routeToHandler(exporter,
|
|
17778
|
+
this.trackPromise(routeToHandler(exporter, cleaned, this.logger));
|
|
17130
17779
|
}
|
|
17131
17780
|
if (this.bridge) {
|
|
17132
|
-
this.trackPromise(routeToHandler(this.bridge,
|
|
17781
|
+
this.trackPromise(routeToHandler(this.bridge, cleaned, this.logger));
|
|
17133
17782
|
}
|
|
17134
|
-
super.emit(
|
|
17783
|
+
super.emit(cleaned);
|
|
17135
17784
|
}
|
|
17136
17785
|
/**
|
|
17137
17786
|
* Track an async handler promise so flush() can await it.
|
|
@@ -18402,218 +19051,6 @@ var ModelSpanTracker = class {
|
|
|
18402
19051
|
}
|
|
18403
19052
|
};
|
|
18404
19053
|
|
|
18405
|
-
// src/spans/serialization.ts
|
|
18406
|
-
var DEFAULT_KEYS_TO_STRIP = /* @__PURE__ */ new Set([
|
|
18407
|
-
"logger",
|
|
18408
|
-
"experimental_providerMetadata",
|
|
18409
|
-
"providerMetadata",
|
|
18410
|
-
"steps",
|
|
18411
|
-
"tracingContext",
|
|
18412
|
-
"execute",
|
|
18413
|
-
// Tool execute functions
|
|
18414
|
-
"validate"
|
|
18415
|
-
// Schema validate functions
|
|
18416
|
-
]);
|
|
18417
|
-
var DEFAULT_DEEP_CLEAN_OPTIONS = Object.freeze({
|
|
18418
|
-
keysToStrip: DEFAULT_KEYS_TO_STRIP,
|
|
18419
|
-
maxDepth: 8,
|
|
18420
|
-
maxStringLength: 128 * 1024,
|
|
18421
|
-
// 128KB - sufficient for large LLM prompts/responses
|
|
18422
|
-
maxArrayLength: 50,
|
|
18423
|
-
maxObjectKeys: 50
|
|
18424
|
-
});
|
|
18425
|
-
function mergeSerializationOptions(userOptions) {
|
|
18426
|
-
if (!userOptions) {
|
|
18427
|
-
return DEFAULT_DEEP_CLEAN_OPTIONS;
|
|
18428
|
-
}
|
|
18429
|
-
return {
|
|
18430
|
-
keysToStrip: DEFAULT_KEYS_TO_STRIP,
|
|
18431
|
-
maxDepth: userOptions.maxDepth ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxDepth,
|
|
18432
|
-
maxStringLength: userOptions.maxStringLength ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxStringLength,
|
|
18433
|
-
maxArrayLength: userOptions.maxArrayLength ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxArrayLength,
|
|
18434
|
-
maxObjectKeys: userOptions.maxObjectKeys ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxObjectKeys
|
|
18435
|
-
};
|
|
18436
|
-
}
|
|
18437
|
-
function truncateString(s, maxChars) {
|
|
18438
|
-
if (s.length <= maxChars) {
|
|
18439
|
-
return s;
|
|
18440
|
-
}
|
|
18441
|
-
return s.slice(0, maxChars) + "\u2026[truncated]";
|
|
18442
|
-
}
|
|
18443
|
-
function isJsonSchema(val) {
|
|
18444
|
-
if (typeof val !== "object" || val === null) return false;
|
|
18445
|
-
if (val.$schema && typeof val.$schema === "string" && val.$schema.includes("json-schema")) {
|
|
18446
|
-
return true;
|
|
18447
|
-
}
|
|
18448
|
-
if (val.type === "object" && val.properties && typeof val.properties === "object") {
|
|
18449
|
-
return true;
|
|
18450
|
-
}
|
|
18451
|
-
return false;
|
|
18452
|
-
}
|
|
18453
|
-
function compressJsonSchema(schema, depth = 0) {
|
|
18454
|
-
if (depth > 3) {
|
|
18455
|
-
return schema.type || "object";
|
|
18456
|
-
}
|
|
18457
|
-
const compositionKeys = ["oneOf", "anyOf", "allOf"].filter((key) => Array.isArray(schema[key]));
|
|
18458
|
-
if (compositionKeys.length > 0) {
|
|
18459
|
-
const compressed2 = {};
|
|
18460
|
-
for (const key of compositionKeys) {
|
|
18461
|
-
compressed2[key] = schema[key].map((entry) => compressJsonSchema(entry, depth + 1));
|
|
18462
|
-
}
|
|
18463
|
-
if (typeof schema.type === "string") {
|
|
18464
|
-
compressed2.type = schema.type;
|
|
18465
|
-
}
|
|
18466
|
-
return compressed2;
|
|
18467
|
-
}
|
|
18468
|
-
if (schema.type !== "object" || !schema.properties) {
|
|
18469
|
-
return schema.type || schema;
|
|
18470
|
-
}
|
|
18471
|
-
const required2 = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
18472
|
-
const compressed = {};
|
|
18473
|
-
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
18474
|
-
const prop = propSchema;
|
|
18475
|
-
let value = prop.type || "unknown";
|
|
18476
|
-
if (prop.type === "object" && prop.properties) {
|
|
18477
|
-
value = compressJsonSchema(prop, depth + 1);
|
|
18478
|
-
if (required2.has(key)) {
|
|
18479
|
-
compressed[key + " (required)"] = value;
|
|
18480
|
-
continue;
|
|
18481
|
-
}
|
|
18482
|
-
} else if (prop.type === "array" && prop.items) {
|
|
18483
|
-
if (prop.items.type === "object" && prop.items.properties) {
|
|
18484
|
-
value = [compressJsonSchema(prop.items, depth + 1)];
|
|
18485
|
-
} else {
|
|
18486
|
-
value = `${prop.items.type || "any"}[]`;
|
|
18487
|
-
}
|
|
18488
|
-
} else if (prop.enum) {
|
|
18489
|
-
value = prop.enum.map((v) => JSON.stringify(v)).join(" | ");
|
|
18490
|
-
}
|
|
18491
|
-
if (required2.has(key) && typeof value === "string") {
|
|
18492
|
-
value += " (required)";
|
|
18493
|
-
}
|
|
18494
|
-
compressed[key] = value;
|
|
18495
|
-
}
|
|
18496
|
-
return compressed;
|
|
18497
|
-
}
|
|
18498
|
-
function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
|
|
18499
|
-
const { keysToStrip, maxDepth, maxStringLength, maxArrayLength, maxObjectKeys } = options;
|
|
18500
|
-
const stripSet = keysToStrip instanceof Set ? keysToStrip : new Set(Array.isArray(keysToStrip) ? keysToStrip : Object.keys(keysToStrip));
|
|
18501
|
-
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
18502
|
-
function helper(val, depth) {
|
|
18503
|
-
if (depth > maxDepth) {
|
|
18504
|
-
return "[MaxDepth]";
|
|
18505
|
-
}
|
|
18506
|
-
if (val === null || val === void 0) {
|
|
18507
|
-
return val;
|
|
18508
|
-
}
|
|
18509
|
-
if (typeof val === "string") {
|
|
18510
|
-
return truncateString(val, maxStringLength);
|
|
18511
|
-
}
|
|
18512
|
-
if (typeof val === "number" || typeof val === "boolean") {
|
|
18513
|
-
return val;
|
|
18514
|
-
}
|
|
18515
|
-
if (typeof val === "bigint") {
|
|
18516
|
-
return `${val}n`;
|
|
18517
|
-
}
|
|
18518
|
-
if (typeof val === "function") {
|
|
18519
|
-
return "[Function]";
|
|
18520
|
-
}
|
|
18521
|
-
if (typeof val === "symbol") {
|
|
18522
|
-
return val.description ? `[Symbol(${val.description})]` : "[Symbol]";
|
|
18523
|
-
}
|
|
18524
|
-
if (val instanceof Date) {
|
|
18525
|
-
return val;
|
|
18526
|
-
}
|
|
18527
|
-
if (val instanceof Error) {
|
|
18528
|
-
return {
|
|
18529
|
-
name: val.name,
|
|
18530
|
-
message: val.message ? truncateString(val.message, maxStringLength) : void 0
|
|
18531
|
-
};
|
|
18532
|
-
}
|
|
18533
|
-
if (typeof val === "object") {
|
|
18534
|
-
if (ancestors.has(val)) {
|
|
18535
|
-
return "[Circular]";
|
|
18536
|
-
}
|
|
18537
|
-
ancestors.add(val);
|
|
18538
|
-
}
|
|
18539
|
-
try {
|
|
18540
|
-
if (Array.isArray(val)) {
|
|
18541
|
-
const cleaned2 = [];
|
|
18542
|
-
for (let i = 0; i < Math.min(val.length, maxArrayLength); i++) {
|
|
18543
|
-
try {
|
|
18544
|
-
cleaned2.push(helper(val[i], depth + 1));
|
|
18545
|
-
} catch (error48) {
|
|
18546
|
-
cleaned2.push(`[${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`);
|
|
18547
|
-
}
|
|
18548
|
-
}
|
|
18549
|
-
if (val.length > maxArrayLength) {
|
|
18550
|
-
cleaned2.push(`[\u2026${val.length - maxArrayLength} more items]`);
|
|
18551
|
-
}
|
|
18552
|
-
return cleaned2;
|
|
18553
|
-
}
|
|
18554
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(val)) {
|
|
18555
|
-
return `[Buffer length=${val.length}]`;
|
|
18556
|
-
}
|
|
18557
|
-
if (ArrayBuffer.isView(val)) {
|
|
18558
|
-
const ctor = val.constructor?.name ?? "TypedArray";
|
|
18559
|
-
const byteLength = val.byteLength ?? "?";
|
|
18560
|
-
return `[${ctor} byteLength=${byteLength}]`;
|
|
18561
|
-
}
|
|
18562
|
-
if (val instanceof ArrayBuffer) {
|
|
18563
|
-
return `[ArrayBuffer byteLength=${val.byteLength}]`;
|
|
18564
|
-
}
|
|
18565
|
-
let serializeForSpan;
|
|
18566
|
-
try {
|
|
18567
|
-
serializeForSpan = val.serializeForSpan;
|
|
18568
|
-
} catch (error48) {
|
|
18569
|
-
return `[serializeForSpan failed: ${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`;
|
|
18570
|
-
}
|
|
18571
|
-
if (typeof serializeForSpan === "function") {
|
|
18572
|
-
try {
|
|
18573
|
-
return helper(serializeForSpan.call(val), depth);
|
|
18574
|
-
} catch (error48) {
|
|
18575
|
-
return `[serializeForSpan failed: ${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`;
|
|
18576
|
-
}
|
|
18577
|
-
}
|
|
18578
|
-
let looksLikeJsonSchema = false;
|
|
18579
|
-
try {
|
|
18580
|
-
looksLikeJsonSchema = isJsonSchema(val);
|
|
18581
|
-
} catch {
|
|
18582
|
-
looksLikeJsonSchema = false;
|
|
18583
|
-
}
|
|
18584
|
-
if (looksLikeJsonSchema) {
|
|
18585
|
-
try {
|
|
18586
|
-
const compressed = compressJsonSchema(val);
|
|
18587
|
-
return compressed === val ? "[JSONSchema]" : helper(compressed, depth);
|
|
18588
|
-
} catch {
|
|
18589
|
-
}
|
|
18590
|
-
}
|
|
18591
|
-
const cleaned = {};
|
|
18592
|
-
const keys = Object.keys(val).filter((key) => !stripSet.has(key));
|
|
18593
|
-
let keyCount = 0;
|
|
18594
|
-
for (const key of keys) {
|
|
18595
|
-
if (keyCount >= maxObjectKeys) {
|
|
18596
|
-
cleaned["__truncated"] = `${keys.length - keyCount} more keys omitted`;
|
|
18597
|
-
break;
|
|
18598
|
-
}
|
|
18599
|
-
try {
|
|
18600
|
-
cleaned[key] = helper(val[key], depth + 1);
|
|
18601
|
-
keyCount++;
|
|
18602
|
-
} catch (error48) {
|
|
18603
|
-
cleaned[key] = `[${error48 instanceof Error ? truncateString(error48.message, 256) : "unknown error"}]`;
|
|
18604
|
-
keyCount++;
|
|
18605
|
-
}
|
|
18606
|
-
}
|
|
18607
|
-
return cleaned;
|
|
18608
|
-
} finally {
|
|
18609
|
-
if (typeof val === "object" && val !== null) {
|
|
18610
|
-
ancestors.delete(val);
|
|
18611
|
-
}
|
|
18612
|
-
}
|
|
18613
|
-
}
|
|
18614
|
-
return helper(value, 0);
|
|
18615
|
-
}
|
|
18616
|
-
|
|
18617
19054
|
// src/spans/base.ts
|
|
18618
19055
|
function isSpanInternal(spanType, flags) {
|
|
18619
19056
|
if (flags === void 0 || flags === observability.InternalSpans.NONE) {
|
|
@@ -19067,12 +19504,16 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
19067
19504
|
spanOutputProcessors: config2.spanOutputProcessors ?? [],
|
|
19068
19505
|
bridge: config2.bridge ?? void 0,
|
|
19069
19506
|
includeInternalSpans: config2.includeInternalSpans ?? false,
|
|
19507
|
+
excludeSpanTypes: config2.excludeSpanTypes,
|
|
19508
|
+
spanFilter: config2.spanFilter,
|
|
19070
19509
|
requestContextKeys: config2.requestContextKeys ?? [],
|
|
19071
19510
|
serializationOptions: config2.serializationOptions,
|
|
19072
19511
|
logging: config2.logging
|
|
19073
19512
|
};
|
|
19074
19513
|
this.cardinalityFilter = new CardinalityFilter(config2.cardinality);
|
|
19075
|
-
this.observabilityBus = new ObservabilityBus(
|
|
19514
|
+
this.observabilityBus = new ObservabilityBus({
|
|
19515
|
+
serializationOptions: this.config.serializationOptions
|
|
19516
|
+
});
|
|
19076
19517
|
for (const exporter of this.exporters) {
|
|
19077
19518
|
this.observabilityBus.registerExporter(exporter);
|
|
19078
19519
|
}
|
|
@@ -19450,8 +19891,18 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
19450
19891
|
getSpanForExport(span) {
|
|
19451
19892
|
if (!span.isValid) return void 0;
|
|
19452
19893
|
if (span.isInternal && !this.config.includeInternalSpans) return void 0;
|
|
19894
|
+
if (this.config.excludeSpanTypes?.includes(span.type)) return void 0;
|
|
19453
19895
|
const processedSpan = this.processSpan(span);
|
|
19454
|
-
|
|
19896
|
+
const exportedSpan = processedSpan?.exportSpan(this.config.includeInternalSpans);
|
|
19897
|
+
if (!exportedSpan) return void 0;
|
|
19898
|
+
if (this.config.spanFilter) {
|
|
19899
|
+
try {
|
|
19900
|
+
if (!this.config.spanFilter(exportedSpan)) return void 0;
|
|
19901
|
+
} catch (error48) {
|
|
19902
|
+
this.logger.error(`[Observability] spanFilter error`, error48);
|
|
19903
|
+
}
|
|
19904
|
+
}
|
|
19905
|
+
return exportedSpan;
|
|
19455
19906
|
}
|
|
19456
19907
|
/**
|
|
19457
19908
|
* Emit a span started event.
|
|
@@ -20433,10 +20884,12 @@ exports.buildTracingOptions = buildTracingOptions;
|
|
|
20433
20884
|
exports.chainFormatters = chainFormatters;
|
|
20434
20885
|
exports.deepClean = deepClean;
|
|
20435
20886
|
exports.getExternalParentId = getExternalParentId;
|
|
20887
|
+
exports.isSerializedMap = isSerializedMap;
|
|
20436
20888
|
exports.mergeSerializationOptions = mergeSerializationOptions;
|
|
20437
20889
|
exports.observabilityConfigValueSchema = observabilityConfigValueSchema;
|
|
20438
20890
|
exports.observabilityInstanceConfigSchema = observabilityInstanceConfigSchema;
|
|
20439
20891
|
exports.observabilityRegistryConfigSchema = observabilityRegistryConfigSchema;
|
|
20892
|
+
exports.reconstructSerializedMap = reconstructSerializedMap;
|
|
20440
20893
|
exports.routeToHandler = routeToHandler;
|
|
20441
20894
|
exports.samplingStrategySchema = samplingStrategySchema;
|
|
20442
20895
|
exports.serializationOptionsSchema = serializationOptionsSchema;
|