@mastra/observability 1.6.0-alpha.1 → 1.6.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/context/logger.d.ts +4 -0
- package/dist/context/logger.d.ts.map +1 -1
- package/dist/context/metrics.d.ts +6 -0
- package/dist/context/metrics.d.ts.map +1 -1
- package/dist/default.d.ts +14 -1
- package/dist/default.d.ts.map +1 -1
- package/dist/index.cjs +471 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +471 -46
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts +5 -0
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/recorded.d.ts +43 -0
- package/dist/recorded.d.ts.map +1 -0
- package/dist/spans/default.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -14,6 +14,47 @@ var __export = (target, all) => {
|
|
|
14
14
|
for (var name in all)
|
|
15
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
16
|
};
|
|
17
|
+
function routeToHandler(handler, event, logger) {
|
|
18
|
+
try {
|
|
19
|
+
switch (event.type) {
|
|
20
|
+
case TracingEventType.SPAN_STARTED:
|
|
21
|
+
case TracingEventType.SPAN_UPDATED:
|
|
22
|
+
case TracingEventType.SPAN_ENDED: {
|
|
23
|
+
const fn = handler.onTracingEvent ? handler.onTracingEvent.bind(handler) : handler.exportTracingEvent.bind(handler);
|
|
24
|
+
return catchAsyncResult(fn(event), handler.name, "tracing", logger);
|
|
25
|
+
}
|
|
26
|
+
case "log":
|
|
27
|
+
if (handler.onLogEvent) {
|
|
28
|
+
return catchAsyncResult(handler.onLogEvent(event), handler.name, "log", logger);
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
case "metric":
|
|
32
|
+
if (handler.onMetricEvent) {
|
|
33
|
+
return catchAsyncResult(handler.onMetricEvent(event), handler.name, "metric", logger);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case "score":
|
|
37
|
+
if (handler.onScoreEvent) {
|
|
38
|
+
return catchAsyncResult(handler.onScoreEvent(event), handler.name, "score", logger);
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
case "feedback":
|
|
42
|
+
if (handler.onFeedbackEvent) {
|
|
43
|
+
return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
} catch (err) {
|
|
48
|
+
logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function catchAsyncResult(result, handlerName, signal, logger) {
|
|
52
|
+
if (result && typeof result.then === "function") {
|
|
53
|
+
return result.catch((err) => {
|
|
54
|
+
logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
17
58
|
|
|
18
59
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
19
60
|
var external_exports = {};
|
|
@@ -15893,7 +15934,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
15893
15934
|
this.#trackEvent("log");
|
|
15894
15935
|
if (this.#config.storeLogs) {
|
|
15895
15936
|
const log = event.log;
|
|
15896
|
-
const traceId = log.
|
|
15937
|
+
const traceId = log.traceId;
|
|
15897
15938
|
const logMessage = `[TestExporter] log.${log.level}: "${log.message}"${traceId ? ` (trace: ${traceId.slice(-8)})` : ""}`;
|
|
15898
15939
|
this.#debugLogs.push(logMessage);
|
|
15899
15940
|
}
|
|
@@ -16011,7 +16052,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
16011
16052
|
getByTraceId(traceId) {
|
|
16012
16053
|
const events = this.#tracingEvents.filter((e) => e.exportedSpan.traceId === traceId);
|
|
16013
16054
|
const spans = this.#getUniqueSpansFromEvents(events);
|
|
16014
|
-
const logs = this.#logEvents.filter((e) => e.log.
|
|
16055
|
+
const logs = this.#logEvents.filter((e) => e.log.traceId === traceId).map((e) => e.log);
|
|
16015
16056
|
const scores = this.#scoreEvents.filter((e) => e.score.traceId === traceId).map((e) => e.score);
|
|
16016
16057
|
const feedback = this.#feedbackEvents.filter((e) => e.feedback.traceId === traceId).map((e) => e.feedback);
|
|
16017
16058
|
return { events, spans, logs, scores, feedback };
|
|
@@ -16078,7 +16119,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
16078
16119
|
traceIds.add(event.exportedSpan.traceId);
|
|
16079
16120
|
}
|
|
16080
16121
|
for (const event of this.#logEvents) {
|
|
16081
|
-
if (event.log.
|
|
16122
|
+
if (event.log.traceId) traceIds.add(event.log.traceId);
|
|
16082
16123
|
}
|
|
16083
16124
|
for (const event of this.#scoreEvents) {
|
|
16084
16125
|
traceIds.add(event.score.traceId);
|
|
@@ -16113,7 +16154,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
16113
16154
|
* Get logs for a specific trace
|
|
16114
16155
|
*/
|
|
16115
16156
|
getLogsByTraceId(traceId) {
|
|
16116
|
-
return this.#logEvents.filter((e) => e.log.
|
|
16157
|
+
return this.#logEvents.filter((e) => e.log.traceId === traceId).map((e) => e.log);
|
|
16117
16158
|
}
|
|
16118
16159
|
// ============================================================================
|
|
16119
16160
|
// Metric Query Methods
|
|
@@ -16987,47 +17028,6 @@ var BaseObservabilityEventBus = class _BaseObservabilityEventBus extends MastraB
|
|
|
16987
17028
|
this.subscribers.clear();
|
|
16988
17029
|
}
|
|
16989
17030
|
};
|
|
16990
|
-
function routeToHandler(handler, event, logger) {
|
|
16991
|
-
try {
|
|
16992
|
-
switch (event.type) {
|
|
16993
|
-
case TracingEventType.SPAN_STARTED:
|
|
16994
|
-
case TracingEventType.SPAN_UPDATED:
|
|
16995
|
-
case TracingEventType.SPAN_ENDED: {
|
|
16996
|
-
const fn = handler.onTracingEvent ? handler.onTracingEvent.bind(handler) : handler.exportTracingEvent.bind(handler);
|
|
16997
|
-
return catchAsyncResult(fn(event), handler.name, "tracing", logger);
|
|
16998
|
-
}
|
|
16999
|
-
case "log":
|
|
17000
|
-
if (handler.onLogEvent) {
|
|
17001
|
-
return catchAsyncResult(handler.onLogEvent(event), handler.name, "log", logger);
|
|
17002
|
-
}
|
|
17003
|
-
break;
|
|
17004
|
-
case "metric":
|
|
17005
|
-
if (handler.onMetricEvent) {
|
|
17006
|
-
return catchAsyncResult(handler.onMetricEvent(event), handler.name, "metric", logger);
|
|
17007
|
-
}
|
|
17008
|
-
break;
|
|
17009
|
-
case "score":
|
|
17010
|
-
if (handler.onScoreEvent) {
|
|
17011
|
-
return catchAsyncResult(handler.onScoreEvent(event), handler.name, "score", logger);
|
|
17012
|
-
}
|
|
17013
|
-
break;
|
|
17014
|
-
case "feedback":
|
|
17015
|
-
if (handler.onFeedbackEvent) {
|
|
17016
|
-
return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
|
|
17017
|
-
}
|
|
17018
|
-
break;
|
|
17019
|
-
}
|
|
17020
|
-
} catch (err) {
|
|
17021
|
-
logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
|
|
17022
|
-
}
|
|
17023
|
-
}
|
|
17024
|
-
function catchAsyncResult(result, handlerName, signal, logger) {
|
|
17025
|
-
if (result && typeof result.then === "function") {
|
|
17026
|
-
return result.catch((err) => {
|
|
17027
|
-
logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
|
|
17028
|
-
});
|
|
17029
|
-
}
|
|
17030
|
-
}
|
|
17031
17031
|
|
|
17032
17032
|
// src/bus/observability-bus.ts
|
|
17033
17033
|
var MAX_FLUSH_ITERATIONS = 3;
|
|
@@ -17187,9 +17187,12 @@ var LoggerContextImpl = class {
|
|
|
17187
17187
|
* mutations after construction do not affect emitted logs.
|
|
17188
17188
|
*/
|
|
17189
17189
|
constructor(config2) {
|
|
17190
|
+
const correlationContext = config2.correlationContext ? { ...config2.correlationContext } : void 0;
|
|
17190
17191
|
this.config = {
|
|
17191
17192
|
...config2,
|
|
17192
|
-
|
|
17193
|
+
traceId: config2.traceId ?? correlationContext?.traceId,
|
|
17194
|
+
spanId: config2.spanId ?? correlationContext?.spanId,
|
|
17195
|
+
correlationContext,
|
|
17193
17196
|
metadata: config2.metadata ? structuredClone(config2.metadata) : void 0
|
|
17194
17197
|
};
|
|
17195
17198
|
}
|
|
@@ -17226,6 +17229,8 @@ var LoggerContextImpl = class {
|
|
|
17226
17229
|
level,
|
|
17227
17230
|
message,
|
|
17228
17231
|
data,
|
|
17232
|
+
traceId: this.config.traceId,
|
|
17233
|
+
spanId: this.config.spanId,
|
|
17229
17234
|
correlationContext: this.config.correlationContext,
|
|
17230
17235
|
metadata: this.config.metadata
|
|
17231
17236
|
};
|
|
@@ -17236,6 +17241,8 @@ var LoggerContextImpl = class {
|
|
|
17236
17241
|
|
|
17237
17242
|
// src/context/metrics.ts
|
|
17238
17243
|
var MetricsContextImpl = class {
|
|
17244
|
+
traceId;
|
|
17245
|
+
spanId;
|
|
17239
17246
|
correlationContext;
|
|
17240
17247
|
metadata;
|
|
17241
17248
|
cardinalityFilter;
|
|
@@ -17246,6 +17253,8 @@ var MetricsContextImpl = class {
|
|
|
17246
17253
|
*/
|
|
17247
17254
|
constructor(config2) {
|
|
17248
17255
|
this.correlationContext = config2.correlationContext ? { ...config2.correlationContext } : void 0;
|
|
17256
|
+
this.traceId = config2.traceId ?? this.correlationContext?.traceId;
|
|
17257
|
+
this.spanId = config2.spanId ?? this.correlationContext?.spanId;
|
|
17249
17258
|
this.metadata = config2.metadata ? structuredClone(config2.metadata) : void 0;
|
|
17250
17259
|
this.cardinalityFilter = config2.cardinalityFilter;
|
|
17251
17260
|
this.observabilityBus = config2.observabilityBus;
|
|
@@ -17259,6 +17268,8 @@ var MetricsContextImpl = class {
|
|
|
17259
17268
|
const costContext = options?.costContext ? cloneCostContext(options.costContext) : void 0;
|
|
17260
17269
|
const exportedMetric = {
|
|
17261
17270
|
timestamp: /* @__PURE__ */ new Date(),
|
|
17271
|
+
traceId: this.traceId,
|
|
17272
|
+
spanId: this.spanId,
|
|
17262
17273
|
name,
|
|
17263
17274
|
value,
|
|
17264
17275
|
labels: filteredLabels,
|
|
@@ -18895,6 +18906,9 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
18895
18906
|
if (this.isEvent) {
|
|
18896
18907
|
return;
|
|
18897
18908
|
}
|
|
18909
|
+
if (options.name !== void 0) {
|
|
18910
|
+
this.name = options.name;
|
|
18911
|
+
}
|
|
18898
18912
|
if (options.input !== void 0) {
|
|
18899
18913
|
this.input = deepClean(options.input, this.deepCleanOptions);
|
|
18900
18914
|
}
|
|
@@ -19190,6 +19204,8 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
19190
19204
|
const correlationContext = span?.getCorrelationContext?.();
|
|
19191
19205
|
const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
|
|
19192
19206
|
return new LoggerContextImpl({
|
|
19207
|
+
traceId: span?.traceId,
|
|
19208
|
+
spanId: span?.id,
|
|
19193
19209
|
correlationContext,
|
|
19194
19210
|
metadata,
|
|
19195
19211
|
observabilityBus: this.observabilityBus
|
|
@@ -19204,6 +19220,8 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
19204
19220
|
const correlationContext = span?.getCorrelationContext?.();
|
|
19205
19221
|
const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
|
|
19206
19222
|
return new MetricsContextImpl({
|
|
19223
|
+
traceId: span?.traceId,
|
|
19224
|
+
spanId: span?.id,
|
|
19207
19225
|
correlationContext,
|
|
19208
19226
|
metadata,
|
|
19209
19227
|
cardinalityFilter: this.cardinalityFilter,
|
|
@@ -19218,6 +19236,13 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
19218
19236
|
emitObservabilityEvent(event) {
|
|
19219
19237
|
this.observabilityBus.emit(event);
|
|
19220
19238
|
}
|
|
19239
|
+
/**
|
|
19240
|
+
* Internal hook used by RecordedTrace/RecordedSpan hydration to route
|
|
19241
|
+
* non-tracing annotation events back through the normal exporter pipeline.
|
|
19242
|
+
*/
|
|
19243
|
+
__emitRecordedEvent(event) {
|
|
19244
|
+
this.emitObservabilityEvent(event);
|
|
19245
|
+
}
|
|
19221
19246
|
// ============================================================================
|
|
19222
19247
|
// Span Lifecycle Management
|
|
19223
19248
|
// ============================================================================
|
|
@@ -19492,6 +19517,311 @@ var DefaultObservabilityInstance = class extends BaseObservabilityInstance {
|
|
|
19492
19517
|
}
|
|
19493
19518
|
};
|
|
19494
19519
|
|
|
19520
|
+
// src/recorded.ts
|
|
19521
|
+
function nullToUndefined(value) {
|
|
19522
|
+
return value ?? void 0;
|
|
19523
|
+
}
|
|
19524
|
+
function mergeMetadata(base, extra) {
|
|
19525
|
+
if (!base && !extra) return void 0;
|
|
19526
|
+
return {
|
|
19527
|
+
...base ?? {},
|
|
19528
|
+
...extra ?? {}
|
|
19529
|
+
};
|
|
19530
|
+
}
|
|
19531
|
+
function normalizeErrorInfo(error48) {
|
|
19532
|
+
if (!error48 || typeof error48 !== "object" || !("message" in error48) || typeof error48.message !== "string") {
|
|
19533
|
+
return void 0;
|
|
19534
|
+
}
|
|
19535
|
+
return {
|
|
19536
|
+
message: error48.message,
|
|
19537
|
+
id: "id" in error48 && typeof error48.id === "string" ? error48.id : void 0,
|
|
19538
|
+
domain: "domain" in error48 && typeof error48.domain === "string" ? error48.domain : void 0,
|
|
19539
|
+
category: "category" in error48 && typeof error48.category === "string" ? error48.category : void 0,
|
|
19540
|
+
details: "details" in error48 && error48.details && typeof error48.details === "object" ? error48.details : void 0
|
|
19541
|
+
};
|
|
19542
|
+
}
|
|
19543
|
+
function buildCorrelationContext(span, rootSpan, parent) {
|
|
19544
|
+
return {
|
|
19545
|
+
tags: rootSpan.tags ?? void 0,
|
|
19546
|
+
entityType: nullToUndefined(span.entityType),
|
|
19547
|
+
entityId: nullToUndefined(span.entityId),
|
|
19548
|
+
entityName: nullToUndefined(span.entityName),
|
|
19549
|
+
parentEntityType: parent?.entityType ?? void 0,
|
|
19550
|
+
parentEntityId: parent?.entityId ?? void 0,
|
|
19551
|
+
parentEntityName: parent?.entityName ?? void 0,
|
|
19552
|
+
rootEntityType: nullToUndefined(rootSpan.entityType),
|
|
19553
|
+
rootEntityId: nullToUndefined(rootSpan.entityId),
|
|
19554
|
+
rootEntityName: nullToUndefined(rootSpan.entityName),
|
|
19555
|
+
userId: nullToUndefined(span.userId),
|
|
19556
|
+
organizationId: nullToUndefined(span.organizationId),
|
|
19557
|
+
resourceId: nullToUndefined(span.resourceId),
|
|
19558
|
+
runId: nullToUndefined(span.runId),
|
|
19559
|
+
sessionId: nullToUndefined(span.sessionId),
|
|
19560
|
+
threadId: nullToUndefined(span.threadId),
|
|
19561
|
+
requestId: nullToUndefined(span.requestId),
|
|
19562
|
+
environment: nullToUndefined(span.environment),
|
|
19563
|
+
source: nullToUndefined(span.source),
|
|
19564
|
+
serviceName: nullToUndefined(span.serviceName),
|
|
19565
|
+
experimentId: nullToUndefined(span.experimentId)
|
|
19566
|
+
};
|
|
19567
|
+
}
|
|
19568
|
+
function buildRecordedScoreEvent(args) {
|
|
19569
|
+
const { span, rootSpan, parent, score, spanId } = args;
|
|
19570
|
+
return {
|
|
19571
|
+
type: "score",
|
|
19572
|
+
score: {
|
|
19573
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
19574
|
+
traceId: span.traceId,
|
|
19575
|
+
spanId,
|
|
19576
|
+
scorerId: score.scorerId,
|
|
19577
|
+
scorerVersion: score.scorerVersion,
|
|
19578
|
+
source: score.source,
|
|
19579
|
+
scoreSource: score.scoreSource,
|
|
19580
|
+
score: score.score,
|
|
19581
|
+
reason: score.reason,
|
|
19582
|
+
experimentId: score.experimentId,
|
|
19583
|
+
scoreTraceId: score.scoreTraceId,
|
|
19584
|
+
correlationContext: buildCorrelationContext(span, rootSpan, parent),
|
|
19585
|
+
metadata: mergeMetadata(span.metadata, score.metadata)
|
|
19586
|
+
}
|
|
19587
|
+
};
|
|
19588
|
+
}
|
|
19589
|
+
function buildRecordedFeedbackEvent(args) {
|
|
19590
|
+
const { span, rootSpan, parent, feedback, spanId } = args;
|
|
19591
|
+
return {
|
|
19592
|
+
type: "feedback",
|
|
19593
|
+
feedback: {
|
|
19594
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
19595
|
+
traceId: span.traceId,
|
|
19596
|
+
spanId,
|
|
19597
|
+
source: feedback.source,
|
|
19598
|
+
feedbackSource: feedback.feedbackSource,
|
|
19599
|
+
feedbackType: feedback.feedbackType,
|
|
19600
|
+
value: feedback.value,
|
|
19601
|
+
userId: feedback.userId,
|
|
19602
|
+
feedbackUserId: feedback.feedbackUserId,
|
|
19603
|
+
comment: feedback.comment,
|
|
19604
|
+
sourceId: feedback.sourceId,
|
|
19605
|
+
experimentId: feedback.experimentId,
|
|
19606
|
+
correlationContext: buildCorrelationContext(span, rootSpan, parent),
|
|
19607
|
+
metadata: mergeMetadata(span.metadata, feedback.metadata)
|
|
19608
|
+
}
|
|
19609
|
+
};
|
|
19610
|
+
}
|
|
19611
|
+
function findSpanById(spans, spanId) {
|
|
19612
|
+
if (!spanId) return void 0;
|
|
19613
|
+
return spans.find((span) => span.spanId === spanId);
|
|
19614
|
+
}
|
|
19615
|
+
function buildRecordedScoreEventFromTrace(args) {
|
|
19616
|
+
const rootSpan = findRootSpan(args.trace.spans);
|
|
19617
|
+
if (!rootSpan) return null;
|
|
19618
|
+
const span = args.spanId ? findSpanById(args.trace.spans, args.spanId) : rootSpan;
|
|
19619
|
+
if (!span) return null;
|
|
19620
|
+
const parent = span.parentSpanId ? findSpanById(args.trace.spans, span.parentSpanId) : void 0;
|
|
19621
|
+
return buildRecordedScoreEvent({
|
|
19622
|
+
span,
|
|
19623
|
+
rootSpan,
|
|
19624
|
+
parent,
|
|
19625
|
+
score: args.score,
|
|
19626
|
+
spanId: args.spanId
|
|
19627
|
+
});
|
|
19628
|
+
}
|
|
19629
|
+
function buildRecordedFeedbackEventFromTrace(args) {
|
|
19630
|
+
const rootSpan = findRootSpan(args.trace.spans);
|
|
19631
|
+
if (!rootSpan) return null;
|
|
19632
|
+
const span = args.spanId ? findSpanById(args.trace.spans, args.spanId) : rootSpan;
|
|
19633
|
+
if (!span) return null;
|
|
19634
|
+
const parent = span.parentSpanId ? findSpanById(args.trace.spans, span.parentSpanId) : void 0;
|
|
19635
|
+
return buildRecordedFeedbackEvent({
|
|
19636
|
+
span,
|
|
19637
|
+
rootSpan,
|
|
19638
|
+
parent,
|
|
19639
|
+
feedback: args.feedback,
|
|
19640
|
+
spanId: args.spanId
|
|
19641
|
+
});
|
|
19642
|
+
}
|
|
19643
|
+
var RecordedSpanImpl = class {
|
|
19644
|
+
id;
|
|
19645
|
+
traceId;
|
|
19646
|
+
name;
|
|
19647
|
+
type;
|
|
19648
|
+
entityType;
|
|
19649
|
+
entityId;
|
|
19650
|
+
entityName;
|
|
19651
|
+
startTime;
|
|
19652
|
+
endTime;
|
|
19653
|
+
attributes;
|
|
19654
|
+
metadata;
|
|
19655
|
+
tags;
|
|
19656
|
+
input;
|
|
19657
|
+
output;
|
|
19658
|
+
errorInfo;
|
|
19659
|
+
requestContext;
|
|
19660
|
+
isEvent;
|
|
19661
|
+
isRootSpan;
|
|
19662
|
+
parentSpanId;
|
|
19663
|
+
parent;
|
|
19664
|
+
children = [];
|
|
19665
|
+
#raw;
|
|
19666
|
+
#rootSpan;
|
|
19667
|
+
#emitRecordedEvent;
|
|
19668
|
+
#canEmitRecordedEvent;
|
|
19669
|
+
#debugRecordedAnnotationUnavailable;
|
|
19670
|
+
constructor(args) {
|
|
19671
|
+
const { raw, rootSpan, emitRecordedEvent, canEmitRecordedEvent, debugRecordedAnnotationUnavailable } = args;
|
|
19672
|
+
this.#raw = raw;
|
|
19673
|
+
this.#rootSpan = rootSpan;
|
|
19674
|
+
this.#emitRecordedEvent = emitRecordedEvent;
|
|
19675
|
+
this.#canEmitRecordedEvent = canEmitRecordedEvent;
|
|
19676
|
+
this.#debugRecordedAnnotationUnavailable = debugRecordedAnnotationUnavailable;
|
|
19677
|
+
this.id = raw.spanId;
|
|
19678
|
+
this.traceId = raw.traceId;
|
|
19679
|
+
this.name = raw.name;
|
|
19680
|
+
this.type = raw.spanType;
|
|
19681
|
+
this.entityType = raw.entityType ?? void 0;
|
|
19682
|
+
this.entityId = raw.entityId ?? void 0;
|
|
19683
|
+
this.entityName = raw.entityName ?? void 0;
|
|
19684
|
+
this.startTime = raw.startedAt;
|
|
19685
|
+
this.endTime = raw.endedAt ?? void 0;
|
|
19686
|
+
this.attributes = raw.attributes ?? void 0;
|
|
19687
|
+
this.metadata = raw.metadata ?? void 0;
|
|
19688
|
+
this.tags = raw.tags ?? void 0;
|
|
19689
|
+
this.input = raw.input ?? void 0;
|
|
19690
|
+
this.output = raw.output ?? void 0;
|
|
19691
|
+
this.errorInfo = normalizeErrorInfo(raw.error);
|
|
19692
|
+
this.requestContext = raw.requestContext ?? void 0;
|
|
19693
|
+
this.isEvent = raw.isEvent;
|
|
19694
|
+
this.isRootSpan = !raw.parentSpanId;
|
|
19695
|
+
this.parentSpanId = raw.parentSpanId ?? void 0;
|
|
19696
|
+
}
|
|
19697
|
+
async addScore(score) {
|
|
19698
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19699
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "score", traceId: this.traceId, spanId: this.id });
|
|
19700
|
+
return;
|
|
19701
|
+
}
|
|
19702
|
+
await this.#emitRecordedEvent(
|
|
19703
|
+
buildRecordedScoreEvent({
|
|
19704
|
+
span: this.#raw,
|
|
19705
|
+
rootSpan: this.#rootSpan,
|
|
19706
|
+
parent: this.parent,
|
|
19707
|
+
score,
|
|
19708
|
+
spanId: this.id
|
|
19709
|
+
})
|
|
19710
|
+
);
|
|
19711
|
+
}
|
|
19712
|
+
async addFeedback(feedback) {
|
|
19713
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19714
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "feedback", traceId: this.traceId, spanId: this.id });
|
|
19715
|
+
return;
|
|
19716
|
+
}
|
|
19717
|
+
await this.#emitRecordedEvent(
|
|
19718
|
+
buildRecordedFeedbackEvent({
|
|
19719
|
+
span: this.#raw,
|
|
19720
|
+
rootSpan: this.#rootSpan,
|
|
19721
|
+
parent: this.parent,
|
|
19722
|
+
feedback,
|
|
19723
|
+
spanId: this.id
|
|
19724
|
+
})
|
|
19725
|
+
);
|
|
19726
|
+
}
|
|
19727
|
+
};
|
|
19728
|
+
var RecordedTraceImpl = class {
|
|
19729
|
+
traceId;
|
|
19730
|
+
rootSpan;
|
|
19731
|
+
spans;
|
|
19732
|
+
#rootRecord;
|
|
19733
|
+
#emitRecordedEvent;
|
|
19734
|
+
#spanMap;
|
|
19735
|
+
#canEmitRecordedEvent;
|
|
19736
|
+
#debugRecordedAnnotationUnavailable;
|
|
19737
|
+
constructor(args) {
|
|
19738
|
+
this.traceId = args.traceId;
|
|
19739
|
+
this.rootSpan = args.rootSpan;
|
|
19740
|
+
this.#rootRecord = args.rootRecord;
|
|
19741
|
+
this.spans = args.spans;
|
|
19742
|
+
this.#emitRecordedEvent = args.emitRecordedEvent;
|
|
19743
|
+
this.#spanMap = new Map(args.spans.map((span) => [span.id, span]));
|
|
19744
|
+
this.#canEmitRecordedEvent = args.canEmitRecordedEvent;
|
|
19745
|
+
this.#debugRecordedAnnotationUnavailable = args.debugRecordedAnnotationUnavailable;
|
|
19746
|
+
}
|
|
19747
|
+
getSpan(spanId) {
|
|
19748
|
+
return this.#spanMap.get(spanId) ?? null;
|
|
19749
|
+
}
|
|
19750
|
+
async addScore(score) {
|
|
19751
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19752
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "score", traceId: this.traceId });
|
|
19753
|
+
return;
|
|
19754
|
+
}
|
|
19755
|
+
await this.#emitRecordedEvent(
|
|
19756
|
+
buildRecordedScoreEvent({
|
|
19757
|
+
span: this.#rootRecord,
|
|
19758
|
+
rootSpan: this.#rootRecord,
|
|
19759
|
+
score
|
|
19760
|
+
})
|
|
19761
|
+
);
|
|
19762
|
+
}
|
|
19763
|
+
async addFeedback(feedback) {
|
|
19764
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19765
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "feedback", traceId: this.traceId });
|
|
19766
|
+
return;
|
|
19767
|
+
}
|
|
19768
|
+
await this.#emitRecordedEvent(
|
|
19769
|
+
buildRecordedFeedbackEvent({
|
|
19770
|
+
span: this.#rootRecord,
|
|
19771
|
+
rootSpan: this.#rootRecord,
|
|
19772
|
+
feedback
|
|
19773
|
+
})
|
|
19774
|
+
);
|
|
19775
|
+
}
|
|
19776
|
+
};
|
|
19777
|
+
function findRootSpan(spans) {
|
|
19778
|
+
const spanIds = new Set(spans.map((span) => span.spanId));
|
|
19779
|
+
return spans.find((span) => !span.parentSpanId || !spanIds.has(span.parentSpanId)) ?? spans[0];
|
|
19780
|
+
}
|
|
19781
|
+
function hydrateRecordedTrace(args) {
|
|
19782
|
+
const {
|
|
19783
|
+
trace,
|
|
19784
|
+
emitRecordedEvent,
|
|
19785
|
+
canEmitRecordedEvent = () => true,
|
|
19786
|
+
debugRecordedAnnotationUnavailable = () => {
|
|
19787
|
+
}
|
|
19788
|
+
} = args;
|
|
19789
|
+
const rootSpan = findRootSpan(trace.spans);
|
|
19790
|
+
if (!rootSpan) {
|
|
19791
|
+
return null;
|
|
19792
|
+
}
|
|
19793
|
+
const recordedSpans = trace.spans.map(
|
|
19794
|
+
(raw) => new RecordedSpanImpl({
|
|
19795
|
+
raw,
|
|
19796
|
+
rootSpan,
|
|
19797
|
+
emitRecordedEvent,
|
|
19798
|
+
canEmitRecordedEvent,
|
|
19799
|
+
debugRecordedAnnotationUnavailable
|
|
19800
|
+
})
|
|
19801
|
+
);
|
|
19802
|
+
const spanMap = new Map(recordedSpans.map((span) => [span.id, span]));
|
|
19803
|
+
for (const span of recordedSpans) {
|
|
19804
|
+
if (!span.parentSpanId) continue;
|
|
19805
|
+
const parent = spanMap.get(span.parentSpanId);
|
|
19806
|
+
if (!parent) continue;
|
|
19807
|
+
span.parent = parent;
|
|
19808
|
+
parent.children.push(span);
|
|
19809
|
+
}
|
|
19810
|
+
const hydratedRootSpan = spanMap.get(rootSpan.spanId);
|
|
19811
|
+
if (!hydratedRootSpan) {
|
|
19812
|
+
return null;
|
|
19813
|
+
}
|
|
19814
|
+
return new RecordedTraceImpl({
|
|
19815
|
+
traceId: trace.traceId,
|
|
19816
|
+
rootSpan: hydratedRootSpan,
|
|
19817
|
+
rootRecord: rootSpan,
|
|
19818
|
+
spans: recordedSpans,
|
|
19819
|
+
emitRecordedEvent,
|
|
19820
|
+
canEmitRecordedEvent,
|
|
19821
|
+
debugRecordedAnnotationUnavailable
|
|
19822
|
+
});
|
|
19823
|
+
}
|
|
19824
|
+
|
|
19495
19825
|
// src/registry.ts
|
|
19496
19826
|
var ObservabilityRegistry = class {
|
|
19497
19827
|
#instances = /* @__PURE__ */ new Map();
|
|
@@ -19732,6 +20062,7 @@ function isInstance(obj) {
|
|
|
19732
20062
|
}
|
|
19733
20063
|
var Observability = class extends MastraBase {
|
|
19734
20064
|
#registry = new ObservabilityRegistry();
|
|
20065
|
+
#mastra;
|
|
19735
20066
|
constructor(config2) {
|
|
19736
20067
|
super({
|
|
19737
20068
|
component: RegisteredLogger.OBSERVABILITY,
|
|
@@ -19806,6 +20137,7 @@ var Observability = class extends MastraBase {
|
|
|
19806
20137
|
setMastraContext(options) {
|
|
19807
20138
|
const instances = this.listInstances();
|
|
19808
20139
|
const { mastra } = options;
|
|
20140
|
+
this.#mastra = mastra;
|
|
19809
20141
|
instances.forEach((instance) => {
|
|
19810
20142
|
const config2 = instance.getConfig();
|
|
19811
20143
|
const exporters = instance.getExporters();
|
|
@@ -19834,6 +20166,60 @@ var Observability = class extends MastraBase {
|
|
|
19834
20166
|
getSelectedInstance(options) {
|
|
19835
20167
|
return this.#registry.getSelected(options);
|
|
19836
20168
|
}
|
|
20169
|
+
async getRecordedTrace(args) {
|
|
20170
|
+
const observabilityStorage = await this.#getObservabilityStorage();
|
|
20171
|
+
if (!observabilityStorage) {
|
|
20172
|
+
return null;
|
|
20173
|
+
}
|
|
20174
|
+
const trace = await observabilityStorage.getTrace({ traceId: args.traceId });
|
|
20175
|
+
if (!trace) {
|
|
20176
|
+
return null;
|
|
20177
|
+
}
|
|
20178
|
+
return hydrateRecordedTrace({
|
|
20179
|
+
trace,
|
|
20180
|
+
emitRecordedEvent: (event) => this.#emitRecordedEvent(event),
|
|
20181
|
+
canEmitRecordedEvent: () => !!this.#getRecordedTraceInstance(),
|
|
20182
|
+
debugRecordedAnnotationUnavailable: ({ kind, traceId, spanId }) => {
|
|
20183
|
+
this.logger?.debug(
|
|
20184
|
+
kind === "score" ? "addScore() is unavailable; rehydrate the trace before calling addScore()" : "addFeedback() is unavailable; rehydrate the trace before calling addFeedback()",
|
|
20185
|
+
{
|
|
20186
|
+
traceId,
|
|
20187
|
+
spanId
|
|
20188
|
+
}
|
|
20189
|
+
);
|
|
20190
|
+
}
|
|
20191
|
+
});
|
|
20192
|
+
}
|
|
20193
|
+
async addScore(args) {
|
|
20194
|
+
const trace = await this.#getStoredTrace(args.traceId);
|
|
20195
|
+
if (!trace) {
|
|
20196
|
+
return;
|
|
20197
|
+
}
|
|
20198
|
+
const event = buildRecordedScoreEventFromTrace({
|
|
20199
|
+
trace,
|
|
20200
|
+
spanId: args.spanId,
|
|
20201
|
+
score: args.score
|
|
20202
|
+
});
|
|
20203
|
+
if (!event) {
|
|
20204
|
+
return;
|
|
20205
|
+
}
|
|
20206
|
+
await this.#emitRecordedEvent(event);
|
|
20207
|
+
}
|
|
20208
|
+
async addFeedback(args) {
|
|
20209
|
+
const trace = await this.#getStoredTrace(args.traceId);
|
|
20210
|
+
if (!trace) {
|
|
20211
|
+
return;
|
|
20212
|
+
}
|
|
20213
|
+
const event = buildRecordedFeedbackEventFromTrace({
|
|
20214
|
+
trace,
|
|
20215
|
+
spanId: args.spanId,
|
|
20216
|
+
feedback: args.feedback
|
|
20217
|
+
});
|
|
20218
|
+
if (!event) {
|
|
20219
|
+
return;
|
|
20220
|
+
}
|
|
20221
|
+
await this.#emitRecordedEvent(event);
|
|
20222
|
+
}
|
|
19837
20223
|
/** Register a named observability instance, optionally marking it as default. */
|
|
19838
20224
|
registerInstance(name, instance, isDefault = false) {
|
|
19839
20225
|
this.#registry.register(name, instance, isDefault);
|
|
@@ -19870,6 +20256,45 @@ var Observability = class extends MastraBase {
|
|
|
19870
20256
|
async shutdown() {
|
|
19871
20257
|
await this.#registry.shutdown();
|
|
19872
20258
|
}
|
|
20259
|
+
async #getObservabilityStorage() {
|
|
20260
|
+
const storage = this.#mastra?.getStorage();
|
|
20261
|
+
if (!storage) {
|
|
20262
|
+
return null;
|
|
20263
|
+
}
|
|
20264
|
+
return await storage.getStore("observability") ?? null;
|
|
20265
|
+
}
|
|
20266
|
+
async #getStoredTrace(traceId) {
|
|
20267
|
+
const observabilityStorage = await this.#getObservabilityStorage();
|
|
20268
|
+
if (!observabilityStorage) {
|
|
20269
|
+
return null;
|
|
20270
|
+
}
|
|
20271
|
+
return observabilityStorage.getTrace({ traceId });
|
|
20272
|
+
}
|
|
20273
|
+
#getRecordedTraceInstance() {
|
|
20274
|
+
return this.getDefaultInstance() ?? Array.from(this.listInstances().values())[0];
|
|
20275
|
+
}
|
|
20276
|
+
async #emitRecordedEvent(event) {
|
|
20277
|
+
const instance = this.#getRecordedTraceInstance();
|
|
20278
|
+
if (!instance) {
|
|
20279
|
+
this.logger?.debug(
|
|
20280
|
+
event.type === "score" ? "Score event was dropped because no observability instance is registered" : "Feedback event was dropped because no observability instance is registered",
|
|
20281
|
+
{ eventType: event.type }
|
|
20282
|
+
);
|
|
20283
|
+
return;
|
|
20284
|
+
}
|
|
20285
|
+
if (instance instanceof BaseObservabilityInstance) {
|
|
20286
|
+
instance.__emitRecordedEvent(event);
|
|
20287
|
+
return;
|
|
20288
|
+
}
|
|
20289
|
+
const bridge = instance.getBridge();
|
|
20290
|
+
const handlerResults = [
|
|
20291
|
+
...instance.getExporters().map((exporter) => routeToHandler(exporter, event, this.logger)),
|
|
20292
|
+
...bridge ? [routeToHandler(bridge, event, this.logger)] : []
|
|
20293
|
+
].filter((result) => !!result && typeof result.then === "function");
|
|
20294
|
+
if (handlerResults.length > 0) {
|
|
20295
|
+
await Promise.allSettled(handlerResults);
|
|
20296
|
+
}
|
|
20297
|
+
}
|
|
19873
20298
|
};
|
|
19874
20299
|
|
|
19875
20300
|
// src/tracing-options.ts
|