@mastra/observability 1.12.0 → 1.13.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 +28 -0
- package/dist/exporters/default.d.ts.map +1 -1
- package/dist/exporters/mastra-storage.d.ts +2 -0
- package/dist/exporters/mastra-storage.d.ts.map +1 -1
- package/dist/features.d.ts.map +1 -1
- package/dist/index.cjs +179 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +179 -12
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts +35 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/metrics/auto-extract.d.ts +11 -1
- package/dist/metrics/auto-extract.d.ts.map +1 -1
- package/dist/usage.d.ts +7 -0
- package/dist/usage.d.ts.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @mastra/observability
|
|
2
2
|
|
|
3
|
+
## 1.13.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- `MastraStorageExporter` now notifies custom exporters and connected integrations when it cannot persist observability events, such as unsupported storage or retries being exceeded. This matches the behavior already available on `DefaultExporter`. ([#16755](https://github.com/mastra-ai/mastra/pull/16755))
|
|
8
|
+
|
|
9
|
+
Also fixed an issue in both exporters where span updates waiting on their parent span could be silently lost if a later flush in the same cycle failed.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`5556cc1`](https://github.com/mastra-ai/mastra/commit/5556cc1befec71518d84f826b3bfe3a079a9daf7), [`5499303`](https://github.com/mastra-ai/mastra/commit/54993032c1ebc09642625b78d2014e0cf84a3cae), [`e47bca7`](https://github.com/mastra-ai/mastra/commit/e47bca7b72866d3abd173b9f530ac4318113a8ff), [`0031d0f`](https://github.com/mastra-ai/mastra/commit/0031d0f13831d7843ac5d498734a7d92862e2ce3), [`3498b49`](https://github.com/mastra-ai/mastra/commit/3498b4946be94f4313cd817733589680dcda5278), [`359439b`](https://github.com/mastra-ai/mastra/commit/359439bb8c635e048176306828195f8297f50021)]:
|
|
14
|
+
- @mastra/core@1.36.0-alpha.3
|
|
15
|
+
|
|
16
|
+
## 1.13.0-alpha.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- Roll up token usage from internal MODEL_GENERATION spans onto the closest exported ancestor span. When `tracingPolicy.internal` filters a model call out of exported traces, its tokens used to disappear from both the trace UI and metrics. Now: ([#16434](https://github.com/mastra-ai/mastra/pull/16434))
|
|
21
|
+
- The visible ancestor (e.g. `PROCESSOR_RUN`, `AGENT_RUN`) gets an `internalUsage` attribute summing the tokens consumed by its hidden descendants — so a Mastra-owned processor that runs an internal agent (moderation, PII detector, structured output, etc.) shows its aggregate cost on the visible `PROCESSOR_RUN` span.
|
|
22
|
+
- Token / cost metrics still emit, but are attributed via labels to the visible ancestor instead of the hidden agent.
|
|
23
|
+
|
|
24
|
+
No action required — the rollup applies automatically whenever an internal `MODEL_GENERATION` ends inside a non-internal ancestor.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`8cdb86c`](https://github.com/mastra-ai/mastra/commit/8cdb86ceed1137bc2768e147dce85a0692b9fb26), [`eda90c5`](https://github.com/mastra-ai/mastra/commit/eda90c5bfd7de11805ecc9f4552716c895fbaf78), [`afc004f`](https://github.com/mastra-ai/mastra/commit/afc004f5cc7e30697809e7021820b9f5881e6719), [`408be73`](https://github.com/mastra-ai/mastra/commit/408be73449dfab92b51eab8c6623b6c443debc25)]:
|
|
29
|
+
- @mastra/core@1.36.0-alpha.1
|
|
30
|
+
|
|
3
31
|
## 1.12.0
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/exporters/default.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,EAId,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAwB,sBAAsB,EAAwB,MAAM,sBAAsB,CAAC;AAS/G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC;;;;;;GAMG;AACH,UAAU,qBAAsB,SAAQ,kBAAkB;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;CAC5C;AA6BD;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAC/C,IAAI,SAA2C;gBAgBnC,MAAM,GAAE,qBAA0B;IAiB9C;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDvD;;OAEG;IACH,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;;OAIG;YACW,kBAAkB;IAQhC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,QAAQ;IAsBhB;;;;OAIG;YACW,YAAY;IA6B1B;;;OAGG;YACW,gBAAgB;
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../src/exporters/default.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,EAId,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAwB,sBAAsB,EAAwB,MAAM,sBAAsB,CAAC;AAS/G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC;;;;;;GAMG;AACH,UAAU,qBAAsB,SAAQ,kBAAkB;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;CAC5C;AA6BD;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAC/C,IAAI,SAA2C;gBAgBnC,MAAM,GAAE,qBAA0B;IAiB9C;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDvD;;OAEG;IACH,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;;OAIG;YACW,kBAAkB;IAQhC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,QAAQ;IAsBhB;;;;OAIG;YACW,YAAY;IA6B1B;;;OAGG;YACW,gBAAgB;IA0D9B;;;;;;;OAOG;YACW,WAAW;IAmHnB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D;;;;OAIG;YACW,WAAW;IAOzB;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1D;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAYhC"}
|
|
@@ -37,6 +37,8 @@ export declare class MastraStorageExporter extends BaseExporter {
|
|
|
37
37
|
* Returns the flush promise when flushing so callers can await it.
|
|
38
38
|
*/
|
|
39
39
|
private handleBatchedFlush;
|
|
40
|
+
private sanitizeDropError;
|
|
41
|
+
private emitDrop;
|
|
40
42
|
/**
|
|
41
43
|
* Flush a batch of create events for a single signal type.
|
|
42
44
|
* On "not implemented" errors, disables the signal for future flushes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mastra-storage.d.ts","sourceRoot":"","sources":["../../src/exporters/mastra-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,
|
|
1
|
+
{"version":3,"file":"mastra-storage.d.ts","sourceRoot":"","sources":["../../src/exporters/mastra-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,QAAQ,EACR,UAAU,EACV,aAAa,EAId,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAwB,sBAAsB,EAAwB,MAAM,sBAAsB,CAAC;AAS/G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,4FAA4F;AAC5F,MAAM,WAAW,2BAA4B,SAAQ,kBAAkB;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;CAC5C;AA6BD;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;;IACrD,IAAI,SAA6B;gBAgBrB,MAAM,GAAE,2BAAgC;IAiBpD;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDvD;;OAEG;IACH,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;;OAIG;YACW,kBAAkB;IAQhC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,QAAQ;IAsBhB;;;;OAIG;YACW,YAAY;IA6B1B;;;OAGG;YACW,gBAAgB;IA0D9B;;;;;;;OAOG;YACW,WAAW;IAmHnB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7D;;;;OAIG;YACW,WAAW;IAOzB;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpD;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1D;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAYhC"}
|
package/dist/features.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAA8D,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -16020,7 +16020,10 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
16020
16020
|
deferredUpdates.length = 0;
|
|
16021
16021
|
this.emitDrop("tracing", "unsupported-storage", events.length + deferredCountAtEntry, error48);
|
|
16022
16022
|
} else {
|
|
16023
|
-
deferredUpdates.length
|
|
16023
|
+
const newlyDeferred = deferredUpdates.length - deferredCountAtEntry;
|
|
16024
|
+
if (newlyDeferred > 0) {
|
|
16025
|
+
deferredUpdates.splice(deferredUpdates.length - newlyDeferred, newlyDeferred);
|
|
16026
|
+
}
|
|
16024
16027
|
const dropped = this.#eventBuffer.reAddUpdates(events);
|
|
16025
16028
|
this.emitDrop("tracing", "retry-exhausted", dropped.length, error48);
|
|
16026
16029
|
}
|
|
@@ -16719,6 +16722,7 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16719
16722
|
#observabilityStorage;
|
|
16720
16723
|
#resolvedStrategy;
|
|
16721
16724
|
#flushTimer;
|
|
16725
|
+
#emitDropEvent;
|
|
16722
16726
|
// Signals whose storage methods threw "not implemented" — skip on future flushes
|
|
16723
16727
|
#unsupportedSignals = /* @__PURE__ */ new Set();
|
|
16724
16728
|
constructor(config2 = {}) {
|
|
@@ -16740,6 +16744,7 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16740
16744
|
async init(options) {
|
|
16741
16745
|
try {
|
|
16742
16746
|
this.#isInitializing = true;
|
|
16747
|
+
this.#emitDropEvent = options.emitDropEvent;
|
|
16743
16748
|
this.#storage = options.mastra?.getStorage();
|
|
16744
16749
|
if (!this.#storage) {
|
|
16745
16750
|
this.logger.warn("MastraStorageExporter disabled: Storage not available. Traces will not be persisted.");
|
|
@@ -16825,21 +16830,54 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16825
16830
|
this.scheduleFlush();
|
|
16826
16831
|
}
|
|
16827
16832
|
}
|
|
16833
|
+
sanitizeDropError(error48) {
|
|
16834
|
+
if (error48 instanceof error$1.MastraError) {
|
|
16835
|
+
return {
|
|
16836
|
+
id: error48.id,
|
|
16837
|
+
domain: String(error48.domain),
|
|
16838
|
+
message: error48.message
|
|
16839
|
+
};
|
|
16840
|
+
}
|
|
16841
|
+
if (error48 instanceof Error) {
|
|
16842
|
+
return { message: error48.message };
|
|
16843
|
+
}
|
|
16844
|
+
return { message: String(error48) };
|
|
16845
|
+
}
|
|
16846
|
+
emitDrop(signal, reason, count, error48) {
|
|
16847
|
+
if (count === 0) return;
|
|
16848
|
+
const dropEvent = {
|
|
16849
|
+
type: "drop",
|
|
16850
|
+
signal,
|
|
16851
|
+
reason,
|
|
16852
|
+
count,
|
|
16853
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
16854
|
+
exporterName: this.name,
|
|
16855
|
+
...this.#observabilityStorage ? { storageName: this.#observabilityStorage.constructor.name } : {},
|
|
16856
|
+
...error48 === void 0 ? {} : { error: this.sanitizeDropError(error48) }
|
|
16857
|
+
};
|
|
16858
|
+
this.#emitDropEvent?.(dropEvent);
|
|
16859
|
+
}
|
|
16828
16860
|
/**
|
|
16829
16861
|
* Flush a batch of create events for a single signal type.
|
|
16830
16862
|
* On "not implemented" errors, disables the signal for future flushes.
|
|
16831
16863
|
* On other errors, re-adds events to the buffer for retry.
|
|
16832
16864
|
*/
|
|
16833
16865
|
async flushCreates(signal, events, storageCall) {
|
|
16834
|
-
if (
|
|
16866
|
+
if (events.length === 0) return;
|
|
16867
|
+
if (this.#unsupportedSignals.has(signal)) {
|
|
16868
|
+
this.emitDrop(signal, "unsupported-storage", events.length);
|
|
16869
|
+
return;
|
|
16870
|
+
}
|
|
16835
16871
|
try {
|
|
16836
16872
|
await storageCall(events);
|
|
16837
16873
|
} catch (error48) {
|
|
16838
16874
|
if (error48 instanceof error$1.MastraError && error48.domain === error$1.ErrorDomain.MASTRA_OBSERVABILITY && error48.id.endsWith("_NOT_IMPLEMENTED")) {
|
|
16839
16875
|
this.logger.warn(error48.message);
|
|
16840
16876
|
this.#unsupportedSignals.add(signal);
|
|
16877
|
+
this.emitDrop(signal, "unsupported-storage", events.length, error48);
|
|
16841
16878
|
} else {
|
|
16842
|
-
this.#eventBuffer.reAddCreates(events);
|
|
16879
|
+
const dropped = this.#eventBuffer.reAddCreates(events);
|
|
16880
|
+
this.emitDrop(signal, "retry-exhausted", dropped.length, error48);
|
|
16843
16881
|
}
|
|
16844
16882
|
}
|
|
16845
16883
|
}
|
|
@@ -16848,7 +16886,12 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16848
16886
|
* When `isEnd` is true, successfully flushed spans are removed from tracking.
|
|
16849
16887
|
*/
|
|
16850
16888
|
async flushSpanUpdates(events, deferredUpdates, isEnd) {
|
|
16851
|
-
|
|
16889
|
+
const deferredCountAtEntry = deferredUpdates.length;
|
|
16890
|
+
if (events.length === 0) return;
|
|
16891
|
+
if (this.#unsupportedSignals.has("tracing")) {
|
|
16892
|
+
this.emitDrop("tracing", "unsupported-storage", events.length);
|
|
16893
|
+
return;
|
|
16894
|
+
}
|
|
16852
16895
|
const partials = [];
|
|
16853
16896
|
for (const event of events) {
|
|
16854
16897
|
const span = event.exportedSpan;
|
|
@@ -16872,9 +16915,15 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16872
16915
|
if (error48 instanceof error$1.MastraError && error48.domain === error$1.ErrorDomain.MASTRA_OBSERVABILITY && error48.id.endsWith("_NOT_IMPLEMENTED")) {
|
|
16873
16916
|
this.logger.warn(error48.message);
|
|
16874
16917
|
this.#unsupportedSignals.add("tracing");
|
|
16875
|
-
} else {
|
|
16876
16918
|
deferredUpdates.length = 0;
|
|
16877
|
-
this
|
|
16919
|
+
this.emitDrop("tracing", "unsupported-storage", events.length + deferredCountAtEntry, error48);
|
|
16920
|
+
} else {
|
|
16921
|
+
const newlyDeferred = deferredUpdates.length - deferredCountAtEntry;
|
|
16922
|
+
if (newlyDeferred > 0) {
|
|
16923
|
+
deferredUpdates.splice(deferredUpdates.length - newlyDeferred, newlyDeferred);
|
|
16924
|
+
}
|
|
16925
|
+
const dropped = this.#eventBuffer.reAddUpdates(events);
|
|
16926
|
+
this.emitDrop("tracing", "retry-exhausted", dropped.length, error48);
|
|
16878
16927
|
}
|
|
16879
16928
|
}
|
|
16880
16929
|
}
|
|
@@ -16950,17 +16999,17 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16950
16999
|
(events) => this.#observabilityStorage.batchCreateFeedback({ feedbacks: events.map((f) => storage.buildFeedbackRecord(f)) })
|
|
16951
17000
|
),
|
|
16952
17001
|
this.flushCreates(
|
|
16953
|
-
"
|
|
17002
|
+
"log",
|
|
16954
17003
|
createLogEvents,
|
|
16955
17004
|
(events) => this.#observabilityStorage.batchCreateLogs({ logs: events.map((l) => storage.buildLogRecord(l)) })
|
|
16956
17005
|
),
|
|
16957
17006
|
this.flushCreates(
|
|
16958
|
-
"
|
|
17007
|
+
"metric",
|
|
16959
17008
|
createMetricEvents,
|
|
16960
17009
|
(events) => this.#observabilityStorage.batchCreateMetrics({ metrics: events.map((m) => storage.buildMetricRecord(m)) })
|
|
16961
17010
|
),
|
|
16962
17011
|
this.flushCreates(
|
|
16963
|
-
"
|
|
17012
|
+
"score",
|
|
16964
17013
|
createScoreEvents,
|
|
16965
17014
|
(events) => this.#observabilityStorage.batchCreateScores({ scores: events.map((s) => storage.buildScoreRecord(s)) })
|
|
16966
17015
|
),
|
|
@@ -16974,7 +17023,13 @@ var MastraStorageExporter = class extends BaseExporter {
|
|
|
16974
17023
|
await this.flushSpanUpdates(updateSpanEvents, deferredUpdates, false);
|
|
16975
17024
|
await this.flushSpanUpdates(endSpanEvents, deferredUpdates, true);
|
|
16976
17025
|
if (deferredUpdates.length > 0) {
|
|
16977
|
-
this.#
|
|
17026
|
+
if (this.#unsupportedSignals.has("tracing")) {
|
|
17027
|
+
this.emitDrop("tracing", "unsupported-storage", deferredUpdates.length);
|
|
17028
|
+
deferredUpdates.length = 0;
|
|
17029
|
+
} else {
|
|
17030
|
+
const dropped = this.#eventBuffer.reAddUpdates(deferredUpdates);
|
|
17031
|
+
this.emitDrop("tracing", "retry-exhausted", dropped.length);
|
|
17032
|
+
}
|
|
16978
17033
|
}
|
|
16979
17034
|
const elapsed = Date.now() - startTime;
|
|
16980
17035
|
this.logger.debug("Batch flushed", {
|
|
@@ -19029,6 +19084,7 @@ var PricingRegistry = class _PricingRegistry {
|
|
|
19029
19084
|
constructor(pricingModels) {
|
|
19030
19085
|
this.pricingModels = pricingModels;
|
|
19031
19086
|
}
|
|
19087
|
+
pricingModels;
|
|
19032
19088
|
static globalRegistry = null;
|
|
19033
19089
|
static fromText(pricingModelText) {
|
|
19034
19090
|
return new _PricingRegistry(parsePricingModelText(pricingModelText));
|
|
@@ -19432,6 +19488,9 @@ function emitTokenMetrics(span, metrics) {
|
|
|
19432
19488
|
}
|
|
19433
19489
|
emitUsageMetrics(attrs, attrs.usage, metrics);
|
|
19434
19490
|
}
|
|
19491
|
+
function emitTokenMetricsForUsage(usage, provider, model, metrics) {
|
|
19492
|
+
emitUsageMetrics({ provider, model }, usage, metrics);
|
|
19493
|
+
}
|
|
19435
19494
|
function emitAutoExtractedMetrics(span, metrics) {
|
|
19436
19495
|
emitDurationMetrics(span, metrics);
|
|
19437
19496
|
emitTokenMetrics(span, metrics);
|
|
@@ -19593,6 +19652,46 @@ function extractUsageMetrics(usage, providerMetadata) {
|
|
|
19593
19652
|
function sumDefinedValues(obj, keys) {
|
|
19594
19653
|
return keys.reduce((sum, key) => sum + (obj[key] ?? 0), 0);
|
|
19595
19654
|
}
|
|
19655
|
+
function addOptional(a, b) {
|
|
19656
|
+
if (a === void 0 && b === void 0) return void 0;
|
|
19657
|
+
return (a ?? 0) + (b ?? 0);
|
|
19658
|
+
}
|
|
19659
|
+
function mergeInputDetails(a, b) {
|
|
19660
|
+
if (!a) return b ? { ...b } : void 0;
|
|
19661
|
+
if (!b) return { ...a };
|
|
19662
|
+
return {
|
|
19663
|
+
text: addOptional(a.text, b.text),
|
|
19664
|
+
cacheRead: addOptional(a.cacheRead, b.cacheRead),
|
|
19665
|
+
cacheWrite: addOptional(a.cacheWrite, b.cacheWrite),
|
|
19666
|
+
audio: addOptional(a.audio, b.audio),
|
|
19667
|
+
image: addOptional(a.image, b.image)
|
|
19668
|
+
};
|
|
19669
|
+
}
|
|
19670
|
+
function mergeOutputDetails(a, b) {
|
|
19671
|
+
if (!a) return b ? { ...b } : void 0;
|
|
19672
|
+
if (!b) return { ...a };
|
|
19673
|
+
return {
|
|
19674
|
+
text: addOptional(a.text, b.text),
|
|
19675
|
+
reasoning: addOptional(a.reasoning, b.reasoning),
|
|
19676
|
+
audio: addOptional(a.audio, b.audio),
|
|
19677
|
+
image: addOptional(a.image, b.image)
|
|
19678
|
+
};
|
|
19679
|
+
}
|
|
19680
|
+
function addUsageStats(a, b) {
|
|
19681
|
+
if (!a) {
|
|
19682
|
+
return {
|
|
19683
|
+
...b,
|
|
19684
|
+
inputDetails: b.inputDetails ? { ...b.inputDetails } : void 0,
|
|
19685
|
+
outputDetails: b.outputDetails ? { ...b.outputDetails } : void 0
|
|
19686
|
+
};
|
|
19687
|
+
}
|
|
19688
|
+
return {
|
|
19689
|
+
inputTokens: addOptional(a.inputTokens, b.inputTokens),
|
|
19690
|
+
outputTokens: addOptional(a.outputTokens, b.outputTokens),
|
|
19691
|
+
inputDetails: mergeInputDetails(a.inputDetails, b.inputDetails),
|
|
19692
|
+
outputDetails: mergeOutputDetails(a.outputDetails, b.outputDetails)
|
|
19693
|
+
};
|
|
19694
|
+
}
|
|
19596
19695
|
|
|
19597
19696
|
// src/model-tracing.ts
|
|
19598
19697
|
function supportsModelInference() {
|
|
@@ -21122,7 +21221,7 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
21122
21221
|
* This ensures all spans emit events regardless of implementation
|
|
21123
21222
|
*/
|
|
21124
21223
|
wireSpanLifecycle(span) {
|
|
21125
|
-
if (!this.config.includeInternalSpans && span.isInternal) {
|
|
21224
|
+
if (!this.config.includeInternalSpans && span.isInternal && span.type !== observability.SpanType.MODEL_GENERATION) {
|
|
21126
21225
|
return;
|
|
21127
21226
|
}
|
|
21128
21227
|
const originalEnd = span.end.bind(span);
|
|
@@ -21132,7 +21231,11 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
21132
21231
|
this.logger.warn(`End event is not available on event spans`);
|
|
21133
21232
|
return;
|
|
21134
21233
|
}
|
|
21234
|
+
const rollupTarget = this.captureModelUsageRollup(span, options);
|
|
21135
21235
|
originalEnd(options);
|
|
21236
|
+
if (rollupTarget) {
|
|
21237
|
+
this.applyUsageRollup(rollupTarget);
|
|
21238
|
+
}
|
|
21136
21239
|
this.emitSpanEnded(span);
|
|
21137
21240
|
};
|
|
21138
21241
|
span.update = (options) => {
|
|
@@ -21306,6 +21409,70 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
21306
21409
|
this.emitTracingEvent(event);
|
|
21307
21410
|
}
|
|
21308
21411
|
}
|
|
21412
|
+
/**
|
|
21413
|
+
* When an internal MODEL_GENERATION span ends, capture the rollup payload
|
|
21414
|
+
* (usage, provider, model, target ancestor) needed to attribute its cost
|
|
21415
|
+
* to the closest exported ancestor span. Returns undefined when no rollup
|
|
21416
|
+
* applies — non-MODEL_GENERATION spans, spans that will be exported, or
|
|
21417
|
+
* spans whose usage isn't available at end time.
|
|
21418
|
+
*/
|
|
21419
|
+
captureModelUsageRollup(span, endOptions) {
|
|
21420
|
+
if (span.type !== observability.SpanType.MODEL_GENERATION) return void 0;
|
|
21421
|
+
if (!span.isInternal || this.config.includeInternalSpans) return void 0;
|
|
21422
|
+
const endAttrs = endOptions?.attributes ?? void 0;
|
|
21423
|
+
const liveAttrs = span.attributes;
|
|
21424
|
+
const usage = endAttrs?.usage ?? liveAttrs?.usage;
|
|
21425
|
+
if (!usage) return void 0;
|
|
21426
|
+
const ancestor = this.findExportedAncestor(span);
|
|
21427
|
+
if (!ancestor) return void 0;
|
|
21428
|
+
const provider = endAttrs?.provider ?? liveAttrs?.provider;
|
|
21429
|
+
const model = endAttrs?.responseModel ?? endAttrs?.model ?? liveAttrs?.responseModel ?? liveAttrs?.model;
|
|
21430
|
+
return { ancestor, usage, provider, model };
|
|
21431
|
+
}
|
|
21432
|
+
/**
|
|
21433
|
+
* Accumulate usage onto the ancestor's `internalUsage` attribute (for trace
|
|
21434
|
+
* UI visibility) and emit auto-extracted token metrics now, using the
|
|
21435
|
+
* ancestor's metrics context so cost / token labels point at the visible
|
|
21436
|
+
* span instead of the hidden agent that incurred them.
|
|
21437
|
+
*/
|
|
21438
|
+
applyUsageRollup(target) {
|
|
21439
|
+
const { ancestor, usage, provider, model } = target;
|
|
21440
|
+
const attrs = ancestor.attributes;
|
|
21441
|
+
attrs.internalUsage = addUsageStats(attrs.internalUsage, usage);
|
|
21442
|
+
try {
|
|
21443
|
+
emitTokenMetricsForUsage(usage, provider, model, this.getMetricsContext(ancestor));
|
|
21444
|
+
} catch (err) {
|
|
21445
|
+
this.logger.error("[Observability] Usage rollup metric emission error:", err);
|
|
21446
|
+
}
|
|
21447
|
+
}
|
|
21448
|
+
/**
|
|
21449
|
+
* Walk up the parent chain to find the closest ancestor that will actually
|
|
21450
|
+
* reach exporters. Skips both internal-filtered ancestors and ancestors
|
|
21451
|
+
* whose type matches `excludeSpanTypes`, so the rollup target is one whose
|
|
21452
|
+
* mutated `internalUsage` attribute is visible in exported traces.
|
|
21453
|
+
*
|
|
21454
|
+
* Note: this does not preemptively run `spanFilter` — that filter can be
|
|
21455
|
+
* async and have side effects, so the rare case of a `spanFilter`-dropped
|
|
21456
|
+
* ancestor falls through.
|
|
21457
|
+
*/
|
|
21458
|
+
findExportedAncestor(span) {
|
|
21459
|
+
let ancestor = span.parent;
|
|
21460
|
+
while (ancestor && this.isFilteredFromExport(ancestor)) {
|
|
21461
|
+
ancestor = ancestor.parent;
|
|
21462
|
+
}
|
|
21463
|
+
return ancestor;
|
|
21464
|
+
}
|
|
21465
|
+
/**
|
|
21466
|
+
* Returns true when a span would be dropped by `getSpanForExport` for a
|
|
21467
|
+
* reason cheap to check up-front (internal-span filtering or
|
|
21468
|
+
* `excludeSpanTypes`). Used by `findExportedAncestor` to skip rollup
|
|
21469
|
+
* targets that would silently lose their `internalUsage` attribute.
|
|
21470
|
+
*/
|
|
21471
|
+
isFilteredFromExport(span) {
|
|
21472
|
+
if (span.isInternal && !this.config.includeInternalSpans) return true;
|
|
21473
|
+
if (this.config.excludeSpanTypes?.includes(span.type)) return true;
|
|
21474
|
+
return false;
|
|
21475
|
+
}
|
|
21309
21476
|
/**
|
|
21310
21477
|
* Emit a tracing event through the bus.
|
|
21311
21478
|
*
|
|
@@ -22256,7 +22423,7 @@ var Observability = class extends base.MastraBase {
|
|
|
22256
22423
|
};
|
|
22257
22424
|
|
|
22258
22425
|
// src/features.ts
|
|
22259
|
-
var observabilityFeatures = /* @__PURE__ */ new Set(["model-inference-span"]);
|
|
22426
|
+
var observabilityFeatures = /* @__PURE__ */ new Set(["model-inference-span", "internal-usage-rollup"]);
|
|
22260
22427
|
|
|
22261
22428
|
// src/tracing-options.ts
|
|
22262
22429
|
function buildTracingOptions(...updaters) {
|