@mastra/observability 1.16.6 → 1.17.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 +30 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.cjs +108 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +108 -29
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/span_processors/sensitive-data-filter.d.ts +22 -3
- package/dist/span_processors/sensitive-data-filter.d.ts.map +1 -1
- package/dist/spans/base.d.ts +10 -1
- package/dist/spans/base.d.ts.map +1 -1
- package/dist/spans/default.d.ts.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @mastra/observability
|
|
2
2
|
|
|
3
|
+
## 1.17.0-alpha.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added an `indexed` redaction style to `SensitiveDataFilter`. Instead of collapsing every sensitive value to the same `[REDACTED]` string, each unique value gets a stable token derived from the first matched field name, like `[APIKEY_1]`. ([#21328](https://github.com/mastra-ai/mastra/pull/21328))
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
new SensitiveDataFilter({
|
|
11
|
+
redactionStyle: 'indexed',
|
|
12
|
+
});
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
See [#21313](https://github.com/mastra-ai/mastra/issues/21313)
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [[`898bba4`](https://github.com/mastra-ai/mastra/commit/898bba46d4806dd255a44e5dc3a3d5827eaefdfe), [`f9aab1c`](https://github.com/mastra-ai/mastra/commit/f9aab1cfc3fda03238a7fd7bd8b794e07497878c), [`e31421b`](https://github.com/mastra-ai/mastra/commit/e31421bc9c11c03c6e74f447ecb5820000e2b9d7), [`aece0e7`](https://github.com/mastra-ai/mastra/commit/aece0e7cb124ae1eb1230689b887f5554b9a0bf0)]:
|
|
20
|
+
- @mastra/core@1.59.0-alpha.2
|
|
21
|
+
|
|
22
|
+
## 1.17.0-alpha.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- Fixed traces that start under an external parent span not appearing in Mastra Studio. ([#20499](https://github.com/mastra-ai/mastra/pull/20499))
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [[`088e41e`](https://github.com/mastra-ai/mastra/commit/088e41e434ed05f2c674b254f1034ec46a57a7be), [`b2f0013`](https://github.com/mastra-ai/mastra/commit/b2f0013375588d40c03c13e843b99c0ff8872ca5), [`3b541ae`](https://github.com/mastra-ai/mastra/commit/3b541ae5d410c52b80a7e381d84d021cddb9a449), [`ae79e34`](https://github.com/mastra-ai/mastra/commit/ae79e34c0bd8674fc24c7524217bfc4a051c6136), [`a6c4399`](https://github.com/mastra-ai/mastra/commit/a6c4399763590b3dae21a2c81826e89a3b1deee4)]:
|
|
31
|
+
- @mastra/core@1.59.0-alpha.0
|
|
32
|
+
|
|
3
33
|
## 1.16.6
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ path = __toESM(path, 1);
|
|
|
35
35
|
let stream_web = require("stream/web");
|
|
36
36
|
let _mastra_core_features = require("@mastra/core/features");
|
|
37
37
|
let _mastra_core_storage = require("@mastra/core/storage");
|
|
38
|
+
let crypto = require("crypto");
|
|
38
39
|
//#region src/bus/route-event.ts
|
|
39
40
|
/**
|
|
40
41
|
* Route a single event to the appropriate method on a handler.
|
|
@@ -770,7 +771,11 @@ const observabilityConfigValueSchema = zod_v4.z.object(observabilityInstanceConf
|
|
|
770
771
|
const sensitiveDataFilterOptionsSchema = zod_v4.z.object({
|
|
771
772
|
sensitiveFields: zod_v4.z.array(zod_v4.z.string()).optional(),
|
|
772
773
|
redactionToken: zod_v4.z.string().optional(),
|
|
773
|
-
redactionStyle: zod_v4.z.enum([
|
|
774
|
+
redactionStyle: zod_v4.z.enum([
|
|
775
|
+
"full",
|
|
776
|
+
"partial",
|
|
777
|
+
"indexed"
|
|
778
|
+
]).optional()
|
|
774
779
|
}).strict();
|
|
775
780
|
const observabilityRegistryConfigSchema = zod_v4.z.object({
|
|
776
781
|
default: zod_v4.z.object({ enabled: zod_v4.z.boolean().optional() }).optional().nullable(),
|
|
@@ -2541,8 +2546,10 @@ var BaseSpan = class {
|
|
|
2541
2546
|
entityId;
|
|
2542
2547
|
/** Entity name that created the span */
|
|
2543
2548
|
entityName;
|
|
2544
|
-
/** Parent span
|
|
2549
|
+
/** Parent span within this Mastra trace: a span Mastra created (the span-tree parent, or a prior Mastra span such as the suspended run a resume links back to) */
|
|
2545
2550
|
parentSpanId;
|
|
2551
|
+
/** Parent from an external tracing system (ambient OTel / dd-trace span) that Mastra did not create; carried for external correlation, not part of Mastra's own parent/child linkage */
|
|
2552
|
+
externalParentSpanId;
|
|
2546
2553
|
/** Deep clean options for serialization */
|
|
2547
2554
|
deepCleanOptions;
|
|
2548
2555
|
/**
|
|
@@ -2649,6 +2656,17 @@ var BaseSpan = class {
|
|
|
2649
2656
|
if (parentSpan) return parentSpan.id;
|
|
2650
2657
|
return this.parent.getParentSpanId(includeInternalSpans);
|
|
2651
2658
|
}
|
|
2659
|
+
/**
|
|
2660
|
+
* External (foreign tracing-system) parent id to export alongside
|
|
2661
|
+
* {@link getParentSpanId}. When every Mastra ancestor is dropped from
|
|
2662
|
+
* export, the span is exported at the root's position, so the root's
|
|
2663
|
+
* external parent must travel with it.
|
|
2664
|
+
*/
|
|
2665
|
+
getExportedExternalParentSpanId(includeInternalSpans) {
|
|
2666
|
+
if (!this.parent) return this.externalParentSpanId;
|
|
2667
|
+
if (this.getParentSpan(includeInternalSpans)) return this.externalParentSpanId;
|
|
2668
|
+
return this.parent.getExportedExternalParentSpanId(includeInternalSpans);
|
|
2669
|
+
}
|
|
2652
2670
|
/** Find the closest parent span of a specific type by walking up the parent chain */
|
|
2653
2671
|
findParent(spanType) {
|
|
2654
2672
|
let current = this.parent;
|
|
@@ -2723,6 +2741,7 @@ var BaseSpan = class {
|
|
|
2723
2741
|
isEvent: this.isEvent,
|
|
2724
2742
|
isRootSpan: this.isRootSpan,
|
|
2725
2743
|
parentSpanId: this.getParentSpanId(includeInternalSpans),
|
|
2744
|
+
externalParentSpanId: this.getExportedExternalParentSpanId(includeInternalSpans),
|
|
2726
2745
|
...this.isRootSpan && this.tags?.length ? { tags: this.tags } : {}
|
|
2727
2746
|
};
|
|
2728
2747
|
}
|
|
@@ -2765,6 +2784,7 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
2765
2784
|
this.id = options.spanId;
|
|
2766
2785
|
this.traceId = options.traceId;
|
|
2767
2786
|
if (options.parentSpanId) this.parentSpanId = options.parentSpanId;
|
|
2787
|
+
if (options.externalParentSpanId) this.externalParentSpanId = options.externalParentSpanId;
|
|
2768
2788
|
return;
|
|
2769
2789
|
}
|
|
2770
2790
|
const bridge = observabilityInstance.getBridge();
|
|
@@ -2773,7 +2793,8 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
2773
2793
|
if (bridgeIds) {
|
|
2774
2794
|
this.id = bridgeIds.spanId;
|
|
2775
2795
|
this.traceId = bridgeIds.traceId;
|
|
2776
|
-
this.parentSpanId = bridgeIds.parentSpanId;
|
|
2796
|
+
this.parentSpanId = options.parentSpanId ?? bridgeIds.parentSpanId;
|
|
2797
|
+
this.externalParentSpanId = options.externalParentSpanId ?? bridgeIds.externalParentSpanId;
|
|
2777
2798
|
return;
|
|
2778
2799
|
}
|
|
2779
2800
|
}
|
|
@@ -2787,6 +2808,8 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
2787
2808
|
this.id = generateSpanId();
|
|
2788
2809
|
if (options.parentSpanId) if (isValidSpanId(options.parentSpanId)) this.parentSpanId = options.parentSpanId;
|
|
2789
2810
|
else console.error(`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring.`);
|
|
2811
|
+
if (options.externalParentSpanId) if (isValidSpanId(options.externalParentSpanId)) this.externalParentSpanId = options.externalParentSpanId;
|
|
2812
|
+
else console.error(`[Mastra Tracing] Invalid externalParentSpanId: must be 1-16 hexadecimal characters, got "${options.externalParentSpanId}". Ignoring.`);
|
|
2790
2813
|
}
|
|
2791
2814
|
end(options) {
|
|
2792
2815
|
if (this.isEvent) return;
|
|
@@ -3035,11 +3058,13 @@ var BaseObservabilityInstance = class extends _mastra_core_base.MastraBase {
|
|
|
3035
3058
|
} : enrichedMetadata;
|
|
3036
3059
|
const tags = !options.parent ? tracingOptions?.tags : void 0;
|
|
3037
3060
|
const traceId = !options.parent ? options.traceId ?? tracingOptions?.traceId : options.traceId;
|
|
3038
|
-
const parentSpanId =
|
|
3061
|
+
const parentSpanId = options.parentSpanId;
|
|
3062
|
+
const externalParentSpanId = !options.parent ? options.externalParentSpanId ?? tracingOptions?.parentSpanId : options.externalParentSpanId;
|
|
3039
3063
|
const span = this.createSpan({
|
|
3040
3064
|
...rest,
|
|
3041
3065
|
traceId,
|
|
3042
3066
|
parentSpanId,
|
|
3067
|
+
externalParentSpanId,
|
|
3043
3068
|
metadata: finalMetadata,
|
|
3044
3069
|
traceState,
|
|
3045
3070
|
tags,
|
|
@@ -8728,13 +8753,26 @@ var ObservabilityRegistry = class {
|
|
|
8728
8753
|
//#endregion
|
|
8729
8754
|
//#region src/span_processors/sensitive-data-filter.ts
|
|
8730
8755
|
/**
|
|
8756
|
+
* Maximum number of traces to keep indexed-redaction state for.
|
|
8757
|
+
* Spans never signal trace completion, so state is evicted least-recently-used.
|
|
8758
|
+
*/
|
|
8759
|
+
const MAX_TRACKED_TRACES = 1e3;
|
|
8760
|
+
/**
|
|
8761
|
+
* Maximum number of unique values tracked per trace for indexed redaction.
|
|
8762
|
+
* Once reached, new values fall back to the full redaction token while
|
|
8763
|
+
* already-tracked values keep their assigned tokens.
|
|
8764
|
+
*/
|
|
8765
|
+
const MAX_TRACKED_VALUES_PER_TRACE = 1e3;
|
|
8766
|
+
/**
|
|
8731
8767
|
* SensitiveDataFilter
|
|
8732
8768
|
*
|
|
8733
8769
|
* An SpanOutputProcessor that redacts sensitive information from span fields.
|
|
8734
8770
|
*
|
|
8735
8771
|
* - Sensitive keys are matched case-insensitively, normalized to remove separators.
|
|
8736
|
-
* - Sensitive values are redacted using
|
|
8772
|
+
* - Sensitive values are redacted using full, partial, or indexed redaction.
|
|
8737
8773
|
* - Partial redaction always keeps 3 chars at the start and end.
|
|
8774
|
+
* - Indexed redaction assigns each unique value a stable `[LABEL_N]` token,
|
|
8775
|
+
* consistent across all spans of a trace.
|
|
8738
8776
|
* - JSON strings containing sensitive fields are parsed and redacted.
|
|
8739
8777
|
* - If filtering a field fails, the field is replaced with:
|
|
8740
8778
|
* `{ error: { processor: "sensitive-data-filter" } }`
|
|
@@ -8744,6 +8782,7 @@ var SensitiveDataFilter = class {
|
|
|
8744
8782
|
sensitiveFields;
|
|
8745
8783
|
redactionToken;
|
|
8746
8784
|
redactionStyle;
|
|
8785
|
+
traceStates = /* @__PURE__ */ new Map();
|
|
8747
8786
|
constructor(options = {}) {
|
|
8748
8787
|
this.sensitiveFields = (options.sensitiveFields || [
|
|
8749
8788
|
"password",
|
|
@@ -8773,42 +8812,63 @@ var SensitiveDataFilter = class {
|
|
|
8773
8812
|
* @returns A new span with sensitive values redacted
|
|
8774
8813
|
*/
|
|
8775
8814
|
process(span) {
|
|
8776
|
-
|
|
8777
|
-
span.
|
|
8778
|
-
span.
|
|
8779
|
-
span.
|
|
8780
|
-
span.
|
|
8815
|
+
const indexedState = this.redactionStyle === "indexed" ? this.getTraceState(span.traceId) : void 0;
|
|
8816
|
+
span.attributes = this.tryFilter(span.attributes, indexedState);
|
|
8817
|
+
span.metadata = this.tryFilter(span.metadata, indexedState);
|
|
8818
|
+
span.input = this.tryFilter(span.input, indexedState);
|
|
8819
|
+
span.output = this.tryFilter(span.output, indexedState);
|
|
8820
|
+
span.errorInfo = this.tryFilter(span.errorInfo, indexedState);
|
|
8781
8821
|
return span;
|
|
8782
8822
|
}
|
|
8783
8823
|
/**
|
|
8824
|
+
* Get (or create) the indexed-redaction state for a trace.
|
|
8825
|
+
* Uses the Map's insertion order as an LRU: accessed traces are re-inserted,
|
|
8826
|
+
* and the least recently used trace is evicted once the cap is exceeded.
|
|
8827
|
+
*/
|
|
8828
|
+
getTraceState(traceId) {
|
|
8829
|
+
let state = this.traceStates.get(traceId);
|
|
8830
|
+
if (state) this.traceStates.delete(traceId);
|
|
8831
|
+
else state = {
|
|
8832
|
+
tokensByValue: /* @__PURE__ */ new Map(),
|
|
8833
|
+
counters: /* @__PURE__ */ new Map()
|
|
8834
|
+
};
|
|
8835
|
+
this.traceStates.set(traceId, state);
|
|
8836
|
+
while (this.traceStates.size > MAX_TRACKED_TRACES) {
|
|
8837
|
+
const oldest = this.traceStates.keys().next().value;
|
|
8838
|
+
if (oldest === void 0) break;
|
|
8839
|
+
this.traceStates.delete(oldest);
|
|
8840
|
+
}
|
|
8841
|
+
return state;
|
|
8842
|
+
}
|
|
8843
|
+
/**
|
|
8784
8844
|
* Recursively filter objects/arrays for sensitive keys.
|
|
8785
8845
|
* Handles circular references by replacing with a marker.
|
|
8786
8846
|
* Also attempts to parse and redact JSON strings.
|
|
8787
8847
|
*/
|
|
8788
|
-
deepFilter(obj, seen = /* @__PURE__ */ new WeakSet()) {
|
|
8848
|
+
deepFilter(obj, seen = /* @__PURE__ */ new WeakSet(), indexedState) {
|
|
8789
8849
|
if (obj === null || typeof obj !== "object") {
|
|
8790
8850
|
if (typeof obj === "string") {
|
|
8791
8851
|
const trimmed = obj.trim();
|
|
8792
|
-
if (trimmed.startsWith("{") || trimmed.startsWith("[")) return this.redactJsonString(obj);
|
|
8852
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) return this.redactJsonString(obj, indexedState);
|
|
8793
8853
|
}
|
|
8794
8854
|
return obj;
|
|
8795
8855
|
}
|
|
8796
8856
|
if (seen.has(obj)) return "[Circular Reference]";
|
|
8797
8857
|
seen.add(obj);
|
|
8798
8858
|
if (obj instanceof Date) return obj;
|
|
8799
|
-
if (Array.isArray(obj)) return obj.map((item) => this.deepFilter(item, seen));
|
|
8859
|
+
if (Array.isArray(obj)) return obj.map((item) => this.deepFilter(item, seen, indexedState));
|
|
8800
8860
|
const filtered = {};
|
|
8801
8861
|
for (const key of Object.keys(obj)) {
|
|
8802
8862
|
const normKey = this.normalizeKey(key);
|
|
8803
|
-
if (this.isSensitive(normKey)) if (obj[key] && typeof obj[key] === "object") filtered[key] = this.deepFilter(obj[key], seen);
|
|
8804
|
-
else filtered[key] = this.redactValue(obj[key]);
|
|
8805
|
-
else filtered[key] = this.deepFilter(obj[key], seen);
|
|
8863
|
+
if (this.isSensitive(normKey)) if (obj[key] && typeof obj[key] === "object") filtered[key] = this.deepFilter(obj[key], seen, indexedState);
|
|
8864
|
+
else filtered[key] = this.redactValue(obj[key], normKey, indexedState);
|
|
8865
|
+
else filtered[key] = this.deepFilter(obj[key], seen, indexedState);
|
|
8806
8866
|
}
|
|
8807
8867
|
return filtered;
|
|
8808
8868
|
}
|
|
8809
|
-
tryFilter(value) {
|
|
8869
|
+
tryFilter(value, indexedState) {
|
|
8810
8870
|
try {
|
|
8811
|
-
return this.deepFilter(value);
|
|
8871
|
+
return this.deepFilter(value, /* @__PURE__ */ new WeakSet(), indexedState);
|
|
8812
8872
|
} catch {
|
|
8813
8873
|
return { error: { processor: this.name } };
|
|
8814
8874
|
}
|
|
@@ -8838,11 +8898,11 @@ var SensitiveDataFilter = class {
|
|
|
8838
8898
|
* Attempt to parse a string as JSON and redact sensitive fields within it.
|
|
8839
8899
|
* If parsing fails or no sensitive data is found, returns the original string.
|
|
8840
8900
|
*/
|
|
8841
|
-
redactJsonString(str) {
|
|
8901
|
+
redactJsonString(str, indexedState) {
|
|
8842
8902
|
try {
|
|
8843
8903
|
const parsed = JSON.parse(str);
|
|
8844
8904
|
if (parsed && typeof parsed === "object") {
|
|
8845
|
-
const filtered = this.deepFilter(parsed, /* @__PURE__ */ new WeakSet());
|
|
8905
|
+
const filtered = this.deepFilter(parsed, /* @__PURE__ */ new WeakSet(), indexedState);
|
|
8846
8906
|
return JSON.stringify(filtered);
|
|
8847
8907
|
}
|
|
8848
8908
|
return str;
|
|
@@ -8854,17 +8914,36 @@ var SensitiveDataFilter = class {
|
|
|
8854
8914
|
* Redact a sensitive value.
|
|
8855
8915
|
* - Full style: replaces with a fixed token.
|
|
8856
8916
|
* - Partial style: shows 3 chars at start and end, hides the middle.
|
|
8917
|
+
* - Indexed style: replaces with a stable `[LABEL_N]` token, where the label
|
|
8918
|
+
* comes from the normalized field name and the same value always maps to
|
|
8919
|
+
* the same token within a trace.
|
|
8857
8920
|
*
|
|
8858
|
-
* Non-string values are converted to strings before partial redaction.
|
|
8859
|
-
*/
|
|
8860
|
-
redactValue(value) {
|
|
8861
|
-
if (this.redactionStyle === "
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8921
|
+
* Non-string values are converted to strings before partial or indexed redaction.
|
|
8922
|
+
*/
|
|
8923
|
+
redactValue(value, normKey, indexedState) {
|
|
8924
|
+
if (this.redactionStyle === "partial") {
|
|
8925
|
+
const str = String(value);
|
|
8926
|
+
const len = str.length;
|
|
8927
|
+
if (len <= 6) return this.redactionToken;
|
|
8928
|
+
return str.slice(0, 3) + "…" + str.slice(len - 3);
|
|
8929
|
+
}
|
|
8930
|
+
if (this.redactionStyle === "indexed" && indexedState) {
|
|
8931
|
+
const valueKey = (0, crypto.createHash)("sha256").update(String(value)).digest("hex");
|
|
8932
|
+
const existing = indexedState.tokensByValue.get(valueKey);
|
|
8933
|
+
if (existing) return existing;
|
|
8934
|
+
if (indexedState.tokensByValue.size >= MAX_TRACKED_VALUES_PER_TRACE) return this.redactionToken;
|
|
8935
|
+
const label = normKey.toUpperCase();
|
|
8936
|
+
const count = (indexedState.counters.get(label) ?? 0) + 1;
|
|
8937
|
+
indexedState.counters.set(label, count);
|
|
8938
|
+
const token = `[${label}_${count}]`;
|
|
8939
|
+
indexedState.tokensByValue.set(valueKey, token);
|
|
8940
|
+
return token;
|
|
8941
|
+
}
|
|
8942
|
+
return this.redactionToken;
|
|
8943
|
+
}
|
|
8944
|
+
async shutdown() {
|
|
8945
|
+
this.traceStates.clear();
|
|
8866
8946
|
}
|
|
8867
|
-
async shutdown() {}
|
|
8868
8947
|
};
|
|
8869
8948
|
//#endregion
|
|
8870
8949
|
//#region src/default.ts
|