@mastra/observability 1.9.1 → 1.9.2-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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # @mastra/observability
2
2
 
3
+ ## 1.9.2-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Improved tracing overhead when filtering spans. Spans dropped by `excludeSpanTypes` or the internal-span filter (`includeInternalSpans: false`) now skip payload serialization and retention entirely instead of paying the cost and discarding at export time. ([#15487](https://github.com/mastra-ai/mastra/pull/15487))
8
+
9
+ - Updated dependencies [[`6315317`](https://github.com/mastra-ai/mastra/commit/63153175fe9a7b224e5be7c209bbebc01dd9b0d5), [`9d3b24b`](https://github.com/mastra-ai/mastra/commit/9d3b24b19407ae9c09586cf7766d38dc4dff4a69)]:
10
+ - @mastra/core@1.26.0-alpha.6
11
+
12
+ ## 1.9.2-alpha.0
13
+
14
+ ### Patch Changes
15
+
16
+ - Fixed span serialization replacing tool parameter JSON schemas with lossy summaries like `"unknown (required)"`. JSON schemas in span data are now preserved as-is, keeping full type information for debugging in observability tools like Datadog. Also fixed MODEL_STEP span input showing only a keys summary instead of actual messages for AI SDK v5 providers. ([#15404](https://github.com/mastra-ai/mastra/pull/15404))
17
+
18
+ - Fixed CloudExporter to default to observability.mastra.ai for Mastra platform exports. ([#15418](https://github.com/mastra-ai/mastra/pull/15418))
19
+
20
+ - Updated dependencies [[`3d83d06`](https://github.com/mastra-ai/mastra/commit/3d83d06f776f00fb5f4163dddd32a030c5c20844), [`7e0e63e`](https://github.com/mastra-ai/mastra/commit/7e0e63e2e485e84442351f4c7a79a424c83539dc), [`9467ea8`](https://github.com/mastra-ai/mastra/commit/9467ea87695749a53dfc041576410ebf9ee7bb67), [`7338d94`](https://github.com/mastra-ai/mastra/commit/7338d949380cf68b095342e8e42610dc51d557c1)]:
21
+ - @mastra/core@1.26.0-alpha.2
22
+
3
23
  ## 1.9.1
4
24
 
5
25
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/exporters/cloud.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA+LD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,IAAI,SAAyC;IAE7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAA4B;gBAEvC,MAAM,GAAE,mBAAwB;cAgE5B,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjE,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1D,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;YAMR,mBAAmB;IAYjC,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,aAAa;YAoBP,WAAW;IAoDzB;;OAEG;YACW,WAAW;YAuBX,gBAAgB;IA+B9B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAiChC"}
1
+ {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/exporters/cloud.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA6LD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,IAAI,SAAyC;IAE7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAA4B;gBAEvC,MAAM,GAAE,mBAAwB;cAgE5B,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjE,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1D,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;YAMR,mBAAmB;IAYjC,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,aAAa;YAoBP,WAAW;IAoDzB;;OAEG;YACW,WAAW;YAuBX,gBAAgB;IA+B9B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAiChC"}
package/dist/index.cjs CHANGED
@@ -15058,7 +15058,6 @@ var SIGNAL_PUBLISH_SEGMENTS = {
15058
15058
  scores: "scores",
15059
15059
  feedback: "feedback"
15060
15060
  };
15061
- var DEFAULT_CLOUD_ENDPOINT = "https://api.mastra.ai";
15062
15061
  function trimTrailingSlashes(value) {
15063
15062
  let end = value.length;
15064
15063
  while (end > 0 && value.charCodeAt(end - 1) === 47) {
@@ -15187,7 +15186,7 @@ var CloudExporter = class extends BaseExporter {
15187
15186
  if (tracesEndpointOverride) {
15188
15187
  tracesEndpoint = resolveExplicitSignalEndpoint("traces", tracesEndpointOverride, projectId);
15189
15188
  } else {
15190
- baseEndpoint = resolveBaseEndpoint(config2.endpoint ?? DEFAULT_CLOUD_ENDPOINT);
15189
+ baseEndpoint = resolveBaseEndpoint(config2.endpoint ?? "https://observability.mastra.ai");
15191
15190
  tracesEndpoint = buildSignalEndpoint(baseEndpoint, "traces", projectId);
15192
15191
  }
15193
15192
  const resolveConfiguredSignalEndpoint = (signal, explicitEndpoint) => {
@@ -17436,51 +17435,6 @@ function isJsonSchema(val) {
17436
17435
  }
17437
17436
  return false;
17438
17437
  }
17439
- function compressJsonSchema(schema, depth = 0) {
17440
- if (depth > 3) {
17441
- return schema.type || "object";
17442
- }
17443
- const compositionKeys = ["oneOf", "anyOf", "allOf"].filter((key) => Array.isArray(schema[key]));
17444
- if (compositionKeys.length > 0) {
17445
- const compressed2 = {};
17446
- for (const key of compositionKeys) {
17447
- compressed2[key] = schema[key].map((entry) => compressJsonSchema(entry, depth + 1));
17448
- }
17449
- if (typeof schema.type === "string") {
17450
- compressed2.type = schema.type;
17451
- }
17452
- return compressed2;
17453
- }
17454
- if (schema.type !== "object" || !schema.properties) {
17455
- return schema.type || schema;
17456
- }
17457
- const required2 = new Set(Array.isArray(schema.required) ? schema.required : []);
17458
- const compressed = {};
17459
- for (const [key, propSchema] of Object.entries(schema.properties)) {
17460
- const prop = propSchema;
17461
- let value = prop.type || "unknown";
17462
- if (prop.type === "object" && prop.properties) {
17463
- value = compressJsonSchema(prop, depth + 1);
17464
- if (required2.has(key)) {
17465
- compressed[key + " (required)"] = value;
17466
- continue;
17467
- }
17468
- } else if (prop.type === "array" && prop.items) {
17469
- if (prop.items.type === "object" && prop.items.properties) {
17470
- value = [compressJsonSchema(prop.items, depth + 1)];
17471
- } else {
17472
- value = `${prop.items.type || "any"}[]`;
17473
- }
17474
- } else if (prop.enum) {
17475
- value = prop.enum.map((v) => JSON.stringify(v)).join(" | ");
17476
- }
17477
- if (required2.has(key) && typeof value === "string") {
17478
- value += " (required)";
17479
- }
17480
- compressed[key] = value;
17481
- }
17482
- return compressed;
17483
- }
17484
17438
  function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
17485
17439
  const { keysToStrip, maxDepth, maxStringLength, maxArrayLength, maxObjectKeys } = options;
17486
17440
  const stripSet = keysToStrip instanceof Set ? keysToStrip : new Set(Array.isArray(keysToStrip) ? keysToStrip : Object.keys(keysToStrip));
@@ -17660,11 +17614,7 @@ function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
17660
17614
  looksLikeJsonSchema = false;
17661
17615
  }
17662
17616
  if (looksLikeJsonSchema) {
17663
- try {
17664
- const compressed = compressJsonSchema(val);
17665
- return compressed === val ? "[JSONSchema]" : helper(compressed, depth);
17666
- } catch {
17667
- }
17617
+ return val;
17668
17618
  }
17669
17619
  const cleaned = {};
17670
17620
  const keys = Object.keys(val).filter((key) => !stripSet.has(key));
@@ -18767,6 +18717,9 @@ function summarizeRequestBody(body) {
18767
18717
  if (Array.isArray(body.messages)) {
18768
18718
  return normalizeMessages(body.messages);
18769
18719
  }
18720
+ if (Array.isArray(body.input)) {
18721
+ return normalizeMessages(body.input);
18722
+ }
18770
18723
  if (Array.isArray(body.contents)) {
18771
18724
  return body.contents.map((item) => ({
18772
18725
  role: typeof item?.role === "string" ? item.role : "user",
@@ -19286,32 +19239,58 @@ var BaseSpan = class {
19286
19239
  parentSpanId;
19287
19240
  /** Deep clean options for serialization */
19288
19241
  deepCleanOptions;
19242
+ /**
19243
+ * Whether this span is filtered out before export. When true, BaseSpan/
19244
+ * DefaultSpan skip attaching attributes/input/output/errorInfo/requestContext
19245
+ * entirely -- they are never read on excluded spans, and skipping avoids
19246
+ * both the deepClean cost and holding references to large payloads for
19247
+ * the lifetime of the span. Set when excludeSpanTypes drops the type,
19248
+ * when the span is internal and includeInternalSpans is false, or when
19249
+ * the subclass is always excluded (e.g., NoOpSpan).
19250
+ *
19251
+ * Note: metadata is still attached and deepCleaned because it is read in
19252
+ * process by getCorrelationContext() and by getLoggerContext() /
19253
+ * getMetricsContext() (which structuredClone it).
19254
+ */
19255
+ isExcluded;
19289
19256
  /** Cached canonical correlation context for this live span */
19290
19257
  correlationContext;
19258
+ /**
19259
+ * Subclasses can override to unconditionally mark the span as excluded.
19260
+ * NoOpSpan uses this because it is never exported regardless of config.
19261
+ */
19262
+ get alwaysExcluded() {
19263
+ return false;
19264
+ }
19291
19265
  constructor(options, observabilityInstance) {
19292
- const serializationOptions = observabilityInstance.getConfig().serializationOptions;
19293
- this.deepCleanOptions = mergeSerializationOptions(serializationOptions);
19266
+ const observabilityConfig = observabilityInstance.getConfig();
19267
+ this.deepCleanOptions = mergeSerializationOptions(observabilityConfig.serializationOptions);
19294
19268
  this.name = options.name;
19295
19269
  this.type = options.type;
19296
- this.attributes = deepClean(options.attributes, this.deepCleanOptions) || {};
19270
+ this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
19271
+ this.isExcluded = this.alwaysExcluded || observabilityConfig.excludeSpanTypes?.includes(this.type) === true || this.isInternal && !observabilityConfig.includeInternalSpans;
19297
19272
  this.metadata = deepClean(
19298
19273
  options.parent?.metadata || options.metadata ? { ...options.parent?.metadata, ...options.metadata } : void 0,
19299
19274
  this.deepCleanOptions
19300
19275
  );
19301
- if (options.requestContext && options.requestContext.size() > 0) {
19302
- this.requestContext = deepClean(options.requestContext.all, this.deepCleanOptions);
19303
- }
19304
19276
  this.parent = options.parent;
19305
19277
  this.startTime = options.startTime ?? /* @__PURE__ */ new Date();
19306
19278
  this.observabilityInstance = observabilityInstance;
19307
19279
  this.isEvent = options.isEvent ?? false;
19308
- this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
19309
19280
  this.traceState = options.traceState;
19310
19281
  this.tags = !options.parent && options.tags?.length ? options.tags : void 0;
19311
19282
  const entityParent = this.getParentSpan(false);
19312
19283
  this.entityType = options.entityType ?? entityParent?.entityType;
19313
19284
  this.entityId = options.entityId ?? entityParent?.entityId;
19314
19285
  this.entityName = options.entityName ?? entityParent?.entityName;
19286
+ if (this.isExcluded) {
19287
+ this.attributes = {};
19288
+ return;
19289
+ }
19290
+ this.attributes = deepClean(options.attributes, this.deepCleanOptions) || {};
19291
+ if (options.requestContext && options.requestContext.size() > 0) {
19292
+ this.requestContext = deepClean(options.requestContext.all, this.deepCleanOptions);
19293
+ }
19315
19294
  if (this.isEvent) {
19316
19295
  this.output = deepClean(options.output, this.deepCleanOptions);
19317
19296
  } else {
@@ -19515,46 +19494,51 @@ var DefaultSpan = class extends BaseSpan {
19515
19494
  return;
19516
19495
  }
19517
19496
  this.endTime = /* @__PURE__ */ new Date();
19497
+ if (options?.metadata) {
19498
+ this.metadata = { ...this.metadata, ...deepClean(options.metadata, this.deepCleanOptions) };
19499
+ }
19500
+ if (this.isExcluded) {
19501
+ return;
19502
+ }
19518
19503
  if (options?.output !== void 0) {
19519
19504
  this.output = deepClean(options.output, this.deepCleanOptions);
19520
19505
  }
19521
19506
  if (options?.attributes) {
19522
19507
  this.attributes = { ...this.attributes, ...deepClean(options.attributes, this.deepCleanOptions) };
19523
19508
  }
19524
- if (options?.metadata) {
19525
- this.metadata = { ...this.metadata, ...deepClean(options.metadata, this.deepCleanOptions) };
19526
- }
19527
19509
  }
19528
19510
  error(options) {
19529
19511
  if (this.isEvent) {
19530
19512
  return;
19531
19513
  }
19532
19514
  const { error: error48, endSpan = true, attributes, metadata } = options;
19533
- this.errorInfo = deepClean(
19534
- error48 instanceof error$1.MastraError ? {
19535
- id: error48.id,
19536
- details: error48.details,
19537
- category: error48.category,
19538
- domain: error48.domain,
19539
- message: error48.message,
19540
- name: error48.name,
19541
- // Prefer the original cause's stack when available. MastraError wraps
19542
- // thrown errors, so its own stack points to the wrapping site rather
19543
- // than where the underlying error was thrown.
19544
- stack: error48.cause instanceof Error && error48.cause.stack || error48.stack
19545
- } : {
19546
- message: error48.message,
19547
- name: error48.name,
19548
- stack: error48.stack
19549
- },
19550
- this.deepCleanOptions
19551
- );
19552
- if (attributes) {
19553
- this.attributes = { ...this.attributes, ...deepClean(attributes, this.deepCleanOptions) };
19554
- }
19555
19515
  if (metadata) {
19556
19516
  this.metadata = { ...this.metadata, ...deepClean(metadata, this.deepCleanOptions) };
19557
19517
  }
19518
+ if (!this.isExcluded) {
19519
+ this.errorInfo = deepClean(
19520
+ error48 instanceof error$1.MastraError ? {
19521
+ id: error48.id,
19522
+ details: error48.details,
19523
+ category: error48.category,
19524
+ domain: error48.domain,
19525
+ message: error48.message,
19526
+ name: error48.name,
19527
+ // Prefer the original cause's stack when available. MastraError wraps
19528
+ // thrown errors, so its own stack points to the wrapping site rather
19529
+ // than where the underlying error was thrown.
19530
+ stack: error48.cause instanceof Error && error48.cause.stack || error48.stack
19531
+ } : {
19532
+ message: error48.message,
19533
+ name: error48.name,
19534
+ stack: error48.stack
19535
+ },
19536
+ this.deepCleanOptions
19537
+ );
19538
+ if (attributes) {
19539
+ this.attributes = { ...this.attributes, ...deepClean(attributes, this.deepCleanOptions) };
19540
+ }
19541
+ }
19558
19542
  if (endSpan) {
19559
19543
  this.end();
19560
19544
  } else {
@@ -19568,6 +19552,12 @@ var DefaultSpan = class extends BaseSpan {
19568
19552
  if (options.name !== void 0) {
19569
19553
  this.name = options.name;
19570
19554
  }
19555
+ if (options.metadata) {
19556
+ this.metadata = { ...this.metadata, ...deepClean(options.metadata, this.deepCleanOptions) };
19557
+ }
19558
+ if (this.isExcluded) {
19559
+ return;
19560
+ }
19571
19561
  if (options.input !== void 0) {
19572
19562
  this.input = deepClean(options.input, this.deepCleanOptions);
19573
19563
  }
@@ -19577,9 +19567,6 @@ var DefaultSpan = class extends BaseSpan {
19577
19567
  if (options.attributes) {
19578
19568
  this.attributes = { ...this.attributes, ...deepClean(options.attributes, this.deepCleanOptions) };
19579
19569
  }
19580
- if (options.metadata) {
19581
- this.metadata = { ...this.metadata, ...deepClean(options.metadata, this.deepCleanOptions) };
19582
- }
19583
19570
  }
19584
19571
  get isValid() {
19585
19572
  return true;
@@ -19655,6 +19642,10 @@ var NoOpSpan = class extends BaseSpan {
19655
19642
  get isValid() {
19656
19643
  return false;
19657
19644
  }
19645
+ // NoOpSpan is never exported, so treat it as always excluded.
19646
+ get alwaysExcluded() {
19647
+ return true;
19648
+ }
19658
19649
  };
19659
19650
 
19660
19651
  // src/instances/base.ts