@mastra/observability 1.0.0-beta.1 → 1.0.0-beta.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/CHANGELOG.md +47 -0
- 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 +300 -29
- 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 +298 -30
- 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 +0 -6
- 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/package.json +8 -6
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,27 @@ 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
|
+
};
|
|
896
949
|
var ModelSpanTracker = class {
|
|
897
950
|
#modelSpan;
|
|
898
951
|
#currentStepSpan;
|
|
@@ -900,9 +953,30 @@ var ModelSpanTracker = class {
|
|
|
900
953
|
#accumulator = {};
|
|
901
954
|
#stepIndex = 0;
|
|
902
955
|
#chunkSequence = 0;
|
|
956
|
+
/** Tracks whether completionStartTime has been captured for this generation */
|
|
957
|
+
#completionStartTimeCaptured = false;
|
|
958
|
+
/** Tracks tool output accumulators by toolCallId for consolidating sub-agent streams */
|
|
959
|
+
#toolOutputAccumulators = /* @__PURE__ */ new Map();
|
|
960
|
+
/** Tracks toolCallIds that had streaming output (to skip redundant tool-result spans) */
|
|
961
|
+
#streamedToolCallIds = /* @__PURE__ */ new Set();
|
|
903
962
|
constructor(modelSpan) {
|
|
904
963
|
this.#modelSpan = modelSpan;
|
|
905
964
|
}
|
|
965
|
+
/**
|
|
966
|
+
* Capture the completion start time (time to first token) when the first content chunk arrives.
|
|
967
|
+
* This is used by observability providers like Langfuse to calculate TTFT metrics.
|
|
968
|
+
*/
|
|
969
|
+
#captureCompletionStartTime() {
|
|
970
|
+
if (this.#completionStartTimeCaptured || !this.#modelSpan) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
this.#completionStartTimeCaptured = true;
|
|
974
|
+
this.#modelSpan.update({
|
|
975
|
+
attributes: {
|
|
976
|
+
completionStartTime: /* @__PURE__ */ new Date()
|
|
977
|
+
}
|
|
978
|
+
});
|
|
979
|
+
}
|
|
906
980
|
/**
|
|
907
981
|
* Get the tracing context for creating child spans.
|
|
908
982
|
* Returns the current step span if active, otherwise the model span.
|
|
@@ -1127,6 +1201,77 @@ var ModelSpanTracker = class {
|
|
|
1127
1201
|
break;
|
|
1128
1202
|
}
|
|
1129
1203
|
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Handle tool-output chunks from sub-agents.
|
|
1206
|
+
* Consolidates streaming text/reasoning deltas into a single span per tool call.
|
|
1207
|
+
*/
|
|
1208
|
+
#handleToolOutputChunk(chunk) {
|
|
1209
|
+
if (chunk.type !== "tool-output") return;
|
|
1210
|
+
const payload = chunk.payload;
|
|
1211
|
+
const { output, toolCallId, toolName } = payload;
|
|
1212
|
+
let acc = this.#toolOutputAccumulators.get(toolCallId);
|
|
1213
|
+
if (!acc) {
|
|
1214
|
+
if (!this.#currentStepSpan) {
|
|
1215
|
+
this.#startStepSpan();
|
|
1216
|
+
}
|
|
1217
|
+
acc = {
|
|
1218
|
+
toolName: toolName || "unknown",
|
|
1219
|
+
toolCallId,
|
|
1220
|
+
text: "",
|
|
1221
|
+
reasoning: "",
|
|
1222
|
+
sequenceNumber: this.#chunkSequence++,
|
|
1223
|
+
// Name the span 'tool-result' for consistency (tool-call → tool-result)
|
|
1224
|
+
span: this.#currentStepSpan?.createChildSpan({
|
|
1225
|
+
name: `chunk: 'tool-result'`,
|
|
1226
|
+
type: SpanType.MODEL_CHUNK,
|
|
1227
|
+
attributes: {
|
|
1228
|
+
chunkType: "tool-result",
|
|
1229
|
+
sequenceNumber: this.#chunkSequence - 1
|
|
1230
|
+
}
|
|
1231
|
+
})
|
|
1232
|
+
};
|
|
1233
|
+
this.#toolOutputAccumulators.set(toolCallId, acc);
|
|
1234
|
+
}
|
|
1235
|
+
if (output && typeof output === "object" && "type" in output) {
|
|
1236
|
+
const innerType = output.type;
|
|
1237
|
+
switch (innerType) {
|
|
1238
|
+
case "text-delta":
|
|
1239
|
+
if (output.payload?.text) {
|
|
1240
|
+
acc.text += output.payload.text;
|
|
1241
|
+
}
|
|
1242
|
+
break;
|
|
1243
|
+
case "reasoning-delta":
|
|
1244
|
+
if (output.payload?.text) {
|
|
1245
|
+
acc.reasoning += output.payload.text;
|
|
1246
|
+
}
|
|
1247
|
+
break;
|
|
1248
|
+
case "finish":
|
|
1249
|
+
case "workflow-finish":
|
|
1250
|
+
this.#endToolOutputSpan(toolCallId);
|
|
1251
|
+
break;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* End a tool output span and clean up the accumulator
|
|
1257
|
+
*/
|
|
1258
|
+
#endToolOutputSpan(toolCallId) {
|
|
1259
|
+
const acc = this.#toolOutputAccumulators.get(toolCallId);
|
|
1260
|
+
if (!acc) return;
|
|
1261
|
+
const output = {
|
|
1262
|
+
toolCallId: acc.toolCallId,
|
|
1263
|
+
toolName: acc.toolName
|
|
1264
|
+
};
|
|
1265
|
+
if (acc.text) {
|
|
1266
|
+
output.text = acc.text;
|
|
1267
|
+
}
|
|
1268
|
+
if (acc.reasoning) {
|
|
1269
|
+
output.reasoning = acc.reasoning;
|
|
1270
|
+
}
|
|
1271
|
+
acc.span?.end({ output });
|
|
1272
|
+
this.#toolOutputAccumulators.delete(toolCallId);
|
|
1273
|
+
this.#streamedToolCallIds.add(toolCallId);
|
|
1274
|
+
}
|
|
1130
1275
|
/**
|
|
1131
1276
|
* Wraps a stream with model tracing transform to track MODEL_STEP and MODEL_CHUNK spans.
|
|
1132
1277
|
*
|
|
@@ -1134,9 +1279,14 @@ var ModelSpanTracker = class {
|
|
|
1134
1279
|
* create MODEL_STEP and MODEL_CHUNK spans for each semantic unit in the stream.
|
|
1135
1280
|
*/
|
|
1136
1281
|
wrapStream(stream) {
|
|
1282
|
+
let captureCompletionStartTime = false;
|
|
1137
1283
|
return stream.pipeThrough(
|
|
1138
1284
|
new TransformStream({
|
|
1139
1285
|
transform: (chunk, controller) => {
|
|
1286
|
+
if (!captureCompletionStartTime) {
|
|
1287
|
+
captureCompletionStartTime = true;
|
|
1288
|
+
this.#captureCompletionStartTime();
|
|
1289
|
+
}
|
|
1140
1290
|
controller.enqueue(chunk);
|
|
1141
1291
|
switch (chunk.type) {
|
|
1142
1292
|
case "text-start":
|
|
@@ -1170,6 +1320,19 @@ var ModelSpanTracker = class {
|
|
|
1170
1320
|
case "start":
|
|
1171
1321
|
case "finish":
|
|
1172
1322
|
break;
|
|
1323
|
+
case "tool-output":
|
|
1324
|
+
this.#handleToolOutputChunk(chunk);
|
|
1325
|
+
break;
|
|
1326
|
+
case "tool-result": {
|
|
1327
|
+
const toolCallId = chunk.payload?.toolCallId;
|
|
1328
|
+
if (toolCallId && this.#streamedToolCallIds.has(toolCallId)) {
|
|
1329
|
+
this.#streamedToolCallIds.delete(toolCallId);
|
|
1330
|
+
break;
|
|
1331
|
+
}
|
|
1332
|
+
const { args, ...cleanPayload } = chunk.payload || {};
|
|
1333
|
+
this.#createEventSpan(chunk.type, cleanPayload);
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1173
1336
|
// Default: auto-create event span for all other chunk types
|
|
1174
1337
|
default: {
|
|
1175
1338
|
let outputPayload = chunk.payload;
|
|
@@ -1224,6 +1387,16 @@ function isSpanInternal(spanType, flags) {
|
|
|
1224
1387
|
return false;
|
|
1225
1388
|
}
|
|
1226
1389
|
}
|
|
1390
|
+
function getExternalParentId(options) {
|
|
1391
|
+
if (!options.parent) {
|
|
1392
|
+
return void 0;
|
|
1393
|
+
}
|
|
1394
|
+
if (options.parent.isInternal) {
|
|
1395
|
+
return options.parent.getParentSpanId(false);
|
|
1396
|
+
} else {
|
|
1397
|
+
return options.parent.id;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1227
1400
|
var BaseSpan = class {
|
|
1228
1401
|
name;
|
|
1229
1402
|
type;
|
|
@@ -1238,6 +1411,7 @@ var BaseSpan = class {
|
|
|
1238
1411
|
output;
|
|
1239
1412
|
errorInfo;
|
|
1240
1413
|
metadata;
|
|
1414
|
+
tags;
|
|
1241
1415
|
traceState;
|
|
1242
1416
|
/** Parent span ID (for root spans that are children of external spans) */
|
|
1243
1417
|
parentSpanId;
|
|
@@ -1252,6 +1426,7 @@ var BaseSpan = class {
|
|
|
1252
1426
|
this.isEvent = options.isEvent ?? false;
|
|
1253
1427
|
this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
|
|
1254
1428
|
this.traceState = options.traceState;
|
|
1429
|
+
this.tags = !options.parent && options.tags?.length ? options.tags : void 0;
|
|
1255
1430
|
if (this.isEvent) {
|
|
1256
1431
|
this.output = deepClean(options.output);
|
|
1257
1432
|
} else {
|
|
@@ -1314,12 +1489,36 @@ var BaseSpan = class {
|
|
|
1314
1489
|
errorInfo: this.errorInfo,
|
|
1315
1490
|
isEvent: this.isEvent,
|
|
1316
1491
|
isRootSpan: this.isRootSpan,
|
|
1317
|
-
parentSpanId: this.getParentSpanId(includeInternalSpans)
|
|
1492
|
+
parentSpanId: this.getParentSpanId(includeInternalSpans),
|
|
1493
|
+
// Tags are only included for root spans
|
|
1494
|
+
...this.isRootSpan && this.tags?.length ? { tags: this.tags } : {}
|
|
1318
1495
|
};
|
|
1319
1496
|
}
|
|
1320
1497
|
get externalTraceId() {
|
|
1321
1498
|
return this.isValid ? this.traceId : void 0;
|
|
1322
1499
|
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Execute an async function within this span's tracing context.
|
|
1502
|
+
* Delegates to the bridge if available.
|
|
1503
|
+
*/
|
|
1504
|
+
async executeInContext(fn) {
|
|
1505
|
+
const bridge = this.observabilityInstance.getBridge();
|
|
1506
|
+
if (bridge?.executeInContext) {
|
|
1507
|
+
return bridge.executeInContext(this.id, fn);
|
|
1508
|
+
}
|
|
1509
|
+
return fn();
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Execute a synchronous function within this span's tracing context.
|
|
1513
|
+
* Delegates to the bridge if available.
|
|
1514
|
+
*/
|
|
1515
|
+
executeInContextSync(fn) {
|
|
1516
|
+
const bridge = this.observabilityInstance.getBridge();
|
|
1517
|
+
if (bridge?.executeInContextSync) {
|
|
1518
|
+
return bridge.executeInContextSync(this.id, fn);
|
|
1519
|
+
}
|
|
1520
|
+
return fn();
|
|
1521
|
+
}
|
|
1323
1522
|
};
|
|
1324
1523
|
var DEFAULT_KEYS_TO_STRIP = /* @__PURE__ */ new Set([
|
|
1325
1524
|
"logger",
|
|
@@ -1366,27 +1565,30 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
1366
1565
|
traceId;
|
|
1367
1566
|
constructor(options, observabilityInstance) {
|
|
1368
1567
|
super(options, observabilityInstance);
|
|
1369
|
-
|
|
1568
|
+
const bridge = observabilityInstance.getBridge();
|
|
1569
|
+
if (bridge && !this.isInternal) {
|
|
1570
|
+
const bridgeIds = bridge.createSpan(options);
|
|
1571
|
+
if (bridgeIds) {
|
|
1572
|
+
this.id = bridgeIds.spanId;
|
|
1573
|
+
this.traceId = bridgeIds.traceId;
|
|
1574
|
+
this.parentSpanId = bridgeIds.parentSpanId;
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1370
1578
|
if (options.parent) {
|
|
1371
1579
|
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();
|
|
1580
|
+
this.parentSpanId = options.parent.id;
|
|
1581
|
+
this.id = generateSpanId();
|
|
1582
|
+
return;
|
|
1383
1583
|
}
|
|
1384
|
-
|
|
1584
|
+
this.traceId = getOrCreateTraceId(options);
|
|
1585
|
+
this.id = generateSpanId();
|
|
1586
|
+
if (options.parentSpanId) {
|
|
1385
1587
|
if (isValidSpanId(options.parentSpanId)) {
|
|
1386
1588
|
this.parentSpanId = options.parentSpanId;
|
|
1387
1589
|
} else {
|
|
1388
1590
|
console.error(
|
|
1389
|
-
`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring
|
|
1591
|
+
`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring.`
|
|
1390
1592
|
);
|
|
1391
1593
|
}
|
|
1392
1594
|
}
|
|
@@ -1491,6 +1693,18 @@ function isValidTraceId(traceId) {
|
|
|
1491
1693
|
function isValidSpanId(spanId) {
|
|
1492
1694
|
return /^[0-9a-f]{1,16}$/i.test(spanId);
|
|
1493
1695
|
}
|
|
1696
|
+
function getOrCreateTraceId(options) {
|
|
1697
|
+
if (options.traceId) {
|
|
1698
|
+
if (isValidTraceId(options.traceId)) {
|
|
1699
|
+
return options.traceId;
|
|
1700
|
+
} else {
|
|
1701
|
+
console.error(
|
|
1702
|
+
`[Mastra Tracing] Invalid traceId: must be 1-32 hexadecimal characters, got "${options.traceId}". Generating new trace ID.`
|
|
1703
|
+
);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return generateTraceId();
|
|
1707
|
+
}
|
|
1494
1708
|
|
|
1495
1709
|
// src/spans/no-op.ts
|
|
1496
1710
|
var NoOpSpan = class extends BaseSpan {
|
|
@@ -1523,13 +1737,17 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1523
1737
|
sampling: config.sampling ?? { type: "always" /* ALWAYS */ },
|
|
1524
1738
|
exporters: config.exporters ?? [],
|
|
1525
1739
|
spanOutputProcessors: config.spanOutputProcessors ?? [],
|
|
1740
|
+
bridge: config.bridge ?? void 0,
|
|
1526
1741
|
includeInternalSpans: config.includeInternalSpans ?? false,
|
|
1527
1742
|
requestContextKeys: config.requestContextKeys ?? []
|
|
1528
1743
|
};
|
|
1744
|
+
if (this.config.bridge?.init) {
|
|
1745
|
+
this.config.bridge.init({ config: this.config });
|
|
1746
|
+
}
|
|
1529
1747
|
}
|
|
1530
1748
|
/**
|
|
1531
1749
|
* Override setLogger to add Observability specific initialization log
|
|
1532
|
-
* and propagate logger to exporters
|
|
1750
|
+
* and propagate logger to exporters and bridge
|
|
1533
1751
|
*/
|
|
1534
1752
|
__setLogger(logger) {
|
|
1535
1753
|
super.__setLogger(logger);
|
|
@@ -1538,8 +1756,11 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1538
1756
|
exporter.__setLogger(logger);
|
|
1539
1757
|
}
|
|
1540
1758
|
});
|
|
1759
|
+
if (this.config.bridge?.__setLogger) {
|
|
1760
|
+
this.config.bridge.__setLogger(logger);
|
|
1761
|
+
}
|
|
1541
1762
|
this.logger.debug(
|
|
1542
|
-
`[Observability] Initialized [service=${this.config.serviceName}] [instance=${this.config.name}] [sampling=${this.config.sampling
|
|
1763
|
+
`[Observability] Initialized [service=${this.config.serviceName}] [instance=${this.config.name}] [sampling=${this.config.sampling?.type}] [bridge=${!!this.config.bridge}]`
|
|
1543
1764
|
);
|
|
1544
1765
|
}
|
|
1545
1766
|
// ============================================================================
|
|
@@ -1568,11 +1789,15 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1568
1789
|
} else {
|
|
1569
1790
|
traceState = this.computeTraceState(tracingOptions);
|
|
1570
1791
|
}
|
|
1571
|
-
const
|
|
1792
|
+
const tracingMetadata = !options.parent ? tracingOptions?.metadata : void 0;
|
|
1793
|
+
const mergedMetadata = metadata || tracingMetadata ? { ...metadata, ...tracingMetadata } : void 0;
|
|
1794
|
+
const enrichedMetadata = this.extractMetadataFromRequestContext(requestContext, mergedMetadata, traceState);
|
|
1795
|
+
const tags = !options.parent ? tracingOptions?.tags : void 0;
|
|
1572
1796
|
const span = this.createSpan({
|
|
1573
1797
|
...rest,
|
|
1574
1798
|
metadata: enrichedMetadata,
|
|
1575
|
-
traceState
|
|
1799
|
+
traceState,
|
|
1800
|
+
tags
|
|
1576
1801
|
});
|
|
1577
1802
|
if (span.isEvent) {
|
|
1578
1803
|
this.emitSpanEnded(span);
|
|
@@ -1606,6 +1831,12 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1606
1831
|
getSpanOutputProcessors() {
|
|
1607
1832
|
return [...this.spanOutputProcessors];
|
|
1608
1833
|
}
|
|
1834
|
+
/**
|
|
1835
|
+
* Get the bridge instance if configured
|
|
1836
|
+
*/
|
|
1837
|
+
getBridge() {
|
|
1838
|
+
return this.config.bridge;
|
|
1839
|
+
}
|
|
1609
1840
|
/**
|
|
1610
1841
|
* Get the logger instance (for exporters and other components)
|
|
1611
1842
|
*/
|
|
@@ -1650,7 +1881,9 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1650
1881
|
*/
|
|
1651
1882
|
shouldSample(options) {
|
|
1652
1883
|
const { sampling } = this.config;
|
|
1653
|
-
switch (sampling
|
|
1884
|
+
switch (sampling?.type) {
|
|
1885
|
+
case void 0:
|
|
1886
|
+
return true;
|
|
1654
1887
|
case "always" /* ALWAYS */:
|
|
1655
1888
|
return true;
|
|
1656
1889
|
case "never" /* NEVER */:
|
|
@@ -1782,17 +2015,21 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1782
2015
|
}
|
|
1783
2016
|
}
|
|
1784
2017
|
/**
|
|
1785
|
-
* Export tracing event through all exporters (realtime mode)
|
|
2018
|
+
* Export tracing event through all exporters and bridge (realtime mode)
|
|
1786
2019
|
*/
|
|
1787
2020
|
async exportTracingEvent(event) {
|
|
1788
|
-
const
|
|
2021
|
+
const targets = [
|
|
2022
|
+
...this.exporters
|
|
2023
|
+
];
|
|
2024
|
+
if (this.config.bridge) {
|
|
2025
|
+
targets.push(this.config.bridge);
|
|
2026
|
+
}
|
|
2027
|
+
const exportPromises = targets.map(async (target) => {
|
|
1789
2028
|
try {
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
this.logger.debug(`[Observability] Event exported [exporter=${exporter.name}] [type=${event.type}]`);
|
|
1793
|
-
}
|
|
2029
|
+
await target.exportTracingEvent(event);
|
|
2030
|
+
this.logger.debug(`[Observability] Event exported [target=${target.name}] [type=${event.type}]`);
|
|
1794
2031
|
} catch (error) {
|
|
1795
|
-
this.logger.error(`[Observability] Export error [
|
|
2032
|
+
this.logger.error(`[Observability] Export error [target=${target.name}]`, error);
|
|
1796
2033
|
}
|
|
1797
2034
|
});
|
|
1798
2035
|
await Promise.allSettled(exportPromises);
|
|
@@ -1816,6 +2053,9 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
1816
2053
|
...this.exporters.map((e) => e.shutdown()),
|
|
1817
2054
|
...this.spanOutputProcessors.map((p) => p.shutdown())
|
|
1818
2055
|
];
|
|
2056
|
+
if (this.config.bridge) {
|
|
2057
|
+
shutdownPromises.push(this.config.bridge.shutdown());
|
|
2058
|
+
}
|
|
1819
2059
|
await Promise.allSettled(shutdownPromises);
|
|
1820
2060
|
this.logger.info(`[Observability] Shutdown completed [name=${this.name}]`);
|
|
1821
2061
|
}
|
|
@@ -1962,9 +2202,16 @@ var SensitiveDataFilter = class {
|
|
|
1962
2202
|
/**
|
|
1963
2203
|
* Recursively filter objects/arrays for sensitive keys.
|
|
1964
2204
|
* Handles circular references by replacing with a marker.
|
|
2205
|
+
* Also attempts to parse and redact JSON strings.
|
|
1965
2206
|
*/
|
|
1966
2207
|
deepFilter(obj, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1967
2208
|
if (obj === null || typeof obj !== "object") {
|
|
2209
|
+
if (typeof obj === "string") {
|
|
2210
|
+
const trimmed = obj.trim();
|
|
2211
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
2212
|
+
return this.redactJsonString(obj);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
1968
2215
|
return obj;
|
|
1969
2216
|
}
|
|
1970
2217
|
if (seen.has(obj)) {
|
|
@@ -2017,6 +2264,22 @@ var SensitiveDataFilter = class {
|
|
|
2017
2264
|
return normalizedKey === sensitiveField;
|
|
2018
2265
|
});
|
|
2019
2266
|
}
|
|
2267
|
+
/**
|
|
2268
|
+
* Attempt to parse a string as JSON and redact sensitive fields within it.
|
|
2269
|
+
* If parsing fails or no sensitive data is found, returns the original string.
|
|
2270
|
+
*/
|
|
2271
|
+
redactJsonString(str) {
|
|
2272
|
+
try {
|
|
2273
|
+
const parsed = JSON.parse(str);
|
|
2274
|
+
if (parsed && typeof parsed === "object") {
|
|
2275
|
+
const filtered = this.deepFilter(parsed, /* @__PURE__ */ new WeakSet());
|
|
2276
|
+
return JSON.stringify(filtered);
|
|
2277
|
+
}
|
|
2278
|
+
return str;
|
|
2279
|
+
} catch {
|
|
2280
|
+
return str;
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2020
2283
|
/**
|
|
2021
2284
|
* Redact a sensitive value.
|
|
2022
2285
|
* - Full style: replaces with a fixed token.
|
|
@@ -2169,6 +2432,11 @@ var Observability = class extends MastraBase {
|
|
|
2169
2432
|
}
|
|
2170
2433
|
};
|
|
2171
2434
|
|
|
2172
|
-
|
|
2435
|
+
// src/tracing-options.ts
|
|
2436
|
+
function buildTracingOptions(...updaters) {
|
|
2437
|
+
return updaters.reduce((opts, updater) => updater(opts), {});
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
export { BaseExporter, BaseObservabilityInstance, BaseSpan, CloudExporter, ConsoleExporter, DefaultExporter, DefaultObservabilityInstance, DefaultSpan, ModelSpanTracker, NoOpSpan, Observability, SamplingStrategyType, SensitiveDataFilter, TestExporter, buildTracingOptions, deepClean, getExternalParentId, observabilityConfigValueSchema, observabilityInstanceConfigSchema, observabilityRegistryConfigSchema, samplingStrategySchema };
|
|
2173
2441
|
//# sourceMappingURL=index.js.map
|
|
2174
2442
|
//# sourceMappingURL=index.js.map
|