@mastra/observability 1.6.0-alpha.2 → 1.6.0
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 +43 -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 +468 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +468 -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/package.json +6 -6
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,
|
|
@@ -19193,6 +19204,8 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
19193
19204
|
const correlationContext = span?.getCorrelationContext?.();
|
|
19194
19205
|
const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
|
|
19195
19206
|
return new LoggerContextImpl({
|
|
19207
|
+
traceId: span?.traceId,
|
|
19208
|
+
spanId: span?.id,
|
|
19196
19209
|
correlationContext,
|
|
19197
19210
|
metadata,
|
|
19198
19211
|
observabilityBus: this.observabilityBus
|
|
@@ -19207,6 +19220,8 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
19207
19220
|
const correlationContext = span?.getCorrelationContext?.();
|
|
19208
19221
|
const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
|
|
19209
19222
|
return new MetricsContextImpl({
|
|
19223
|
+
traceId: span?.traceId,
|
|
19224
|
+
spanId: span?.id,
|
|
19210
19225
|
correlationContext,
|
|
19211
19226
|
metadata,
|
|
19212
19227
|
cardinalityFilter: this.cardinalityFilter,
|
|
@@ -19221,6 +19236,13 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
19221
19236
|
emitObservabilityEvent(event) {
|
|
19222
19237
|
this.observabilityBus.emit(event);
|
|
19223
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
|
+
}
|
|
19224
19246
|
// ============================================================================
|
|
19225
19247
|
// Span Lifecycle Management
|
|
19226
19248
|
// ============================================================================
|
|
@@ -19495,6 +19517,311 @@ var DefaultObservabilityInstance = class extends BaseObservabilityInstance {
|
|
|
19495
19517
|
}
|
|
19496
19518
|
};
|
|
19497
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
|
+
|
|
19498
19825
|
// src/registry.ts
|
|
19499
19826
|
var ObservabilityRegistry = class {
|
|
19500
19827
|
#instances = /* @__PURE__ */ new Map();
|
|
@@ -19735,6 +20062,7 @@ function isInstance(obj) {
|
|
|
19735
20062
|
}
|
|
19736
20063
|
var Observability = class extends MastraBase {
|
|
19737
20064
|
#registry = new ObservabilityRegistry();
|
|
20065
|
+
#mastra;
|
|
19738
20066
|
constructor(config2) {
|
|
19739
20067
|
super({
|
|
19740
20068
|
component: RegisteredLogger.OBSERVABILITY,
|
|
@@ -19809,6 +20137,7 @@ var Observability = class extends MastraBase {
|
|
|
19809
20137
|
setMastraContext(options) {
|
|
19810
20138
|
const instances = this.listInstances();
|
|
19811
20139
|
const { mastra } = options;
|
|
20140
|
+
this.#mastra = mastra;
|
|
19812
20141
|
instances.forEach((instance) => {
|
|
19813
20142
|
const config2 = instance.getConfig();
|
|
19814
20143
|
const exporters = instance.getExporters();
|
|
@@ -19837,6 +20166,60 @@ var Observability = class extends MastraBase {
|
|
|
19837
20166
|
getSelectedInstance(options) {
|
|
19838
20167
|
return this.#registry.getSelected(options);
|
|
19839
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
|
+
}
|
|
19840
20223
|
/** Register a named observability instance, optionally marking it as default. */
|
|
19841
20224
|
registerInstance(name, instance, isDefault = false) {
|
|
19842
20225
|
this.#registry.register(name, instance, isDefault);
|
|
@@ -19873,6 +20256,45 @@ var Observability = class extends MastraBase {
|
|
|
19873
20256
|
async shutdown() {
|
|
19874
20257
|
await this.#registry.shutdown();
|
|
19875
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
|
+
}
|
|
19876
20298
|
};
|
|
19877
20299
|
|
|
19878
20300
|
// src/tracing-options.ts
|