@mastra/observability 1.17.0 → 1.17.1-alpha.0
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 +19 -0
- package/dist/exporters/mastra-platform.d.ts +2 -0
- package/dist/exporters/mastra-platform.d.ts.map +1 -1
- package/dist/index.cjs +168 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +167 -44
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/spans/base.d.ts +2 -0
- package/dist/spans/base.d.ts.map +1 -1
- package/dist/spans/default.d.ts.map +1 -1
- package/dist/spans/metadata.d.ts +22 -0
- package/dist/spans/metadata.d.ts.map +1 -0
- package/dist/spans/serialization.d.ts +0 -5
- package/dist/spans/serialization.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @mastra/observability
|
|
2
2
|
|
|
3
|
+
## 1.17.1-alpha.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fixed span serialization so internal tracing fields are removed only from framework-owned payloads while preserving user data with the same key names. ([#21332](https://github.com/mastra-ai/mastra/pull/21332))
|
|
8
|
+
|
|
9
|
+
- Advertise quota-pause support to the Mastra platform. `MastraPlatformExporter` now sends `x-mastra-observability-capabilities: quota-pause-v1` on every request (batch uploads for all five signal types, plus the traces recovery probe), letting the platform respond with `402 Payment Required` to clients that understand the quota-pause contract while shielding legacy clients from retry loops. No configuration change is required: ([#21447](https://github.com/mastra-ai/mastra/pull/21447))
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { MastraPlatformExporter } from '@mastra/observability';
|
|
13
|
+
|
|
14
|
+
const exporter = new MastraPlatformExporter({
|
|
15
|
+
accessToken: process.env.MASTRA_PLATFORM_ACCESS_TOKEN,
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [[`15101bb`](https://github.com/mastra-ai/mastra/commit/15101bb53c0d934f31af6b8813b88191e382a5e5), [`c2c3deb`](https://github.com/mastra-ai/mastra/commit/c2c3debcf670c7082d0a5e553aa99818a864698c), [`33374ba`](https://github.com/mastra-ai/mastra/commit/33374ba359e4fb13eaa918ae925fe167a3c55414), [`c5f964d`](https://github.com/mastra-ai/mastra/commit/c5f964d3f77064e978f8066ec506eed77ba5c63c), [`f8f653f`](https://github.com/mastra-ai/mastra/commit/f8f653f10980d01a73706cc3c8689ca5e40ce808)]:
|
|
20
|
+
- @mastra/core@1.60.0-alpha.1
|
|
21
|
+
|
|
3
22
|
## 1.17.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
|
@@ -14,6 +14,8 @@ export interface MastraPlatformExporterConfig extends BaseExporterConfig {
|
|
|
14
14
|
scoresEndpoint?: string;
|
|
15
15
|
feedbackEndpoint?: string;
|
|
16
16
|
}
|
|
17
|
+
export declare const OBSERVABILITY_CAPABILITIES_HEADER = "x-mastra-observability-capabilities";
|
|
18
|
+
export declare const QUOTA_PAUSE_CAPABILITY = "quota-pause-v1";
|
|
17
19
|
export declare class MastraPlatformExporter extends BaseExporter {
|
|
18
20
|
name: string;
|
|
19
21
|
private readonly platformConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mastra-platform.d.ts","sourceRoot":"","sources":["../../src/exporters/mastra-platform.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,MAAM,WAAW,4BAA6B,SAAQ,kBAAkB;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,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;
|
|
1
|
+
{"version":3,"file":"mastra-platform.d.ts","sourceRoot":"","sources":["../../src/exporters/mastra-platform.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,MAAM,WAAW,4BAA6B,SAAQ,kBAAkB;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,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;AAyBD,eAAO,MAAM,iCAAiC,wCAAwC,CAAC;AACvF,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AA6MvD,qBAAa,sBAAuB,SAAQ,YAAY;IACtD,IAAI,SAA8B;IAElC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmC;IAClE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAA4B;IACnD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,yBAAyB,CAAwC;IACzE,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,GAAE,4BAAiC;cAyErC,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjE,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1C,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAahD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9C,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1D,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;IAenB,OAAO,CAAC,aAAa;YAoBP,WAAW;IA4EzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,gBAAgB;YAIV,WAAW;IAoDzB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,kBAAkB;IAkB1B;;;;;OAKG;YACW,gBAAgB;YAoDhB,gBAAgB;IAmC9B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAsChC"}
|
package/dist/index.cjs
CHANGED
|
@@ -210,21 +210,15 @@ var BaseObservabilityEventBus = class BaseObservabilityEventBus extends _mastra_
|
|
|
210
210
|
* }
|
|
211
211
|
* ```
|
|
212
212
|
*/
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"
|
|
219
|
-
|
|
220
|
-
"providerMetadata",
|
|
221
|
-
"steps",
|
|
222
|
-
"tracingContext",
|
|
223
|
-
"execute",
|
|
224
|
-
"validate"
|
|
225
|
-
]);
|
|
213
|
+
const FUNCTION_KEYS_TO_STRIP = /* @__PURE__ */ new Set(["execute", "validate"]);
|
|
214
|
+
const LOGGER_METHODS = [
|
|
215
|
+
"debug",
|
|
216
|
+
"info",
|
|
217
|
+
"warn",
|
|
218
|
+
"error"
|
|
219
|
+
];
|
|
226
220
|
const DEFAULT_DEEP_CLEAN_OPTIONS = Object.freeze({
|
|
227
|
-
keysToStrip:
|
|
221
|
+
keysToStrip: [],
|
|
228
222
|
maxDepth: 8,
|
|
229
223
|
maxStringLength: 128 * 1024,
|
|
230
224
|
maxArrayLength: 50,
|
|
@@ -237,7 +231,7 @@ const DEFAULT_DEEP_CLEAN_OPTIONS = Object.freeze({
|
|
|
237
231
|
function mergeSerializationOptions(userOptions) {
|
|
238
232
|
if (!userOptions) return DEFAULT_DEEP_CLEAN_OPTIONS;
|
|
239
233
|
return {
|
|
240
|
-
keysToStrip:
|
|
234
|
+
keysToStrip: DEFAULT_DEEP_CLEAN_OPTIONS.keysToStrip,
|
|
241
235
|
maxDepth: userOptions.maxDepth ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxDepth,
|
|
242
236
|
maxStringLength: userOptions.maxStringLength ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxStringLength,
|
|
243
237
|
maxArrayLength: userOptions.maxArrayLength ?? DEFAULT_DEEP_CLEAN_OPTIONS.maxArrayLength,
|
|
@@ -263,6 +257,47 @@ function getMapKeyType(key) {
|
|
|
263
257
|
if (key instanceof Error) return "error";
|
|
264
258
|
return typeof key;
|
|
265
259
|
}
|
|
260
|
+
function hasOnlyKnownKeys(value, keys) {
|
|
261
|
+
try {
|
|
262
|
+
return Object.keys(value).every((key) => keys.includes(key));
|
|
263
|
+
} catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function isSpanLike(value) {
|
|
268
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
269
|
+
const span = value;
|
|
270
|
+
try {
|
|
271
|
+
return typeof span.id === "string" && typeof span.traceId === "string" && typeof span.type === "string" && typeof span.name === "string";
|
|
272
|
+
} catch {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function isTracingContextLike(value) {
|
|
277
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
278
|
+
const context = value;
|
|
279
|
+
if (!hasOnlyKnownKeys(context, ["currentSpan"])) return false;
|
|
280
|
+
try {
|
|
281
|
+
return context.currentSpan === void 0 || isSpanLike(context.currentSpan);
|
|
282
|
+
} catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function isLoggerLike(value) {
|
|
287
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
288
|
+
const logger = value;
|
|
289
|
+
try {
|
|
290
|
+
return LOGGER_METHODS.some((method) => typeof logger[method] === "function");
|
|
291
|
+
} catch {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function shouldStripEntry(key, value, stripSet) {
|
|
296
|
+
if (stripSet.has(key)) return true;
|
|
297
|
+
if (key === "tracingContext" && isTracingContextLike(value)) return true;
|
|
298
|
+
if (key === "logger") return typeof value === "function" || isLoggerLike(value);
|
|
299
|
+
return FUNCTION_KEYS_TO_STRIP.has(key) && typeof value === "function";
|
|
300
|
+
}
|
|
266
301
|
function restoreSerializedMapKey(keyType, key) {
|
|
267
302
|
switch (keyType) {
|
|
268
303
|
case "undefined": return;
|
|
@@ -365,7 +400,7 @@ function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
|
|
|
365
400
|
let mapKeyCount = 0;
|
|
366
401
|
let omittedMapEntries = 0;
|
|
367
402
|
for (const [mapKey, mapVal] of val) {
|
|
368
|
-
if (typeof mapKey === "string" &&
|
|
403
|
+
if (typeof mapKey === "string" && shouldStripEntry(mapKey, mapVal, stripSet)) continue;
|
|
369
404
|
if (mapKeyCount >= maxObjectKeys) {
|
|
370
405
|
omittedMapEntries++;
|
|
371
406
|
continue;
|
|
@@ -441,15 +476,34 @@ function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
|
|
|
441
476
|
}
|
|
442
477
|
if (looksLikeJsonSchema) return val;
|
|
443
478
|
const cleaned = {};
|
|
444
|
-
|
|
479
|
+
let keys;
|
|
480
|
+
try {
|
|
481
|
+
keys = Object.keys(val);
|
|
482
|
+
} catch (error) {
|
|
483
|
+
return formatSerializationError(error);
|
|
484
|
+
}
|
|
445
485
|
let keyCount = 0;
|
|
446
486
|
for (const key of keys) {
|
|
487
|
+
if (stripSet.has(key)) continue;
|
|
488
|
+
let rawValue;
|
|
489
|
+
try {
|
|
490
|
+
rawValue = val[key];
|
|
491
|
+
} catch (error) {
|
|
492
|
+
if (keyCount >= maxObjectKeys) {
|
|
493
|
+
cleaned["__truncated"] = `${keys.length - keyCount} more keys omitted`;
|
|
494
|
+
break;
|
|
495
|
+
}
|
|
496
|
+
cleaned[key] = formatSerializationError(error);
|
|
497
|
+
keyCount++;
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (shouldStripEntry(key, rawValue, stripSet)) continue;
|
|
447
501
|
if (keyCount >= maxObjectKeys) {
|
|
448
502
|
cleaned["__truncated"] = `${keys.length - keyCount} more keys omitted`;
|
|
449
503
|
break;
|
|
450
504
|
}
|
|
451
505
|
try {
|
|
452
|
-
cleaned[key] = helper(
|
|
506
|
+
cleaned[key] = helper(rawValue, depth + 1);
|
|
453
507
|
keyCount++;
|
|
454
508
|
} catch (error) {
|
|
455
509
|
cleaned[key] = formatSerializationError(error);
|
|
@@ -2462,6 +2516,49 @@ var ModelSpanTracker = class {
|
|
|
2462
2516
|
}
|
|
2463
2517
|
};
|
|
2464
2518
|
//#endregion
|
|
2519
|
+
//#region src/spans/metadata.ts
|
|
2520
|
+
/**
|
|
2521
|
+
* Shared span-metadata helpers.
|
|
2522
|
+
*
|
|
2523
|
+
* Used by both the observability instance (`instances/base.ts`) and the span
|
|
2524
|
+
* base class (`spans/base.ts`) so the plain-record check and the
|
|
2525
|
+
* descriptor-preserving merge stay in a single place. Both feed the same span
|
|
2526
|
+
* metadata pipeline, so keeping one implementation avoids divergence.
|
|
2527
|
+
*/
|
|
2528
|
+
/**
|
|
2529
|
+
* Returns true only for plain object records (prototype is `Object.prototype`
|
|
2530
|
+
* or `null`). Maps, Dates, class instances, and arrays return false so callers
|
|
2531
|
+
* can preserve their original shape instead of shallow-copying them into `{}`.
|
|
2532
|
+
*/
|
|
2533
|
+
function isPlainRecord(value) {
|
|
2534
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
2535
|
+
try {
|
|
2536
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2537
|
+
return prototype === Object.prototype || prototype === null;
|
|
2538
|
+
} catch {
|
|
2539
|
+
return false;
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
/**
|
|
2543
|
+
* Merges two metadata values while preserving property descriptors (so getters
|
|
2544
|
+
* are copied as accessors rather than eagerly invoked). Only plain records are
|
|
2545
|
+
* merged; if either side is non-plain the second argument is returned as-is,
|
|
2546
|
+
* matching the previous per-module behavior.
|
|
2547
|
+
*/
|
|
2548
|
+
function mergeMetadata$1(parentMetadata, metadata) {
|
|
2549
|
+
if (!parentMetadata) return metadata;
|
|
2550
|
+
if (!metadata) return parentMetadata;
|
|
2551
|
+
if (!isPlainRecord(parentMetadata) || !isPlainRecord(metadata)) return metadata;
|
|
2552
|
+
try {
|
|
2553
|
+
const merged = {};
|
|
2554
|
+
Object.defineProperties(merged, Object.getOwnPropertyDescriptors(parentMetadata));
|
|
2555
|
+
Object.defineProperties(merged, Object.getOwnPropertyDescriptors(metadata));
|
|
2556
|
+
return merged;
|
|
2557
|
+
} catch {
|
|
2558
|
+
return metadata;
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
//#endregion
|
|
2465
2562
|
//#region src/spans/base.ts
|
|
2466
2563
|
/**
|
|
2467
2564
|
* Determines if a span type should be considered internal based on flags.
|
|
@@ -2586,10 +2683,7 @@ var BaseSpan = class {
|
|
|
2586
2683
|
this.type = options.type;
|
|
2587
2684
|
this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
|
|
2588
2685
|
this.isExcluded = this.alwaysExcluded || observabilityConfig.excludeSpanTypes?.includes(this.type) === true || this.isInternal && !observabilityConfig.includeInternalSpans;
|
|
2589
|
-
this.metadata = deepClean(options.parent?.metadata
|
|
2590
|
-
...options.parent?.metadata,
|
|
2591
|
-
...options.metadata
|
|
2592
|
-
} : void 0, this.deepCleanOptions);
|
|
2686
|
+
this.metadata = deepClean(this.prepareSpanMetadata(mergeMetadata$1(options.parent?.metadata, options.metadata)), this.deepCleanOptions);
|
|
2593
2687
|
this.parent = options.parent;
|
|
2594
2688
|
this.startTime = options.startTime ?? /* @__PURE__ */ new Date();
|
|
2595
2689
|
this.observabilityInstance = observabilityInstance;
|
|
@@ -2607,9 +2701,32 @@ var BaseSpan = class {
|
|
|
2607
2701
|
}
|
|
2608
2702
|
this.attributes = deepClean(options.attributes, this.deepCleanOptions) || {};
|
|
2609
2703
|
if (options.requestContext && options.requestContext.size() > 0) this.requestContext = deepClean(options.requestContext, this.deepCleanOptions);
|
|
2610
|
-
if (this.isEvent) this.output = deepClean(options.output, this.deepCleanOptions);
|
|
2704
|
+
if (this.isEvent) this.output = deepClean(this.prepareSpanOutput(options.output), this.deepCleanOptions);
|
|
2611
2705
|
else this.input = deepClean(options.input, this.deepCleanOptions);
|
|
2612
2706
|
}
|
|
2707
|
+
prepareSpanOutput(value) {
|
|
2708
|
+
if (!isPlainRecord(value)) return value;
|
|
2709
|
+
if (this.type !== _mastra_core_observability.SpanType.MODEL_STEP && this.type !== _mastra_core_observability.SpanType.MODEL_INFERENCE) return value;
|
|
2710
|
+
try {
|
|
2711
|
+
const prepared = { ...value };
|
|
2712
|
+
delete prepared.steps;
|
|
2713
|
+
return prepared;
|
|
2714
|
+
} catch {
|
|
2715
|
+
return value;
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
prepareSpanMetadata(value) {
|
|
2719
|
+
if (!isPlainRecord(value)) return value;
|
|
2720
|
+
if (this.type !== _mastra_core_observability.SpanType.MODEL_STEP) return value;
|
|
2721
|
+
try {
|
|
2722
|
+
const prepared = { ...value };
|
|
2723
|
+
delete prepared.providerMetadata;
|
|
2724
|
+
delete prepared.experimental_providerMetadata;
|
|
2725
|
+
return prepared;
|
|
2726
|
+
} catch {
|
|
2727
|
+
return value;
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2613
2730
|
createChildSpan(options) {
|
|
2614
2731
|
return this.observabilityInstance.startSpan({
|
|
2615
2732
|
...options,
|
|
@@ -2816,10 +2933,10 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
2816
2933
|
this.endTime = /* @__PURE__ */ new Date();
|
|
2817
2934
|
if (options?.metadata) this.metadata = {
|
|
2818
2935
|
...this.metadata,
|
|
2819
|
-
...deepClean(options.metadata, this.deepCleanOptions)
|
|
2936
|
+
...deepClean(this.prepareSpanMetadata(options.metadata), this.deepCleanOptions)
|
|
2820
2937
|
};
|
|
2821
2938
|
if (this.isExcluded) return;
|
|
2822
|
-
if (options?.output !== void 0) this.output = deepClean(options.output, this.deepCleanOptions);
|
|
2939
|
+
if (options?.output !== void 0) this.output = deepClean(this.prepareSpanOutput(options.output), this.deepCleanOptions);
|
|
2823
2940
|
if (options?.attributes) this.attributes = {
|
|
2824
2941
|
...this.attributes,
|
|
2825
2942
|
...deepClean(options.attributes, this.deepCleanOptions)
|
|
@@ -2830,7 +2947,7 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
2830
2947
|
const { error, endSpan = true, attributes, metadata } = options;
|
|
2831
2948
|
if (metadata) this.metadata = {
|
|
2832
2949
|
...this.metadata,
|
|
2833
|
-
...deepClean(metadata, this.deepCleanOptions)
|
|
2950
|
+
...deepClean(this.prepareSpanMetadata(metadata), this.deepCleanOptions)
|
|
2834
2951
|
};
|
|
2835
2952
|
if (!this.isExcluded) {
|
|
2836
2953
|
this.errorInfo = deepClean(error instanceof _mastra_core_error.MastraError ? {
|
|
@@ -2859,11 +2976,11 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
2859
2976
|
if (options.name !== void 0) this.name = options.name;
|
|
2860
2977
|
if (options.metadata) this.metadata = {
|
|
2861
2978
|
...this.metadata,
|
|
2862
|
-
...deepClean(options.metadata, this.deepCleanOptions)
|
|
2979
|
+
...deepClean(this.prepareSpanMetadata(options.metadata), this.deepCleanOptions)
|
|
2863
2980
|
};
|
|
2864
2981
|
if (this.isExcluded) return;
|
|
2865
2982
|
if (options.input !== void 0) this.input = deepClean(options.input, this.deepCleanOptions);
|
|
2866
|
-
if (options.output !== void 0) this.output = deepClean(options.output, this.deepCleanOptions);
|
|
2983
|
+
if (options.output !== void 0) this.output = deepClean(this.prepareSpanOutput(options.output), this.deepCleanOptions);
|
|
2867
2984
|
if (options.attributes) this.attributes = {
|
|
2868
2985
|
...this.attributes,
|
|
2869
2986
|
...deepClean(options.attributes, this.deepCleanOptions)
|
|
@@ -2951,6 +3068,19 @@ var NoOpSpan = class extends BaseSpan {
|
|
|
2951
3068
|
/**
|
|
2952
3069
|
* BaseObservability - Abstract base class for Observability implementations
|
|
2953
3070
|
*/
|
|
3071
|
+
function hasMetadataKey(metadata, key) {
|
|
3072
|
+
if (!metadata || typeof metadata !== "object") return false;
|
|
3073
|
+
try {
|
|
3074
|
+
return Object.prototype.hasOwnProperty.call(Object.getOwnPropertyDescriptors(metadata), key);
|
|
3075
|
+
} catch {
|
|
3076
|
+
return true;
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
function injectEnvironmentMetadata(metadata, environment) {
|
|
3080
|
+
if (environment === void 0 || hasMetadataKey(metadata, "environment")) return metadata;
|
|
3081
|
+
if (metadata && !isPlainRecord(metadata)) return metadata;
|
|
3082
|
+
return mergeMetadata$1(metadata, { environment });
|
|
3083
|
+
}
|
|
2954
3084
|
/**
|
|
2955
3085
|
* Abstract base class for all Observability implementations in Mastra.
|
|
2956
3086
|
*/
|
|
@@ -3046,16 +3176,9 @@ var BaseObservabilityInstance = class extends _mastra_core_base.MastraBase {
|
|
|
3046
3176
|
let traceState;
|
|
3047
3177
|
if (options.parent) traceState = options.parent.traceState;
|
|
3048
3178
|
else traceState = this.computeTraceState(tracingOptions);
|
|
3049
|
-
const
|
|
3050
|
-
const mergedMetadata = metadata || tracingMetadata ? {
|
|
3051
|
-
...metadata,
|
|
3052
|
-
...tracingMetadata
|
|
3053
|
-
} : void 0;
|
|
3179
|
+
const mergedMetadata = mergeMetadata$1(metadata, !options.parent ? tracingOptions?.metadata : void 0);
|
|
3054
3180
|
const enrichedMetadata = this.extractMetadataFromRequestContext(requestContext, mergedMetadata, traceState);
|
|
3055
|
-
const finalMetadata = !options.parent
|
|
3056
|
-
...enrichedMetadata ?? {},
|
|
3057
|
-
environment: this.#mastraEnvironment
|
|
3058
|
-
} : enrichedMetadata;
|
|
3181
|
+
const finalMetadata = !options.parent ? injectEnvironmentMetadata(enrichedMetadata, this.#mastraEnvironment) : enrichedMetadata;
|
|
3059
3182
|
const tags = !options.parent ? tracingOptions?.tags : void 0;
|
|
3060
3183
|
const traceId = !options.parent ? options.traceId ?? tracingOptions?.traceId : options.traceId;
|
|
3061
3184
|
const parentSpanId = options.parentSpanId;
|
|
@@ -3320,10 +3443,7 @@ var BaseObservabilityInstance = class extends _mastra_core_base.MastraBase {
|
|
|
3320
3443
|
if (!requestContext || !traceState || traceState.requestContextKeys.length === 0) return explicitMetadata;
|
|
3321
3444
|
const extracted = this.extractKeys(requestContext, traceState.requestContextKeys);
|
|
3322
3445
|
if (Object.keys(extracted).length === 0 && !explicitMetadata) return;
|
|
3323
|
-
return
|
|
3324
|
-
...extracted,
|
|
3325
|
-
...explicitMetadata
|
|
3326
|
-
};
|
|
3446
|
+
return mergeMetadata$1(extracted, explicitMetadata);
|
|
3327
3447
|
}
|
|
3328
3448
|
/**
|
|
3329
3449
|
* Extract specific keys from RequestContext
|
|
@@ -6370,6 +6490,8 @@ const QUOTA_EXCEEDED_STATUS = 402;
|
|
|
6370
6490
|
const OBSERVABILITY_STATUS_HEADER = "x-mastra-observability";
|
|
6371
6491
|
const OBSERVABILITY_DISABLED_VALUE = "disabled";
|
|
6372
6492
|
const OBSERVABILITY_RETRY_AFTER_HEADER = "x-mastra-observability-retry-after";
|
|
6493
|
+
const OBSERVABILITY_CAPABILITIES_HEADER = "x-mastra-observability-capabilities";
|
|
6494
|
+
const QUOTA_PAUSE_CAPABILITY = "quota-pause-v1";
|
|
6373
6495
|
const DEFAULT_QUOTA_PROBE_INTERVAL_SECONDS = 300;
|
|
6374
6496
|
const MAX_QUOTA_PROBE_INTERVAL_SECONDS = Math.floor(2147483647 / 1e3);
|
|
6375
6497
|
function isObservabilityDisabled(response) {
|
|
@@ -6696,7 +6818,8 @@ var MastraPlatformExporter = class extends BaseExporter {
|
|
|
6696
6818
|
buildPublishHeaders() {
|
|
6697
6819
|
return {
|
|
6698
6820
|
Authorization: `Bearer ${this.platformConfig.accessToken}`,
|
|
6699
|
-
"Content-Type": "application/json"
|
|
6821
|
+
"Content-Type": "application/json",
|
|
6822
|
+
[OBSERVABILITY_CAPABILITIES_HEADER]: QUOTA_PAUSE_CAPABILITY
|
|
6700
6823
|
};
|
|
6701
6824
|
}
|
|
6702
6825
|
buildPublishBody(signal, records) {
|
|
@@ -6749,7 +6872,7 @@ var MastraPlatformExporter = class extends BaseExporter {
|
|
|
6749
6872
|
this.flushTimer = null;
|
|
6750
6873
|
}
|
|
6751
6874
|
this.resetBuffer();
|
|
6752
|
-
this.logger.warn(`Mastra observability paused: quota exhausted
|
|
6875
|
+
this.logger.warn(`Mastra observability export paused: platform quota exhausted (OBSERVABILITY_QUOTA_EXCEEDED). Dropping telemetry and retrying in ${retryAfterSeconds} seconds. Check Platform billing/usage to restore telemetry.`);
|
|
6753
6876
|
this.scheduleQuotaProbe();
|
|
6754
6877
|
}
|
|
6755
6878
|
scheduleQuotaProbe() {
|
|
@@ -9332,7 +9455,6 @@ exports.CardinalityFilter = CardinalityFilter;
|
|
|
9332
9455
|
exports.CloudExporter = CloudExporter;
|
|
9333
9456
|
exports.ConsoleExporter = ConsoleExporter;
|
|
9334
9457
|
exports.DEFAULT_DEEP_CLEAN_OPTIONS = DEFAULT_DEEP_CLEAN_OPTIONS;
|
|
9335
|
-
exports.DEFAULT_KEYS_TO_STRIP = DEFAULT_KEYS_TO_STRIP;
|
|
9336
9458
|
exports.DEFAULT_LIMITS = DEFAULT_LIMITS;
|
|
9337
9459
|
exports.DefaultExporter = DefaultExporter;
|
|
9338
9460
|
exports.DefaultObservabilityInstance = DefaultObservabilityInstance;
|
|
@@ -9344,8 +9466,10 @@ exports.MastraStorageExporter = MastraStorageExporter;
|
|
|
9344
9466
|
exports.MetricsContextImpl = MetricsContextImpl;
|
|
9345
9467
|
exports.ModelSpanTracker = ModelSpanTracker;
|
|
9346
9468
|
exports.NoOpSpan = NoOpSpan;
|
|
9469
|
+
exports.OBSERVABILITY_CAPABILITIES_HEADER = OBSERVABILITY_CAPABILITIES_HEADER;
|
|
9347
9470
|
exports.Observability = Observability;
|
|
9348
9471
|
exports.ObservabilityBus = ObservabilityBus;
|
|
9472
|
+
exports.QUOTA_PAUSE_CAPABILITY = QUOTA_PAUSE_CAPABILITY;
|
|
9349
9473
|
exports.SamplingStrategyType = SamplingStrategyType;
|
|
9350
9474
|
exports.SensitiveDataFilter = SensitiveDataFilter;
|
|
9351
9475
|
exports.TestExporter = TestExporter;
|