@mastra/observability 1.21.1-alpha.1 → 1.22.0-alpha.3
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/dist/exporters/event-buffer.d.ts +5 -0
- package/dist/exporters/event-buffer.d.ts.map +1 -1
- package/dist/exporters/mastra-platform.d.ts.map +1 -1
- package/dist/exporters/mastra-storage.d.ts +14 -1
- package/dist/exporters/mastra-storage.d.ts.map +1 -1
- package/dist/exporters/span-previews.d.ts +4 -0
- package/dist/exporters/span-previews.d.ts.map +1 -0
- package/dist/exporters/test.d.ts.map +1 -1
- package/dist/index.cjs +169 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +168 -111
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/metrics/pricing-data.json +1529 -598
- package/dist/model-tracing.d.ts +5 -0
- package/dist/model-tracing.d.ts.map +1 -1
- package/dist/spans/base.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
2
|
+
// \0rolldown/runtime.js
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -20,11 +20,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
20
20
|
value: mod,
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
|
-
//#endregion
|
|
24
23
|
let _mastra_core_base = require("@mastra/core/base");
|
|
25
24
|
let _mastra_core_error = require("@mastra/core/error");
|
|
26
25
|
let _mastra_core_logger = require("@mastra/core/logger");
|
|
27
26
|
let _mastra_core_observability = require("@mastra/core/observability");
|
|
27
|
+
_mastra_core_observability = __toESM(_mastra_core_observability, 1);
|
|
28
28
|
let _mastra_core_utils = require("@mastra/core/utils");
|
|
29
29
|
let zod_v4 = require("zod/v4");
|
|
30
30
|
let fs = require("fs");
|
|
@@ -38,7 +38,7 @@ let stream_web = require("stream/web");
|
|
|
38
38
|
let _mastra_core_features = require("@mastra/core/features");
|
|
39
39
|
let _mastra_core_storage = require("@mastra/core/storage");
|
|
40
40
|
let crypto$1 = require("crypto");
|
|
41
|
-
|
|
41
|
+
// src/bus/route-event.ts
|
|
42
42
|
/**
|
|
43
43
|
* Route a single event to the appropriate method on a handler.
|
|
44
44
|
*
|
|
@@ -105,8 +105,7 @@ function catchAsyncResult(result, handlerName, signal, logger) {
|
|
|
105
105
|
logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
|
-
|
|
109
|
-
//#region src/bus/base.ts
|
|
108
|
+
// src/bus/base.ts
|
|
110
109
|
/**
|
|
111
110
|
* BaseObservabilityEventBus - Generic event bus for observability events.
|
|
112
111
|
*
|
|
@@ -181,8 +180,7 @@ var BaseObservabilityEventBus = class BaseObservabilityEventBus extends _mastra_
|
|
|
181
180
|
this.subscribers.clear();
|
|
182
181
|
}
|
|
183
182
|
};
|
|
184
|
-
|
|
185
|
-
//#region src/spans/serialization.ts
|
|
183
|
+
// src/spans/serialization.ts
|
|
186
184
|
/**
|
|
187
185
|
* Bounded serialization utilities for AI tracing.
|
|
188
186
|
*
|
|
@@ -548,8 +546,7 @@ function deepClean(value, options = DEFAULT_DEEP_CLEAN_OPTIONS) {
|
|
|
548
546
|
}
|
|
549
547
|
return helper(value, 0);
|
|
550
548
|
}
|
|
551
|
-
|
|
552
|
-
//#region src/bus/observability-bus.ts
|
|
549
|
+
// src/bus/observability-bus.ts
|
|
553
550
|
/**
|
|
554
551
|
* Apply deepClean() to non-tracing observability events. Tracing events are
|
|
555
552
|
* already deep-cleaned at span construction time (see spans/base.ts and
|
|
@@ -758,8 +755,7 @@ var ObservabilityBus = class extends BaseObservabilityEventBus {
|
|
|
758
755
|
await super.shutdown();
|
|
759
756
|
}
|
|
760
757
|
};
|
|
761
|
-
|
|
762
|
-
//#region src/config.ts
|
|
758
|
+
// src/config.ts
|
|
763
759
|
/**
|
|
764
760
|
* Sampling strategy types
|
|
765
761
|
*/
|
|
@@ -886,8 +882,7 @@ const observabilityRegistryConfigSchema = zod_v4.z.object({
|
|
|
886
882
|
}
|
|
887
883
|
return true;
|
|
888
884
|
}, { message: "A \"configSelector\" requires at least one config or default observability to be configured." });
|
|
889
|
-
|
|
890
|
-
//#region src/ids.ts
|
|
885
|
+
// src/ids.ts
|
|
891
886
|
/**
|
|
892
887
|
* Signal and span id helpers.
|
|
893
888
|
*
|
|
@@ -955,8 +950,7 @@ function resolveExportedSpanId(span) {
|
|
|
955
950
|
if (!span) return void 0;
|
|
956
951
|
return typeof span.getExportedSpanId === "function" ? span.getExportedSpanId() : span.id;
|
|
957
952
|
}
|
|
958
|
-
|
|
959
|
-
//#region src/context/logger.ts
|
|
953
|
+
// src/context/logger.ts
|
|
960
954
|
/** Numeric priority used to compare log levels against the configured minimum. */
|
|
961
955
|
const LOG_LEVEL_PRIORITY = {
|
|
962
956
|
debug: 0,
|
|
@@ -1024,8 +1018,7 @@ var LoggerContextImpl = class {
|
|
|
1024
1018
|
this.config.observabilityBus.emit(event);
|
|
1025
1019
|
}
|
|
1026
1020
|
};
|
|
1027
|
-
|
|
1028
|
-
//#region src/context/metrics.ts
|
|
1021
|
+
// src/context/metrics.ts
|
|
1029
1022
|
/**
|
|
1030
1023
|
* User-facing metric emission API. All metrics are routed through
|
|
1031
1024
|
* ObservabilityBus.emit() after validation and cardinality filtering.
|
|
@@ -1100,14 +1093,12 @@ function cloneCostContext(costContext) {
|
|
|
1100
1093
|
costMetadata: costContext.costMetadata ? structuredClone(costContext.costMetadata) : void 0
|
|
1101
1094
|
};
|
|
1102
1095
|
}
|
|
1103
|
-
|
|
1104
|
-
//#region src/model-id.ts
|
|
1096
|
+
// src/model-id.ts
|
|
1105
1097
|
/** Return the first model id that contains non-whitespace characters. */
|
|
1106
1098
|
function resolveModelId(...candidates) {
|
|
1107
1099
|
return candidates.find((candidate) => candidate?.trim());
|
|
1108
1100
|
}
|
|
1109
|
-
|
|
1110
|
-
//#region src/metrics/pricing-model.ts
|
|
1101
|
+
// src/metrics/pricing-model.ts
|
|
1111
1102
|
var PricingTier = class {
|
|
1112
1103
|
index;
|
|
1113
1104
|
when;
|
|
@@ -1165,8 +1156,7 @@ var PricingModel = class {
|
|
|
1165
1156
|
return this.tiers[0] ?? null;
|
|
1166
1157
|
}
|
|
1167
1158
|
};
|
|
1168
|
-
|
|
1169
|
-
//#region src/metrics/models-dev.ts
|
|
1159
|
+
// src/metrics/models-dev.ts
|
|
1170
1160
|
/** Same catalog the model router reads in `@mastra/core` (`gateways/models-dev.ts`). */
|
|
1171
1161
|
const MODELS_DEV_API_URL = "https://models.dev/api.json";
|
|
1172
1162
|
/**
|
|
@@ -1297,8 +1287,7 @@ function sortedEntries(value) {
|
|
|
1297
1287
|
function isRecord(value) {
|
|
1298
1288
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1299
1289
|
}
|
|
1300
|
-
|
|
1301
|
-
//#region src/metrics/pricing-registry.ts
|
|
1290
|
+
// src/metrics/pricing-registry.ts
|
|
1302
1291
|
const DATA_FILE_NAME = "pricing-data.json";
|
|
1303
1292
|
const REFRESH_INTERVAL_MS = 864e5;
|
|
1304
1293
|
const MIN_REFRESH_ATTEMPT_INTERVAL_MS = 36e5;
|
|
@@ -1649,8 +1638,7 @@ function stripDateSuffix(model) {
|
|
|
1649
1638
|
stripped = model.replace(/-\d{2}-20\d{2}$/, "");
|
|
1650
1639
|
return stripped;
|
|
1651
1640
|
}
|
|
1652
|
-
|
|
1653
|
-
//#region src/metrics/types.ts
|
|
1641
|
+
// src/metrics/types.ts
|
|
1654
1642
|
const PricingMeter = {
|
|
1655
1643
|
INPUT_TOKENS: "input_tokens",
|
|
1656
1644
|
INPUT_AUDIO_TOKENS: "input_audio_tokens",
|
|
@@ -1686,8 +1674,7 @@ const TokenMetrics = {
|
|
|
1686
1674
|
OUTPUT_AUDIO: "mastra_model_output_audio_tokens",
|
|
1687
1675
|
OUTPUT_IMAGE: "mastra_model_output_image_tokens"
|
|
1688
1676
|
};
|
|
1689
|
-
|
|
1690
|
-
//#region src/metrics/usage-metrics.ts
|
|
1677
|
+
// src/metrics/usage-metrics.ts
|
|
1691
1678
|
function getTokenMetricSamples(usage) {
|
|
1692
1679
|
const samples = [];
|
|
1693
1680
|
const pushIfDefined = (name, value) => {
|
|
@@ -1721,8 +1708,7 @@ function getTokenMetricSamples(usage) {
|
|
|
1721
1708
|
}
|
|
1722
1709
|
return samples;
|
|
1723
1710
|
}
|
|
1724
|
-
|
|
1725
|
-
//#region src/metrics/estimator.ts
|
|
1711
|
+
// src/metrics/estimator.ts
|
|
1726
1712
|
function estimateCosts(args, pricingRegistry = PricingRegistry.getGlobal()) {
|
|
1727
1713
|
const { provider, model, usage } = args;
|
|
1728
1714
|
const results = /* @__PURE__ */ new Map();
|
|
@@ -1954,8 +1940,7 @@ function estimateCostForMeter(args) {
|
|
|
1954
1940
|
}
|
|
1955
1941
|
};
|
|
1956
1942
|
}
|
|
1957
|
-
|
|
1958
|
-
//#region src/metrics/auto-extract.ts
|
|
1943
|
+
// src/metrics/auto-extract.ts
|
|
1959
1944
|
/**
|
|
1960
1945
|
* Emits metrics derived from live spans.
|
|
1961
1946
|
*/
|
|
@@ -2109,8 +2094,7 @@ function getDurationMetricName(span) {
|
|
|
2109
2094
|
default: return null;
|
|
2110
2095
|
}
|
|
2111
2096
|
}
|
|
2112
|
-
|
|
2113
|
-
//#region src/metrics/cardinality.ts
|
|
2097
|
+
// src/metrics/cardinality.ts
|
|
2114
2098
|
/** Matches standard UUID v4 strings (case-insensitive). */
|
|
2115
2099
|
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2116
2100
|
var CardinalityFilter = class {
|
|
@@ -2141,8 +2125,7 @@ var CardinalityFilter = class {
|
|
|
2141
2125
|
return filtered;
|
|
2142
2126
|
}
|
|
2143
2127
|
};
|
|
2144
|
-
|
|
2145
|
-
//#region src/usage.ts
|
|
2128
|
+
// src/usage.ts
|
|
2146
2129
|
/**
|
|
2147
2130
|
* For non-BYOK requests, `usage.cost` is the complete OpenRouter charge and
|
|
2148
2131
|
* `usage.costDetails.upstreamInferenceCost` is only its upstream breakdown. For BYOK requests,
|
|
@@ -2327,8 +2310,7 @@ function addUsageStats(a, b) {
|
|
|
2327
2310
|
outputDetails: mergeOutputDetails(a.outputDetails, b.outputDetails)
|
|
2328
2311
|
};
|
|
2329
2312
|
}
|
|
2330
|
-
|
|
2331
|
-
//#region src/model-tracing.ts
|
|
2313
|
+
// src/model-tracing.ts
|
|
2332
2314
|
/**
|
|
2333
2315
|
* Model Span Tracing
|
|
2334
2316
|
*
|
|
@@ -2756,8 +2738,20 @@ var ModelSpanTracker = class {
|
|
|
2756
2738
|
* feature flag, or when called without an active step span. Auto-invoked from
|
|
2757
2739
|
* chunk handlers as a safety net; explicit callers get the most accurate
|
|
2758
2740
|
* start time.
|
|
2741
|
+
*
|
|
2742
|
+
* `payload.modelId` / `payload.provider` name the model the caller is about
|
|
2743
|
+
* to invoke and are recorded on MODEL_STEP, also when a fallback attempt
|
|
2744
|
+
* reuses the step's open inference span. The safety net never records them:
|
|
2745
|
+
* a replayed step-start chunk names the model of the original call.
|
|
2759
2746
|
*/
|
|
2760
2747
|
startInference(payload) {
|
|
2748
|
+
if (payload?.modelId && payload.provider) this.#currentStepSpan?.update({ attributes: {
|
|
2749
|
+
model: payload.modelId,
|
|
2750
|
+
provider: payload.provider
|
|
2751
|
+
} });
|
|
2752
|
+
this.#openInference(payload);
|
|
2753
|
+
}
|
|
2754
|
+
#openInference(payload) {
|
|
2761
2755
|
if (!supportsModelInference()) return;
|
|
2762
2756
|
if (!this.#currentStepSpan || this.#currentInferenceSpan) return;
|
|
2763
2757
|
this.#inferenceCompletionStartTime = void 0;
|
|
@@ -2882,7 +2876,7 @@ var ModelSpanTracker = class {
|
|
|
2882
2876
|
*/
|
|
2883
2877
|
#ensureStepAndInference() {
|
|
2884
2878
|
if (!this.#currentStepSpan) this.startStep();
|
|
2885
|
-
if (!this.#currentInferenceSpan) this
|
|
2879
|
+
if (!this.#currentInferenceSpan) this.#openInference();
|
|
2886
2880
|
}
|
|
2887
2881
|
/**
|
|
2888
2882
|
* Create a new chunk span (for multi-part chunks like text-start/delta/end)
|
|
@@ -3082,7 +3076,7 @@ var ModelSpanTracker = class {
|
|
|
3082
3076
|
this.#inModelResponse = true;
|
|
3083
3077
|
if (this.#currentStepSpan) this.updateStep(chunk.payload);
|
|
3084
3078
|
else this.startStep(chunk.payload);
|
|
3085
|
-
if (!this.#currentInferenceSpan) this
|
|
3079
|
+
if (!this.#currentInferenceSpan) this.#openInference(chunk.payload);
|
|
3086
3080
|
break;
|
|
3087
3081
|
case "step-finish":
|
|
3088
3082
|
this.#inModelResponse = false;
|
|
@@ -3128,8 +3122,7 @@ var ModelSpanTracker = class {
|
|
|
3128
3122
|
} }));
|
|
3129
3123
|
}
|
|
3130
3124
|
};
|
|
3131
|
-
|
|
3132
|
-
//#region src/spans/metadata.ts
|
|
3125
|
+
// src/spans/metadata.ts
|
|
3133
3126
|
/**
|
|
3134
3127
|
* Shared span-metadata helpers.
|
|
3135
3128
|
*
|
|
@@ -3196,8 +3189,7 @@ function mergeMetadata$1(parentMetadata, metadata) {
|
|
|
3196
3189
|
return metadata;
|
|
3197
3190
|
}
|
|
3198
3191
|
}
|
|
3199
|
-
|
|
3200
|
-
//#region src/spans/base.ts
|
|
3192
|
+
// src/spans/base.ts
|
|
3201
3193
|
const LINEAGE_KEYS = [
|
|
3202
3194
|
"parentEntityType",
|
|
3203
3195
|
"parentEntityId",
|
|
@@ -3208,10 +3200,10 @@ const LINEAGE_KEYS = [
|
|
|
3208
3200
|
"rootEntityName",
|
|
3209
3201
|
"rootEntityVersionId"
|
|
3210
3202
|
];
|
|
3211
|
-
/** Copy only the lineage fields that have values, so spans don't carry undefined keys */
|
|
3212
3203
|
function ownEntityVersionId(span) {
|
|
3213
3204
|
return span instanceof BaseSpan ? span.ownEntityVersionId : void 0;
|
|
3214
3205
|
}
|
|
3206
|
+
/** Copy only the lineage fields that have values, so spans don't carry undefined keys */
|
|
3215
3207
|
function definedLineage(source) {
|
|
3216
3208
|
const lineage = {};
|
|
3217
3209
|
for (const key of LINEAGE_KEYS) {
|
|
@@ -3290,6 +3282,19 @@ function getExternalParentId(options) {
|
|
|
3290
3282
|
if (parent.isInternal || parent.isExcluded) return parent.getParentSpanId(false);
|
|
3291
3283
|
return parent.id;
|
|
3292
3284
|
}
|
|
3285
|
+
/**
|
|
3286
|
+
* Vercel AI Gateway reports which provider served a step, and any provider
|
|
3287
|
+
* attempts that failed first, only in `providerMetadata.gateway.routing`.
|
|
3288
|
+
* Read it defensively so a throwing getter never skips the strip below.
|
|
3289
|
+
*/
|
|
3290
|
+
function readGatewayRouting(providerMetadata) {
|
|
3291
|
+
try {
|
|
3292
|
+
const gateway = isPlainRecord(providerMetadata) ? providerMetadata.gateway : void 0;
|
|
3293
|
+
return isPlainRecord(gateway) ? gateway.routing : void 0;
|
|
3294
|
+
} catch {
|
|
3295
|
+
return;
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3293
3298
|
var BaseSpan = class BaseSpan {
|
|
3294
3299
|
name;
|
|
3295
3300
|
type;
|
|
@@ -3417,8 +3422,10 @@ var BaseSpan = class BaseSpan {
|
|
|
3417
3422
|
if (this.type !== _mastra_core_observability.SpanType.MODEL_STEP) return value;
|
|
3418
3423
|
try {
|
|
3419
3424
|
const prepared = { ...value };
|
|
3425
|
+
const gatewayRouting = readGatewayRouting(prepared.providerMetadata);
|
|
3420
3426
|
delete prepared.providerMetadata;
|
|
3421
3427
|
delete prepared.experimental_providerMetadata;
|
|
3428
|
+
if (gatewayRouting !== void 0) prepared.providerMetadata = { gateway: { routing: gatewayRouting } };
|
|
3422
3429
|
return prepared;
|
|
3423
3430
|
} catch {
|
|
3424
3431
|
return value;
|
|
@@ -3604,7 +3611,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3604
3611
|
entityType: this.entityType,
|
|
3605
3612
|
entityId: this.entityId,
|
|
3606
3613
|
entityName: this.entityName,
|
|
3607
|
-
entityVersionId:
|
|
3614
|
+
entityVersionId: this.ownEntityVersionId,
|
|
3608
3615
|
...parentLineage,
|
|
3609
3616
|
...rootLineage,
|
|
3610
3617
|
userId: getMetadataString("userId"),
|
|
@@ -3647,6 +3654,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3647
3654
|
isEvent: this.isEvent,
|
|
3648
3655
|
isRootSpan: this.isRootSpan,
|
|
3649
3656
|
...this.isInternal ? { isInternal: true } : {},
|
|
3657
|
+
...correlation.entityVersionId ? { entityVersionId: correlation.entityVersionId } : {},
|
|
3650
3658
|
...definedLineage(correlation),
|
|
3651
3659
|
parentSpanId: this.getParentSpanId(includeInternalSpans),
|
|
3652
3660
|
externalParentSpanId: this.getExportedExternalParentSpanId(includeInternalSpans),
|
|
@@ -3691,8 +3699,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3691
3699
|
return fn();
|
|
3692
3700
|
}
|
|
3693
3701
|
};
|
|
3694
|
-
|
|
3695
|
-
//#region src/spans/default.ts
|
|
3702
|
+
// src/spans/default.ts
|
|
3696
3703
|
/** Every AI SDK `APICallError` (v4, v5 and v6) carries this shared marker symbol. */
|
|
3697
3704
|
const API_CALL_ERROR_MARKER = Symbol.for("vercel.ai.error.AI_APICallError");
|
|
3698
3705
|
function isApiCallError(value) {
|
|
@@ -3883,8 +3890,7 @@ function getOrCreateTraceId(options) {
|
|
|
3883
3890
|
}
|
|
3884
3891
|
return generateTraceId();
|
|
3885
3892
|
}
|
|
3886
|
-
|
|
3887
|
-
//#region src/spans/no-op.ts
|
|
3893
|
+
// src/spans/no-op.ts
|
|
3888
3894
|
var NoOpSpan = class extends BaseSpan {
|
|
3889
3895
|
id;
|
|
3890
3896
|
traceId;
|
|
@@ -3903,8 +3909,7 @@ var NoOpSpan = class extends BaseSpan {
|
|
|
3903
3909
|
return true;
|
|
3904
3910
|
}
|
|
3905
3911
|
};
|
|
3906
|
-
|
|
3907
|
-
//#region src/exporters/base.ts
|
|
3912
|
+
// src/exporters/base.ts
|
|
3908
3913
|
/**
|
|
3909
3914
|
* Base Exporter for Observability
|
|
3910
3915
|
*
|
|
@@ -4066,8 +4071,7 @@ var BaseExporter = class {
|
|
|
4066
4071
|
this.logger.info(`${this.name} shutdown complete`);
|
|
4067
4072
|
}
|
|
4068
4073
|
};
|
|
4069
|
-
|
|
4070
|
-
//#region src/exporters/event-buffer.ts
|
|
4074
|
+
// src/exporters/event-buffer.ts
|
|
4071
4075
|
/**
|
|
4072
4076
|
* Buffers observability events (creates and updates) for batch flushing.
|
|
4073
4077
|
* Handles strategy-aware routing of tracing events and tracks created spans
|
|
@@ -4078,6 +4082,8 @@ var EventBuffer = class {
|
|
|
4078
4082
|
#creates = [];
|
|
4079
4083
|
#updates = [];
|
|
4080
4084
|
#allCreatedSpans = /* @__PURE__ */ new Set();
|
|
4085
|
+
/** Spans whose SPAN_STARTED this buffer has seen but whose create isn't confirmed yet */
|
|
4086
|
+
#pendingCreateSpans = /* @__PURE__ */ new Set();
|
|
4081
4087
|
#firstEventTime;
|
|
4082
4088
|
#storageStrategy;
|
|
4083
4089
|
#maxRetries;
|
|
@@ -4128,8 +4134,11 @@ var EventBuffer = class {
|
|
|
4128
4134
|
case _mastra_core_observability.TracingEventType.SPAN_STARTED:
|
|
4129
4135
|
switch (this.#storageStrategy) {
|
|
4130
4136
|
case "realtime":
|
|
4131
|
-
case "
|
|
4132
|
-
|
|
4137
|
+
case "batch-with-updates":
|
|
4138
|
+
if (!event.exportedSpan.isEvent) this.#pendingCreateSpans.add(this.exportedSpanKey(event.exportedSpan));
|
|
4139
|
+
this.pushCreate(event);
|
|
4140
|
+
break;
|
|
4141
|
+
case "event-sourced": this.pushCreate(event);
|
|
4133
4142
|
}
|
|
4134
4143
|
break;
|
|
4135
4144
|
case _mastra_core_observability.TracingEventType.SPAN_UPDATED:
|
|
@@ -4198,28 +4207,44 @@ var EventBuffer = class {
|
|
|
4198
4207
|
buildSpanKey(span) {
|
|
4199
4208
|
return `${span.traceId}:${span.spanId}`;
|
|
4200
4209
|
}
|
|
4210
|
+
exportedSpanKey(span) {
|
|
4211
|
+
return this.buildSpanKey({
|
|
4212
|
+
traceId: span.traceId,
|
|
4213
|
+
spanId: span.id
|
|
4214
|
+
});
|
|
4215
|
+
}
|
|
4201
4216
|
/** Track successfully created spans so updates can verify span existence before flushing. */
|
|
4202
4217
|
addCreatedSpans(args) {
|
|
4203
4218
|
if (this.#storageStrategy === "event-sourced" || this.#storageStrategy === "insert-only") return;
|
|
4204
|
-
for (const createRecord of args.records) if (!createRecord.isEvent)
|
|
4219
|
+
for (const createRecord of args.records) if (!createRecord.isEvent) {
|
|
4220
|
+
const key = this.buildSpanKey(createRecord);
|
|
4221
|
+
this.#pendingCreateSpans.delete(key);
|
|
4222
|
+
this.#allCreatedSpans.add(key);
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
/** Stop waiting on creates that were dropped, so their updates aren't held back for them. */
|
|
4226
|
+
forgetDroppedCreates(events) {
|
|
4227
|
+
for (const event of events) if (event.type === _mastra_core_observability.TracingEventType.SPAN_STARTED) this.#pendingCreateSpans.delete(this.exportedSpanKey(event.exportedSpan));
|
|
4205
4228
|
}
|
|
4206
4229
|
/** Check whether a span's create record has already been flushed to storage. */
|
|
4207
4230
|
spanExists(span) {
|
|
4208
|
-
return this.#allCreatedSpans
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4231
|
+
return this.#allCreatedSpans.has(this.exportedSpanKey(span));
|
|
4232
|
+
}
|
|
4233
|
+
/** Check whether this buffer saw the span's SPAN_STARTED but its create hasn't been confirmed yet. */
|
|
4234
|
+
isAwaitingCreate(span) {
|
|
4235
|
+
return this.#pendingCreateSpans.has(this.exportedSpanKey(span));
|
|
4212
4236
|
}
|
|
4213
4237
|
/** Remove completed spans from tracking after their SPAN_ENDED updates are flushed. */
|
|
4214
4238
|
endFinishedSpans(args) {
|
|
4215
4239
|
if (this.#storageStrategy === "event-sourced" || this.#storageStrategy === "insert-only") return;
|
|
4216
4240
|
args.records.forEach((r) => {
|
|
4217
|
-
this
|
|
4241
|
+
const key = this.buildSpanKey(r);
|
|
4242
|
+
this.#allCreatedSpans.delete(key);
|
|
4243
|
+
this.#pendingCreateSpans.delete(key);
|
|
4218
4244
|
});
|
|
4219
4245
|
}
|
|
4220
4246
|
};
|
|
4221
|
-
|
|
4222
|
-
//#region src/exporters/default.ts
|
|
4247
|
+
// src/exporters/default.ts
|
|
4223
4248
|
/**
|
|
4224
4249
|
* Resolves the final tracing storage strategy based on config and observability store hints
|
|
4225
4250
|
*/
|
|
@@ -4657,8 +4682,22 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
4657
4682
|
this.logger.info("DefaultExporter shutdown complete");
|
|
4658
4683
|
}
|
|
4659
4684
|
};
|
|
4660
|
-
|
|
4661
|
-
|
|
4685
|
+
// src/exporters/span-previews.ts
|
|
4686
|
+
const buildSpanPreviews = _mastra_core_observability.buildSpanPreviews;
|
|
4687
|
+
/** Older core versions retain their existing storage preview fallback. */
|
|
4688
|
+
function withSpanPreviews(span) {
|
|
4689
|
+
if (!_mastra_core_features.coreFeatures.has("observability-span-previews")) return span;
|
|
4690
|
+
try {
|
|
4691
|
+
const previews = buildSpanPreviews?.(span);
|
|
4692
|
+
return previews ? {
|
|
4693
|
+
...span,
|
|
4694
|
+
...previews
|
|
4695
|
+
} : span;
|
|
4696
|
+
} catch {
|
|
4697
|
+
return span;
|
|
4698
|
+
}
|
|
4699
|
+
}
|
|
4700
|
+
// src/exporters/mastra-storage.ts
|
|
4662
4701
|
/**
|
|
4663
4702
|
* Resolves the final tracing storage strategy based on config and observability store hints
|
|
4664
4703
|
*/
|
|
@@ -4861,6 +4900,7 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
4861
4900
|
return { failed: true };
|
|
4862
4901
|
}
|
|
4863
4902
|
const dropped = this.#eventBuffer.reAddCreates(events);
|
|
4903
|
+
this.#eventBuffer.forgetDroppedCreates(dropped);
|
|
4864
4904
|
const retryAttempt = this.retryAttempt(events);
|
|
4865
4905
|
this.logStorageFailure(signal, events, retryAttempt, error);
|
|
4866
4906
|
this.emitDrop(signal, "retry-exhausted", dropped.length, error);
|
|
@@ -4871,7 +4911,15 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
4871
4911
|
}
|
|
4872
4912
|
}
|
|
4873
4913
|
/**
|
|
4874
|
-
* Flush span update/end events
|
|
4914
|
+
* Flush span update/end events.
|
|
4915
|
+
*
|
|
4916
|
+
* When the store supports conditional updates, only spans this exporter started
|
|
4917
|
+
* and hasn't confirmed the create for are deferred. Everything else, including
|
|
4918
|
+
* spans another exporter instance started (such as a durable agent ending spans
|
|
4919
|
+
* it rebuilt after a crash), goes straight to storage, and updates that didn't
|
|
4920
|
+
* apply are counted as drops. Without conditional updates, updates for spans this
|
|
4921
|
+
* exporter hasn't created are deferred until their create is flushed.
|
|
4922
|
+
*
|
|
4875
4923
|
* When `isEnd` is true, successfully flushed spans are removed from tracking.
|
|
4876
4924
|
*/
|
|
4877
4925
|
async flushSpanUpdates(events, deferredUpdates, isEnd) {
|
|
@@ -4881,10 +4929,12 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
4881
4929
|
this.emitDrop("tracing", "unsupported-storage", events.length);
|
|
4882
4930
|
return { failed: true };
|
|
4883
4931
|
}
|
|
4932
|
+
const storage = this.#observabilityStorage;
|
|
4933
|
+
const batchUpdateUnendedSpans = typeof storage.batchUpdateUnendedSpans === "function" ? storage.batchUpdateUnendedSpans.bind(storage) : void 0;
|
|
4884
4934
|
const partials = [];
|
|
4885
4935
|
for (const event of events) {
|
|
4886
4936
|
const span = event.exportedSpan;
|
|
4887
|
-
if (this.#eventBuffer.spanExists(span)) partials.push({
|
|
4937
|
+
if (batchUpdateUnendedSpans ? !this.#eventBuffer.isAwaitingCreate(span) : this.#eventBuffer.spanExists(span)) partials.push({
|
|
4888
4938
|
traceId: span.traceId,
|
|
4889
4939
|
spanId: span.id,
|
|
4890
4940
|
updates: (0, _mastra_core_storage.buildUpdateSpanRecord)(span)
|
|
@@ -4893,7 +4943,10 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
4893
4943
|
}
|
|
4894
4944
|
if (partials.length === 0) return FLUSH_SUCCEEDED;
|
|
4895
4945
|
try {
|
|
4896
|
-
|
|
4946
|
+
if (batchUpdateUnendedSpans) {
|
|
4947
|
+
const { updated } = await batchUpdateUnendedSpans({ records: partials });
|
|
4948
|
+
this.emitNotApplied(partials, updated);
|
|
4949
|
+
} else await storage.batchUpdateSpans({ records: partials });
|
|
4897
4950
|
if (isEnd) this.#eventBuffer.endFinishedSpans({ records: partials });
|
|
4898
4951
|
return FLUSH_SUCCEEDED;
|
|
4899
4952
|
} catch (error) {
|
|
@@ -4917,6 +4970,27 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
4917
4970
|
}
|
|
4918
4971
|
}
|
|
4919
4972
|
/**
|
|
4973
|
+
* Reports conditional span updates that storage didn't apply: the span wasn't
|
|
4974
|
+
* stored, or it had already ended. Ended spans are immutable, so these are dropped.
|
|
4975
|
+
*/
|
|
4976
|
+
emitNotApplied(partials, updated) {
|
|
4977
|
+
const appliedCounts = /* @__PURE__ */ new Map();
|
|
4978
|
+
for (const span of updated) {
|
|
4979
|
+
const key = `${span.traceId}:${span.spanId}`;
|
|
4980
|
+
appliedCounts.set(key, (appliedCounts.get(key) ?? 0) + 1);
|
|
4981
|
+
}
|
|
4982
|
+
let notApplied = 0;
|
|
4983
|
+
for (const partial of partials) {
|
|
4984
|
+
const key = `${partial.traceId}:${partial.spanId}`;
|
|
4985
|
+
const remaining = appliedCounts.get(key) ?? 0;
|
|
4986
|
+
if (remaining > 0) appliedCounts.set(key, remaining - 1);
|
|
4987
|
+
else notApplied++;
|
|
4988
|
+
}
|
|
4989
|
+
if (notApplied === 0) return;
|
|
4990
|
+
this.logger.debug("Span updates not applied: span not stored or already ended", { count: notApplied });
|
|
4991
|
+
this.emitDrop("tracing", "span-not-updatable", notApplied);
|
|
4992
|
+
}
|
|
4993
|
+
/**
|
|
4920
4994
|
* Runs flushBuffer() and tracks its promise so flush() can wait for writes
|
|
4921
4995
|
* that a timer or size trigger started on their own.
|
|
4922
4996
|
*/
|
|
@@ -5026,7 +5100,10 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
5026
5100
|
this.logger.debug("Cannot store traces. Observability storage is not initialized");
|
|
5027
5101
|
return;
|
|
5028
5102
|
}
|
|
5029
|
-
this.#eventBuffer.addEvent(
|
|
5103
|
+
this.#eventBuffer.addEvent({
|
|
5104
|
+
...event,
|
|
5105
|
+
exportedSpan: withSpanPreviews(event.exportedSpan)
|
|
5106
|
+
});
|
|
5030
5107
|
await this.handleBatchedFlush();
|
|
5031
5108
|
}
|
|
5032
5109
|
/**
|
|
@@ -5095,8 +5172,7 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
5095
5172
|
this.logger.info("MastraStorageExporter shutdown complete");
|
|
5096
5173
|
}
|
|
5097
5174
|
};
|
|
5098
|
-
|
|
5099
|
-
//#region src/instances/platform-policy.ts
|
|
5175
|
+
// src/instances/platform-policy.ts
|
|
5100
5176
|
const MASTRA_BUILT_IN_STORAGE_EXPORTER_NAMES = /* @__PURE__ */ new Set(["mastra-storage-exporter", "mastra-default-observability-exporter"]);
|
|
5101
5177
|
function isMastraPlatformDeployment() {
|
|
5102
5178
|
return Boolean(process.env.MASTRA_DEPLOYMENT_ID);
|
|
@@ -5104,8 +5180,7 @@ function isMastraPlatformDeployment() {
|
|
|
5104
5180
|
function isMastraBuiltInStorageExporter(exporter) {
|
|
5105
5181
|
return exporter instanceof MastraStorageExporter || exporter instanceof DefaultExporter || MASTRA_BUILT_IN_STORAGE_EXPORTER_NAMES.has(exporter.name);
|
|
5106
5182
|
}
|
|
5107
|
-
|
|
5108
|
-
//#region src/instances/base.ts
|
|
5183
|
+
// src/instances/base.ts
|
|
5109
5184
|
/**
|
|
5110
5185
|
* BaseObservability - Abstract base class for Observability implementations
|
|
5111
5186
|
*/
|
|
@@ -5818,13 +5893,11 @@ var BaseObservabilityInstance = class extends _mastra_core_base.MastraBase {
|
|
|
5818
5893
|
this.logger.info(`[Observability] Shutdown completed [name=${this.name}]`);
|
|
5819
5894
|
}
|
|
5820
5895
|
};
|
|
5821
|
-
|
|
5822
|
-
//#region src/client/id.ts
|
|
5896
|
+
// src/client/id.ts
|
|
5823
5897
|
function generateClientSignalId() {
|
|
5824
5898
|
return globalThis.crypto.randomUUID();
|
|
5825
5899
|
}
|
|
5826
|
-
|
|
5827
|
-
//#region src/client/otlp.ts
|
|
5900
|
+
// src/client/otlp.ts
|
|
5828
5901
|
/**
|
|
5829
5902
|
* Hand-rolled OTLP/JSON decoder for the subset we need to ingest from
|
|
5830
5903
|
* client-side tool execution.
|
|
@@ -6012,8 +6085,7 @@ function buildExportedLog(decoded) {
|
|
|
6012
6085
|
data: decoded.attributes
|
|
6013
6086
|
};
|
|
6014
6087
|
}
|
|
6015
|
-
|
|
6016
|
-
//#region src/client/w3c.ts
|
|
6088
|
+
// src/client/w3c.ts
|
|
6017
6089
|
/**
|
|
6018
6090
|
* Hand-rolled W3C Trace Context and Baggage propagation.
|
|
6019
6091
|
*
|
|
@@ -6084,8 +6156,7 @@ function formatBaggage(entries) {
|
|
|
6084
6156
|
}
|
|
6085
6157
|
return parts.join(",");
|
|
6086
6158
|
}
|
|
6087
|
-
|
|
6088
|
-
//#region src/client/proxy.ts
|
|
6159
|
+
// src/client/proxy.ts
|
|
6089
6160
|
const DEFAULT_LIMITS = {
|
|
6090
6161
|
maxSpans: 10,
|
|
6091
6162
|
maxLogs: 10,
|
|
@@ -6223,8 +6294,7 @@ function validateParentLinks(spans, rootParent) {
|
|
|
6223
6294
|
function createClientObservabilityProxy(options) {
|
|
6224
6295
|
return new ClientObservabilityProxyImpl(options);
|
|
6225
6296
|
}
|
|
6226
|
-
|
|
6227
|
-
//#region src/exporters/tracking.ts
|
|
6297
|
+
// src/exporters/tracking.ts
|
|
6228
6298
|
/**
|
|
6229
6299
|
* TrackingExporter base class for vendor-specific observability exporters.
|
|
6230
6300
|
*
|
|
@@ -7305,8 +7375,7 @@ var TrackingExporter = class extends BaseExporter {
|
|
|
7305
7375
|
await super.shutdown();
|
|
7306
7376
|
}
|
|
7307
7377
|
};
|
|
7308
|
-
|
|
7309
|
-
//#region src/exporters/span-formatters.ts
|
|
7378
|
+
// src/exporters/span-formatters.ts
|
|
7310
7379
|
/**
|
|
7311
7380
|
* Chains multiple span formatters into a single formatter.
|
|
7312
7381
|
*
|
|
@@ -7343,8 +7412,7 @@ function chainFormatters(formatters) {
|
|
|
7343
7412
|
return currentSpan;
|
|
7344
7413
|
};
|
|
7345
7414
|
}
|
|
7346
|
-
|
|
7347
|
-
//#region src/exporters/auth-failure-cooldown.ts
|
|
7415
|
+
// src/exporters/auth-failure-cooldown.ts
|
|
7348
7416
|
const AUTH_FAILURE_STATUSES = /* @__PURE__ */ new Set([401, 403]);
|
|
7349
7417
|
const AUTH_COOLDOWN_BASE_MS = 6e4;
|
|
7350
7418
|
const AUTH_COOLDOWN_MAX_MS = 9e5;
|
|
@@ -7425,8 +7493,7 @@ var AuthFailureCooldown = class {
|
|
|
7425
7493
|
});
|
|
7426
7494
|
}
|
|
7427
7495
|
};
|
|
7428
|
-
|
|
7429
|
-
//#region src/exporters/cloud.ts
|
|
7496
|
+
// src/exporters/cloud.ts
|
|
7430
7497
|
const SIGNAL_PUBLISH_SUFFIXES$1 = {
|
|
7431
7498
|
traces: "/spans/publish",
|
|
7432
7499
|
logs: "/logs/publish",
|
|
@@ -7846,8 +7913,7 @@ var CloudExporter = class extends BaseExporter {
|
|
|
7846
7913
|
this.logger.info("CloudExporter shutdown complete");
|
|
7847
7914
|
}
|
|
7848
7915
|
};
|
|
7849
|
-
|
|
7850
|
-
//#region src/exporters/console.ts
|
|
7916
|
+
// src/exporters/console.ts
|
|
7851
7917
|
var ConsoleExporter = class extends BaseExporter {
|
|
7852
7918
|
name = "tracing-console-exporter";
|
|
7853
7919
|
constructor(config = {}) {
|
|
@@ -7910,8 +7976,7 @@ var ConsoleExporter = class extends BaseExporter {
|
|
|
7910
7976
|
this.logger.info("ConsoleExporter shutdown");
|
|
7911
7977
|
}
|
|
7912
7978
|
};
|
|
7913
|
-
|
|
7914
|
-
//#region src/exporters/mastra-platform.ts
|
|
7979
|
+
// src/exporters/mastra-platform.ts
|
|
7915
7980
|
const SIGNAL_PUBLISH_SUFFIXES = {
|
|
7916
7981
|
traces: "/spans/publish",
|
|
7917
7982
|
logs: "/logs/publish",
|
|
@@ -8142,7 +8207,7 @@ var MastraPlatformExporter = class extends BaseExporter {
|
|
|
8142
8207
|
}
|
|
8143
8208
|
formatSpan(span) {
|
|
8144
8209
|
return {
|
|
8145
|
-
...span,
|
|
8210
|
+
...withSpanPreviews(span),
|
|
8146
8211
|
spanId: span.id,
|
|
8147
8212
|
spanType: span.type,
|
|
8148
8213
|
startedAt: span.startTime,
|
|
@@ -8442,8 +8507,7 @@ var MastraPlatformExporter = class extends BaseExporter {
|
|
|
8442
8507
|
this.logger.info("MastraPlatformExporter shutdown complete");
|
|
8443
8508
|
}
|
|
8444
8509
|
};
|
|
8445
|
-
|
|
8446
|
-
//#region src/exporters/test.ts
|
|
8510
|
+
// src/exporters/test.ts
|
|
8447
8511
|
/**
|
|
8448
8512
|
* Test Exporter for Observability
|
|
8449
8513
|
*
|
|
@@ -9489,8 +9553,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
9489
9553
|
* @deprecated Use `TestExporter` instead. This alias will be removed in a future version.
|
|
9490
9554
|
*/
|
|
9491
9555
|
const JsonExporter = TestExporter;
|
|
9492
|
-
|
|
9493
|
-
//#region src/instances/default.ts
|
|
9556
|
+
// src/instances/default.ts
|
|
9494
9557
|
var DefaultObservabilityInstance = class extends BaseObservabilityInstance {
|
|
9495
9558
|
constructor(config) {
|
|
9496
9559
|
super(config);
|
|
@@ -9499,8 +9562,7 @@ var DefaultObservabilityInstance = class extends BaseObservabilityInstance {
|
|
|
9499
9562
|
return new DefaultSpan(options, this);
|
|
9500
9563
|
}
|
|
9501
9564
|
};
|
|
9502
|
-
|
|
9503
|
-
//#region src/recorded.ts
|
|
9565
|
+
// src/recorded.ts
|
|
9504
9566
|
function nullToUndefined(value) {
|
|
9505
9567
|
return value ?? void 0;
|
|
9506
9568
|
}
|
|
@@ -9804,8 +9866,7 @@ function hydrateRecordedTrace(args) {
|
|
|
9804
9866
|
debugRecordedAnnotationUnavailable
|
|
9805
9867
|
});
|
|
9806
9868
|
}
|
|
9807
|
-
|
|
9808
|
-
//#region src/registry.ts
|
|
9869
|
+
// src/registry.ts
|
|
9809
9870
|
/**
|
|
9810
9871
|
* Registry for Observability instances.
|
|
9811
9872
|
*/
|
|
@@ -9894,8 +9955,7 @@ var ObservabilityRegistry = class {
|
|
|
9894
9955
|
return new Map(this.#instances);
|
|
9895
9956
|
}
|
|
9896
9957
|
};
|
|
9897
|
-
|
|
9898
|
-
//#region src/span_processors/sensitive-data-filter.ts
|
|
9958
|
+
// src/span_processors/sensitive-data-filter.ts
|
|
9899
9959
|
/**
|
|
9900
9960
|
* Maximum number of traces to keep indexed-redaction state for.
|
|
9901
9961
|
* Spans never signal trace completion, so state is evicted least-recently-used.
|
|
@@ -10105,8 +10165,7 @@ var SensitiveDataFilter = class {
|
|
|
10105
10165
|
this.traceStates.clear();
|
|
10106
10166
|
}
|
|
10107
10167
|
};
|
|
10108
|
-
|
|
10109
|
-
//#region src/default.ts
|
|
10168
|
+
// src/default.ts
|
|
10110
10169
|
/**
|
|
10111
10170
|
* Type guard to check if an object is a BaseObservability instance
|
|
10112
10171
|
*/
|
|
@@ -10441,8 +10500,7 @@ var Observability = class extends _mastra_core_base.MastraBase {
|
|
|
10441
10500
|
if (handlerResults.length > 0) await Promise.allSettled(handlerResults);
|
|
10442
10501
|
}
|
|
10443
10502
|
};
|
|
10444
|
-
|
|
10445
|
-
//#region src/features.ts
|
|
10503
|
+
// src/features.ts
|
|
10446
10504
|
/**
|
|
10447
10505
|
* Feature flags for @mastra/observability
|
|
10448
10506
|
*
|
|
@@ -10481,8 +10539,7 @@ var Observability = class extends _mastra_core_base.MastraBase {
|
|
|
10481
10539
|
* ```
|
|
10482
10540
|
*/
|
|
10483
10541
|
const observabilityFeatures = /* @__PURE__ */ new Set(["model-inference-span", "internal-usage-rollup"]);
|
|
10484
|
-
|
|
10485
|
-
//#region src/tracing-options.ts
|
|
10542
|
+
// src/tracing-options.ts
|
|
10486
10543
|
/**
|
|
10487
10544
|
* Builds TracingOptions by composing one or more updater functions.
|
|
10488
10545
|
*
|
|
@@ -10503,7 +10560,6 @@ const observabilityFeatures = /* @__PURE__ */ new Set(["model-inference-span", "
|
|
|
10503
10560
|
function buildTracingOptions(...updaters) {
|
|
10504
10561
|
return updaters.reduce((opts, updater) => updater(opts), {});
|
|
10505
10562
|
}
|
|
10506
|
-
//#endregion
|
|
10507
10563
|
exports.BaseExporter = BaseExporter;
|
|
10508
10564
|
exports.BaseObservabilityEventBus = BaseObservabilityEventBus;
|
|
10509
10565
|
exports.BaseObservabilityInstance = BaseObservabilityInstance;
|