@mastra/observability 0.0.0-span-scorring-test-20251124132129 → 0.0.0-top-level-fix-20251211111608
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 +94 -3
- package/dist/config.d.ts +107 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/exporters/index.d.ts +1 -0
- package/dist/exporters/index.d.ts.map +1 -1
- package/dist/exporters/test.d.ts +13 -0
- package/dist/exporters/test.d.ts.map +1 -0
- package/dist/index.cjs +360 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +358 -33
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts +9 -5
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/model-tracing.d.ts +4 -9
- package/dist/model-tracing.d.ts.map +1 -1
- package/dist/span_processors/sensitive-data-filter.d.ts +7 -0
- package/dist/span_processors/sensitive-data-filter.d.ts.map +1 -1
- package/dist/spans/base.d.ts +39 -0
- package/dist/spans/base.d.ts.map +1 -1
- package/dist/spans/default.d.ts.map +1 -1
- package/dist/tracing-options.d.ts +27 -0
- package/dist/tracing-options.d.ts.map +1 -0
- package/dist/usage.d.ts +21 -0
- package/dist/usage.d.ts.map +1 -0
- package/package.json +7 -5
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,cAAc,UAAU,CAAC;AAGzB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,cAAc,UAAU,CAAC;AAGzB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAGhC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -35,18 +35,38 @@ var observabilityInstanceConfigSchema = z.object({
|
|
|
35
35
|
serviceName: z.string().min(1, "Service name is required"),
|
|
36
36
|
sampling: samplingStrategySchema.optional(),
|
|
37
37
|
exporters: z.array(z.any()).optional(),
|
|
38
|
+
bridge: z.any().optional(),
|
|
38
39
|
spanOutputProcessors: z.array(z.any()).optional(),
|
|
39
40
|
includeInternalSpans: z.boolean().optional(),
|
|
40
41
|
requestContextKeys: z.array(z.string()).optional()
|
|
41
|
-
})
|
|
42
|
+
}).refine(
|
|
43
|
+
(data) => {
|
|
44
|
+
const hasExporters = data.exporters && data.exporters.length > 0;
|
|
45
|
+
const hasBridge = !!data.bridge;
|
|
46
|
+
return hasExporters || hasBridge;
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
message: "At least one exporter or a bridge is required"
|
|
50
|
+
}
|
|
51
|
+
);
|
|
42
52
|
var observabilityConfigValueSchema = z.object({
|
|
43
53
|
serviceName: z.string().min(1, "Service name is required"),
|
|
44
54
|
sampling: samplingStrategySchema.optional(),
|
|
45
55
|
exporters: z.array(z.any()).optional(),
|
|
56
|
+
bridge: z.any().optional(),
|
|
46
57
|
spanOutputProcessors: z.array(z.any()).optional(),
|
|
47
58
|
includeInternalSpans: z.boolean().optional(),
|
|
48
59
|
requestContextKeys: z.array(z.string()).optional()
|
|
49
|
-
})
|
|
60
|
+
}).refine(
|
|
61
|
+
(data) => {
|
|
62
|
+
const hasExporters = data.exporters && data.exporters.length > 0;
|
|
63
|
+
const hasBridge = !!data.bridge;
|
|
64
|
+
return hasExporters || hasBridge;
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
message: "At least one exporter or a bridge is required"
|
|
68
|
+
}
|
|
69
|
+
);
|
|
50
70
|
var observabilityRegistryConfigSchema = z.object({
|
|
51
71
|
default: z.object({
|
|
52
72
|
enabled: z.boolean().optional()
|
|
@@ -73,6 +93,18 @@ var observabilityRegistryConfigSchema = z.object({
|
|
|
73
93
|
{
|
|
74
94
|
message: 'A "configSelector" function is required when multiple configs are specified to determine which config to use.'
|
|
75
95
|
}
|
|
96
|
+
).refine(
|
|
97
|
+
(data) => {
|
|
98
|
+
if (data.configSelector) {
|
|
99
|
+
const isDefaultEnabled = data.default?.enabled === true;
|
|
100
|
+
const hasConfigs = data.configs && typeof data.configs === "object" && !Array.isArray(data.configs) ? Object.keys(data.configs).length > 0 : false;
|
|
101
|
+
return isDefaultEnabled || hasConfigs;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
message: 'A "configSelector" requires at least one config or default observability to be configured.'
|
|
107
|
+
}
|
|
76
108
|
);
|
|
77
109
|
var BaseExporter = class {
|
|
78
110
|
/** Mastra logger instance */
|
|
@@ -893,6 +925,79 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
893
925
|
this.logger.info("DefaultExporter shutdown complete");
|
|
894
926
|
}
|
|
895
927
|
};
|
|
928
|
+
|
|
929
|
+
// src/exporters/test.ts
|
|
930
|
+
var TestExporter = class extends BaseExporter {
|
|
931
|
+
name = "tracing-test-exporter";
|
|
932
|
+
#events = [];
|
|
933
|
+
constructor(config = {}) {
|
|
934
|
+
super(config);
|
|
935
|
+
}
|
|
936
|
+
async _exportTracingEvent(event) {
|
|
937
|
+
this.#events.push(event);
|
|
938
|
+
}
|
|
939
|
+
clearEvents() {
|
|
940
|
+
this.#events = [];
|
|
941
|
+
}
|
|
942
|
+
get events() {
|
|
943
|
+
return this.#events;
|
|
944
|
+
}
|
|
945
|
+
async shutdown() {
|
|
946
|
+
this.logger.info("TestExporter shutdown");
|
|
947
|
+
}
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
// src/usage.ts
|
|
951
|
+
function extractUsageMetrics(usage, providerMetadata) {
|
|
952
|
+
if (!usage) {
|
|
953
|
+
return {};
|
|
954
|
+
}
|
|
955
|
+
const inputDetails = {};
|
|
956
|
+
const outputDetails = {};
|
|
957
|
+
let inputTokens = usage.inputTokens;
|
|
958
|
+
const outputTokens = usage.outputTokens;
|
|
959
|
+
if (usage.cachedInputTokens) {
|
|
960
|
+
inputDetails.cacheRead = usage.cachedInputTokens;
|
|
961
|
+
}
|
|
962
|
+
if (usage.reasoningTokens) {
|
|
963
|
+
outputDetails.reasoning = usage.reasoningTokens;
|
|
964
|
+
}
|
|
965
|
+
const anthropic = providerMetadata?.anthropic;
|
|
966
|
+
if (anthropic) {
|
|
967
|
+
if (anthropic.cacheReadInputTokens) {
|
|
968
|
+
inputDetails.cacheRead = anthropic.cacheReadInputTokens;
|
|
969
|
+
}
|
|
970
|
+
if (anthropic.cacheCreationInputTokens) {
|
|
971
|
+
inputDetails.cacheWrite = anthropic.cacheCreationInputTokens;
|
|
972
|
+
}
|
|
973
|
+
if (anthropic.cacheReadInputTokens || anthropic.cacheCreationInputTokens) {
|
|
974
|
+
inputDetails.text = usage.inputTokens;
|
|
975
|
+
inputTokens = (usage.inputTokens ?? 0) + (anthropic.cacheReadInputTokens ?? 0) + (anthropic.cacheCreationInputTokens ?? 0);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
const google = providerMetadata?.google;
|
|
979
|
+
if (google?.usageMetadata) {
|
|
980
|
+
if (google.usageMetadata.cachedContentTokenCount) {
|
|
981
|
+
inputDetails.cacheRead = google.usageMetadata.cachedContentTokenCount;
|
|
982
|
+
}
|
|
983
|
+
if (google.usageMetadata.thoughtsTokenCount) {
|
|
984
|
+
outputDetails.reasoning = google.usageMetadata.thoughtsTokenCount;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
const result = {
|
|
988
|
+
inputTokens,
|
|
989
|
+
outputTokens
|
|
990
|
+
};
|
|
991
|
+
if (Object.keys(inputDetails).length > 0) {
|
|
992
|
+
result.inputDetails = inputDetails;
|
|
993
|
+
}
|
|
994
|
+
if (Object.keys(outputDetails).length > 0) {
|
|
995
|
+
result.outputDetails = outputDetails;
|
|
996
|
+
}
|
|
997
|
+
return result;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// src/model-tracing.ts
|
|
896
1001
|
var ModelSpanTracker = class {
|
|
897
1002
|
#modelSpan;
|
|
898
1003
|
#currentStepSpan;
|
|
@@ -900,9 +1005,23 @@ var ModelSpanTracker = class {
|
|
|
900
1005
|
#accumulator = {};
|
|
901
1006
|
#stepIndex = 0;
|
|
902
1007
|
#chunkSequence = 0;
|
|
1008
|
+
#completionStartTime;
|
|
1009
|
+
/** Tracks tool output accumulators by toolCallId for consolidating sub-agent streams */
|
|
1010
|
+
#toolOutputAccumulators = /* @__PURE__ */ new Map();
|
|
1011
|
+
/** Tracks toolCallIds that had streaming output (to skip redundant tool-result spans) */
|
|
1012
|
+
#streamedToolCallIds = /* @__PURE__ */ new Set();
|
|
903
1013
|
constructor(modelSpan) {
|
|
904
1014
|
this.#modelSpan = modelSpan;
|
|
905
1015
|
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Capture the completion start time (time to first token) when the first content chunk arrives.
|
|
1018
|
+
*/
|
|
1019
|
+
#captureCompletionStartTime() {
|
|
1020
|
+
if (this.#completionStartTime) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
this.#completionStartTime = /* @__PURE__ */ new Date();
|
|
1024
|
+
}
|
|
906
1025
|
/**
|
|
907
1026
|
* Get the tracing context for creating child spans.
|
|
908
1027
|
* Returns the current step span if active, otherwise the model span.
|
|
@@ -919,10 +1038,16 @@ var ModelSpanTracker = class {
|
|
|
919
1038
|
this.#modelSpan?.error(options);
|
|
920
1039
|
}
|
|
921
1040
|
/**
|
|
922
|
-
* End the generation span
|
|
1041
|
+
* End the generation span with optional raw usage data.
|
|
1042
|
+
* If usage is provided, it will be converted to UsageStats with cache token details.
|
|
923
1043
|
*/
|
|
924
1044
|
endGeneration(options) {
|
|
925
|
-
|
|
1045
|
+
const { usage, providerMetadata, ...spanOptions } = options ?? {};
|
|
1046
|
+
if (spanOptions.attributes) {
|
|
1047
|
+
spanOptions.attributes.completionStartTime = this.#completionStartTime;
|
|
1048
|
+
spanOptions.attributes.usage = extractUsageMetrics(usage, providerMetadata);
|
|
1049
|
+
}
|
|
1050
|
+
this.#modelSpan?.end(spanOptions);
|
|
926
1051
|
}
|
|
927
1052
|
/**
|
|
928
1053
|
* Update the generation span
|
|
@@ -952,9 +1077,10 @@ var ModelSpanTracker = class {
|
|
|
952
1077
|
#endStepSpan(payload) {
|
|
953
1078
|
if (!this.#currentStepSpan) return;
|
|
954
1079
|
const output = payload.output;
|
|
955
|
-
const { usage, ...otherOutput } = output;
|
|
1080
|
+
const { usage: rawUsage, ...otherOutput } = output;
|
|
956
1081
|
const stepResult = payload.stepResult;
|
|
957
1082
|
const metadata = payload.metadata;
|
|
1083
|
+
const usage = extractUsageMetrics(rawUsage, metadata?.providerMetadata);
|
|
958
1084
|
const cleanMetadata = metadata ? { ...metadata } : void 0;
|
|
959
1085
|
if (cleanMetadata?.request) {
|
|
960
1086
|
delete cleanMetadata.request;
|
|
@@ -1127,6 +1253,77 @@ var ModelSpanTracker = class {
|
|
|
1127
1253
|
break;
|
|
1128
1254
|
}
|
|
1129
1255
|
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Handle tool-output chunks from sub-agents.
|
|
1258
|
+
* Consolidates streaming text/reasoning deltas into a single span per tool call.
|
|
1259
|
+
*/
|
|
1260
|
+
#handleToolOutputChunk(chunk) {
|
|
1261
|
+
if (chunk.type !== "tool-output") return;
|
|
1262
|
+
const payload = chunk.payload;
|
|
1263
|
+
const { output, toolCallId, toolName } = payload;
|
|
1264
|
+
let acc = this.#toolOutputAccumulators.get(toolCallId);
|
|
1265
|
+
if (!acc) {
|
|
1266
|
+
if (!this.#currentStepSpan) {
|
|
1267
|
+
this.#startStepSpan();
|
|
1268
|
+
}
|
|
1269
|
+
acc = {
|
|
1270
|
+
toolName: toolName || "unknown",
|
|
1271
|
+
toolCallId,
|
|
1272
|
+
text: "",
|
|
1273
|
+
reasoning: "",
|
|
1274
|
+
sequenceNumber: this.#chunkSequence++,
|
|
1275
|
+
// Name the span 'tool-result' for consistency (tool-call → tool-result)
|
|
1276
|
+
span: this.#currentStepSpan?.createChildSpan({
|
|
1277
|
+
name: `chunk: 'tool-result'`,
|
|
1278
|
+
type: SpanType.MODEL_CHUNK,
|
|
1279
|
+
attributes: {
|
|
1280
|
+
chunkType: "tool-result",
|
|
1281
|
+
sequenceNumber: this.#chunkSequence - 1
|
|
1282
|
+
}
|
|
1283
|
+
})
|
|
1284
|
+
};
|
|
1285
|
+
this.#toolOutputAccumulators.set(toolCallId, acc);
|
|
1286
|
+
}
|
|
1287
|
+
if (output && typeof output === "object" && "type" in output) {
|
|
1288
|
+
const innerType = output.type;
|
|
1289
|
+
switch (innerType) {
|
|
1290
|
+
case "text-delta":
|
|
1291
|
+
if (output.payload?.text) {
|
|
1292
|
+
acc.text += output.payload.text;
|
|
1293
|
+
}
|
|
1294
|
+
break;
|
|
1295
|
+
case "reasoning-delta":
|
|
1296
|
+
if (output.payload?.text) {
|
|
1297
|
+
acc.reasoning += output.payload.text;
|
|
1298
|
+
}
|
|
1299
|
+
break;
|
|
1300
|
+
case "finish":
|
|
1301
|
+
case "workflow-finish":
|
|
1302
|
+
this.#endToolOutputSpan(toolCallId);
|
|
1303
|
+
break;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* End a tool output span and clean up the accumulator
|
|
1309
|
+
*/
|
|
1310
|
+
#endToolOutputSpan(toolCallId) {
|
|
1311
|
+
const acc = this.#toolOutputAccumulators.get(toolCallId);
|
|
1312
|
+
if (!acc) return;
|
|
1313
|
+
const output = {
|
|
1314
|
+
toolCallId: acc.toolCallId,
|
|
1315
|
+
toolName: acc.toolName
|
|
1316
|
+
};
|
|
1317
|
+
if (acc.text) {
|
|
1318
|
+
output.text = acc.text;
|
|
1319
|
+
}
|
|
1320
|
+
if (acc.reasoning) {
|
|
1321
|
+
output.reasoning = acc.reasoning;
|
|
1322
|
+
}
|
|
1323
|
+
acc.span?.end({ output });
|
|
1324
|
+
this.#toolOutputAccumulators.delete(toolCallId);
|
|
1325
|
+
this.#streamedToolCallIds.add(toolCallId);
|
|
1326
|
+
}
|
|
1130
1327
|
/**
|
|
1131
1328
|
* Wraps a stream with model tracing transform to track MODEL_STEP and MODEL_CHUNK spans.
|
|
1132
1329
|
*
|
|
@@ -1137,6 +1334,13 @@ var ModelSpanTracker = class {
|
|
|
1137
1334
|
return stream.pipeThrough(
|
|
1138
1335
|
new TransformStream({
|
|
1139
1336
|
transform: (chunk, controller) => {
|
|
1337
|
+
switch (chunk.type) {
|
|
1338
|
+
case "text-delta":
|
|
1339
|
+
case "tool-call-delta":
|
|
1340
|
+
case "reasoning-delta":
|
|
1341
|
+
this.#captureCompletionStartTime();
|
|
1342
|
+
break;
|
|
1343
|
+
}
|
|
1140
1344
|
controller.enqueue(chunk);
|
|
1141
1345
|
switch (chunk.type) {
|
|
1142
1346
|
case "text-start":
|
|
@@ -1170,6 +1374,19 @@ var ModelSpanTracker = class {
|
|
|
1170
1374
|
case "start":
|
|
1171
1375
|
case "finish":
|
|
1172
1376
|
break;
|
|
1377
|
+
case "tool-output":
|
|
1378
|
+
this.#handleToolOutputChunk(chunk);
|
|
1379
|
+
break;
|
|
1380
|
+
case "tool-result": {
|
|
1381
|
+
const toolCallId = chunk.payload?.toolCallId;
|
|
1382
|
+
if (toolCallId && this.#streamedToolCallIds.has(toolCallId)) {
|
|
1383
|
+
this.#streamedToolCallIds.delete(toolCallId);
|
|
1384
|
+
break;
|
|
1385
|
+
}
|
|
1386
|
+
const { args, ...cleanPayload } = chunk.payload || {};
|
|
1387
|
+
this.#createEventSpan(chunk.type, cleanPayload);
|
|
1388
|
+
break;
|
|
1389
|
+
}
|
|
1173
1390
|
// Default: auto-create event span for all other chunk types
|
|
1174
1391
|
default: {
|
|
1175
1392
|
let outputPayload = chunk.payload;
|
|
@@ -1224,6 +1441,16 @@ function isSpanInternal(spanType, flags) {
|
|
|
1224
1441
|
return false;
|
|
1225
1442
|
}
|
|
1226
1443
|
}
|
|
1444
|
+
function getExternalParentId(options) {
|
|
1445
|
+
if (!options.parent) {
|
|
1446
|
+
return void 0;
|
|
1447
|
+
}
|
|
1448
|
+
if (options.parent.isInternal) {
|
|
1449
|
+
return options.parent.getParentSpanId(false);
|
|
1450
|
+
} else {
|
|
1451
|
+
return options.parent.id;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1227
1454
|
var BaseSpan = class {
|
|
1228
1455
|
name;
|
|
1229
1456
|
type;
|
|
@@ -1238,6 +1465,7 @@ var BaseSpan = class {
|
|
|
1238
1465
|
output;
|
|
1239
1466
|
errorInfo;
|
|
1240
1467
|
metadata;
|
|
1468
|
+
tags;
|
|
1241
1469
|
traceState;
|
|
1242
1470
|
/** Parent span ID (for root spans that are children of external spans) */
|
|
1243
1471
|
parentSpanId;
|
|
@@ -1252,6 +1480,7 @@ var BaseSpan = class {
|
|
|
1252
1480
|
this.isEvent = options.isEvent ?? false;
|
|
1253
1481
|
this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
|
|
1254
1482
|
this.traceState = options.traceState;
|
|
1483
|
+
this.tags = !options.parent && options.tags?.length ? options.tags : void 0;
|
|
1255
1484
|
if (this.isEvent) {
|
|
1256
1485
|
this.output = deepClean(options.output);
|
|
1257
1486
|
} else {
|
|
@@ -1314,12 +1543,36 @@ var BaseSpan = class {
|
|
|
1314
1543
|
errorInfo: this.errorInfo,
|
|
1315
1544
|
isEvent: this.isEvent,
|
|
1316
1545
|
isRootSpan: this.isRootSpan,
|
|
1317
|
-
parentSpanId: this.getParentSpanId(includeInternalSpans)
|
|
1546
|
+
parentSpanId: this.getParentSpanId(includeInternalSpans),
|
|
1547
|
+
// Tags are only included for root spans
|
|
1548
|
+
...this.isRootSpan && this.tags?.length ? { tags: this.tags } : {}
|
|
1318
1549
|
};
|
|
1319
1550
|
}
|
|
1320
1551
|
get externalTraceId() {
|
|
1321
1552
|
return this.isValid ? this.traceId : void 0;
|
|
1322
1553
|
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Execute an async function within this span's tracing context.
|
|
1556
|
+
* Delegates to the bridge if available.
|
|
1557
|
+
*/
|
|
1558
|
+
async executeInContext(fn) {
|
|
1559
|
+
const bridge = this.observabilityInstance.getBridge();
|
|
1560
|
+
if (bridge?.executeInContext) {
|
|
1561
|
+
return bridge.executeInContext(this.id, fn);
|
|
1562
|
+
}
|
|
1563
|
+
return fn();
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Execute a synchronous function within this span's tracing context.
|
|
1567
|
+
* Delegates to the bridge if available.
|
|
1568
|
+
*/
|
|
1569
|
+
executeInContextSync(fn) {
|
|
1570
|
+
const bridge = this.observabilityInstance.getBridge();
|
|
1571
|
+
if (bridge?.executeInContextSync) {
|
|
1572
|
+
return bridge.executeInContextSync(this.id, fn);
|
|
1573
|
+
}
|
|
1574
|
+
return fn();
|
|
1575
|
+
}
|
|
1323
1576
|
};
|
|
1324
1577
|
var DEFAULT_KEYS_TO_STRIP = /* @__PURE__ */ new Set([
|
|
1325
1578
|
"logger",
|
|
@@ -1345,6 +1598,9 @@ function deepClean(value, options = {}, _seen = /* @__PURE__ */ new WeakSet(), _
|
|
|
1345
1598
|
return "[Circular]";
|
|
1346
1599
|
}
|
|
1347
1600
|
_seen.add(value);
|
|
1601
|
+
if (value instanceof Date) {
|
|
1602
|
+
return value;
|
|
1603
|
+
}
|
|
1348
1604
|
if (Array.isArray(value)) {
|
|
1349
1605
|
return value.map((item) => deepClean(item, options, _seen, _depth + 1));
|
|
1350
1606
|
}
|
|
@@ -1366,27 +1622,30 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
1366
1622
|
traceId;
|
|
1367
1623
|
constructor(options, observabilityInstance) {
|
|
1368
1624
|
super(options, observabilityInstance);
|
|
1369
|
-
|
|
1625
|
+
const bridge = observabilityInstance.getBridge();
|
|
1626
|
+
if (bridge && !this.isInternal) {
|
|
1627
|
+
const bridgeIds = bridge.createSpan(options);
|
|
1628
|
+
if (bridgeIds) {
|
|
1629
|
+
this.id = bridgeIds.spanId;
|
|
1630
|
+
this.traceId = bridgeIds.traceId;
|
|
1631
|
+
this.parentSpanId = bridgeIds.parentSpanId;
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1370
1635
|
if (options.parent) {
|
|
1371
1636
|
this.traceId = options.parent.traceId;
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
} else {
|
|
1376
|
-
console.error(
|
|
1377
|
-
`[Mastra Tracing] Invalid traceId: must be 1-32 hexadecimal characters, got "${options.traceId}". Generating new trace ID.`
|
|
1378
|
-
);
|
|
1379
|
-
this.traceId = generateTraceId();
|
|
1380
|
-
}
|
|
1381
|
-
} else {
|
|
1382
|
-
this.traceId = generateTraceId();
|
|
1637
|
+
this.parentSpanId = options.parent.id;
|
|
1638
|
+
this.id = generateSpanId();
|
|
1639
|
+
return;
|
|
1383
1640
|
}
|
|
1384
|
-
|
|
1641
|
+
this.traceId = getOrCreateTraceId(options);
|
|
1642
|
+
this.id = generateSpanId();
|
|
1643
|
+
if (options.parentSpanId) {
|
|
1385
1644
|
if (isValidSpanId(options.parentSpanId)) {
|
|
1386
1645
|
this.parentSpanId = options.parentSpanId;
|
|
1387
1646
|
} else {
|
|
1388
1647
|
console.error(
|
|
1389
|
-
`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring
|
|
1648
|
+
`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring.`
|
|
1390
1649
|
);
|
|
1391
1650
|
}
|
|
1392
1651
|
}
|
|
@@ -1491,6 +1750,18 @@ function isValidTraceId(traceId) {
|
|
|
1491
1750
|
function isValidSpanId(spanId) {
|
|
1492
1751
|
return /^[0-9a-f]{1,16}$/i.test(spanId);
|
|
1493
1752
|
}
|
|
1753
|
+
function getOrCreateTraceId(options) {
|
|
1754
|
+
if (options.traceId) {
|
|
1755
|
+
if (isValidTraceId(options.traceId)) {
|
|
1756
|
+
return options.traceId;
|
|
1757
|
+
} else {
|
|
1758
|
+
console.error(
|
|
1759
|
+
`[Mastra Tracing] Invalid traceId: must be 1-32 hexadecimal characters, got "${options.traceId}". Generating new trace ID.`
|
|
1760
|
+
);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
return generateTraceId();
|
|
1764
|
+
}
|
|
1494
1765
|
|
|
1495
1766
|
// src/spans/no-op.ts
|
|
1496
1767
|
var NoOpSpan = class extends BaseSpan {
|
|
@@ -1523,13 +1794,17 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1523
1794
|
sampling: config.sampling ?? { type: "always" /* ALWAYS */ },
|
|
1524
1795
|
exporters: config.exporters ?? [],
|
|
1525
1796
|
spanOutputProcessors: config.spanOutputProcessors ?? [],
|
|
1797
|
+
bridge: config.bridge ?? void 0,
|
|
1526
1798
|
includeInternalSpans: config.includeInternalSpans ?? false,
|
|
1527
1799
|
requestContextKeys: config.requestContextKeys ?? []
|
|
1528
1800
|
};
|
|
1801
|
+
if (this.config.bridge?.init) {
|
|
1802
|
+
this.config.bridge.init({ config: this.config });
|
|
1803
|
+
}
|
|
1529
1804
|
}
|
|
1530
1805
|
/**
|
|
1531
1806
|
* Override setLogger to add Observability specific initialization log
|
|
1532
|
-
* and propagate logger to exporters
|
|
1807
|
+
* and propagate logger to exporters and bridge
|
|
1533
1808
|
*/
|
|
1534
1809
|
__setLogger(logger) {
|
|
1535
1810
|
super.__setLogger(logger);
|
|
@@ -1538,8 +1813,11 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1538
1813
|
exporter.__setLogger(logger);
|
|
1539
1814
|
}
|
|
1540
1815
|
});
|
|
1816
|
+
if (this.config.bridge?.__setLogger) {
|
|
1817
|
+
this.config.bridge.__setLogger(logger);
|
|
1818
|
+
}
|
|
1541
1819
|
this.logger.debug(
|
|
1542
|
-
`[Observability] Initialized [service=${this.config.serviceName}] [instance=${this.config.name}] [sampling=${this.config.sampling
|
|
1820
|
+
`[Observability] Initialized [service=${this.config.serviceName}] [instance=${this.config.name}] [sampling=${this.config.sampling?.type}] [bridge=${!!this.config.bridge}]`
|
|
1543
1821
|
);
|
|
1544
1822
|
}
|
|
1545
1823
|
// ============================================================================
|
|
@@ -1568,11 +1846,15 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1568
1846
|
} else {
|
|
1569
1847
|
traceState = this.computeTraceState(tracingOptions);
|
|
1570
1848
|
}
|
|
1571
|
-
const
|
|
1849
|
+
const tracingMetadata = !options.parent ? tracingOptions?.metadata : void 0;
|
|
1850
|
+
const mergedMetadata = metadata || tracingMetadata ? { ...metadata, ...tracingMetadata } : void 0;
|
|
1851
|
+
const enrichedMetadata = this.extractMetadataFromRequestContext(requestContext, mergedMetadata, traceState);
|
|
1852
|
+
const tags = !options.parent ? tracingOptions?.tags : void 0;
|
|
1572
1853
|
const span = this.createSpan({
|
|
1573
1854
|
...rest,
|
|
1574
1855
|
metadata: enrichedMetadata,
|
|
1575
|
-
traceState
|
|
1856
|
+
traceState,
|
|
1857
|
+
tags
|
|
1576
1858
|
});
|
|
1577
1859
|
if (span.isEvent) {
|
|
1578
1860
|
this.emitSpanEnded(span);
|
|
@@ -1606,6 +1888,12 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1606
1888
|
getSpanOutputProcessors() {
|
|
1607
1889
|
return [...this.spanOutputProcessors];
|
|
1608
1890
|
}
|
|
1891
|
+
/**
|
|
1892
|
+
* Get the bridge instance if configured
|
|
1893
|
+
*/
|
|
1894
|
+
getBridge() {
|
|
1895
|
+
return this.config.bridge;
|
|
1896
|
+
}
|
|
1609
1897
|
/**
|
|
1610
1898
|
* Get the logger instance (for exporters and other components)
|
|
1611
1899
|
*/
|
|
@@ -1650,7 +1938,9 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1650
1938
|
*/
|
|
1651
1939
|
shouldSample(options) {
|
|
1652
1940
|
const { sampling } = this.config;
|
|
1653
|
-
switch (sampling
|
|
1941
|
+
switch (sampling?.type) {
|
|
1942
|
+
case void 0:
|
|
1943
|
+
return true;
|
|
1654
1944
|
case "always" /* ALWAYS */:
|
|
1655
1945
|
return true;
|
|
1656
1946
|
case "never" /* NEVER */:
|
|
@@ -1782,17 +2072,21 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1782
2072
|
}
|
|
1783
2073
|
}
|
|
1784
2074
|
/**
|
|
1785
|
-
* Export tracing event through all exporters (realtime mode)
|
|
2075
|
+
* Export tracing event through all exporters and bridge (realtime mode)
|
|
1786
2076
|
*/
|
|
1787
2077
|
async exportTracingEvent(event) {
|
|
1788
|
-
const
|
|
2078
|
+
const targets = [
|
|
2079
|
+
...this.exporters
|
|
2080
|
+
];
|
|
2081
|
+
if (this.config.bridge) {
|
|
2082
|
+
targets.push(this.config.bridge);
|
|
2083
|
+
}
|
|
2084
|
+
const exportPromises = targets.map(async (target) => {
|
|
1789
2085
|
try {
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
this.logger.debug(`[Observability] Event exported [exporter=${exporter.name}] [type=${event.type}]`);
|
|
1793
|
-
}
|
|
2086
|
+
await target.exportTracingEvent(event);
|
|
2087
|
+
this.logger.debug(`[Observability] Event exported [target=${target.name}] [type=${event.type}]`);
|
|
1794
2088
|
} catch (error) {
|
|
1795
|
-
this.logger.error(`[Observability] Export error [
|
|
2089
|
+
this.logger.error(`[Observability] Export error [target=${target.name}]`, error);
|
|
1796
2090
|
}
|
|
1797
2091
|
});
|
|
1798
2092
|
await Promise.allSettled(exportPromises);
|
|
@@ -1816,6 +2110,9 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1816
2110
|
...this.exporters.map((e) => e.shutdown()),
|
|
1817
2111
|
...this.spanOutputProcessors.map((p) => p.shutdown())
|
|
1818
2112
|
];
|
|
2113
|
+
if (this.config.bridge) {
|
|
2114
|
+
shutdownPromises.push(this.config.bridge.shutdown());
|
|
2115
|
+
}
|
|
1819
2116
|
await Promise.allSettled(shutdownPromises);
|
|
1820
2117
|
this.logger.info(`[Observability] Shutdown completed [name=${this.name}]`);
|
|
1821
2118
|
}
|
|
@@ -1962,9 +2259,16 @@ var SensitiveDataFilter = class {
|
|
|
1962
2259
|
/**
|
|
1963
2260
|
* Recursively filter objects/arrays for sensitive keys.
|
|
1964
2261
|
* Handles circular references by replacing with a marker.
|
|
2262
|
+
* Also attempts to parse and redact JSON strings.
|
|
1965
2263
|
*/
|
|
1966
2264
|
deepFilter(obj, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1967
2265
|
if (obj === null || typeof obj !== "object") {
|
|
2266
|
+
if (typeof obj === "string") {
|
|
2267
|
+
const trimmed = obj.trim();
|
|
2268
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
2269
|
+
return this.redactJsonString(obj);
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
1968
2272
|
return obj;
|
|
1969
2273
|
}
|
|
1970
2274
|
if (seen.has(obj)) {
|
|
@@ -2017,6 +2321,22 @@ var SensitiveDataFilter = class {
|
|
|
2017
2321
|
return normalizedKey === sensitiveField;
|
|
2018
2322
|
});
|
|
2019
2323
|
}
|
|
2324
|
+
/**
|
|
2325
|
+
* Attempt to parse a string as JSON and redact sensitive fields within it.
|
|
2326
|
+
* If parsing fails or no sensitive data is found, returns the original string.
|
|
2327
|
+
*/
|
|
2328
|
+
redactJsonString(str) {
|
|
2329
|
+
try {
|
|
2330
|
+
const parsed = JSON.parse(str);
|
|
2331
|
+
if (parsed && typeof parsed === "object") {
|
|
2332
|
+
const filtered = this.deepFilter(parsed, /* @__PURE__ */ new WeakSet());
|
|
2333
|
+
return JSON.stringify(filtered);
|
|
2334
|
+
}
|
|
2335
|
+
return str;
|
|
2336
|
+
} catch {
|
|
2337
|
+
return str;
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2020
2340
|
/**
|
|
2021
2341
|
* Redact a sensitive value.
|
|
2022
2342
|
* - Full style: replaces with a fixed token.
|
|
@@ -2169,6 +2489,11 @@ var Observability = class extends MastraBase {
|
|
|
2169
2489
|
}
|
|
2170
2490
|
};
|
|
2171
2491
|
|
|
2172
|
-
|
|
2492
|
+
// src/tracing-options.ts
|
|
2493
|
+
function buildTracingOptions(...updaters) {
|
|
2494
|
+
return updaters.reduce((opts, updater) => updater(opts), {});
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
export { BaseExporter, BaseObservabilityInstance, BaseSpan, CloudExporter, ConsoleExporter, DefaultExporter, DefaultObservabilityInstance, DefaultSpan, ModelSpanTracker, NoOpSpan, Observability, SamplingStrategyType, SensitiveDataFilter, TestExporter, buildTracingOptions, deepClean, getExternalParentId, observabilityConfigValueSchema, observabilityInstanceConfigSchema, observabilityRegistryConfigSchema, samplingStrategySchema };
|
|
2173
2498
|
//# sourceMappingURL=index.js.map
|
|
2174
2499
|
//# sourceMappingURL=index.js.map
|