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