@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.cjs
CHANGED
|
@@ -22,6 +22,47 @@ var __export = (target, all) => {
|
|
|
22
22
|
for (var name in all)
|
|
23
23
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
24
24
|
};
|
|
25
|
+
function routeToHandler(handler, event, logger) {
|
|
26
|
+
try {
|
|
27
|
+
switch (event.type) {
|
|
28
|
+
case observability.TracingEventType.SPAN_STARTED:
|
|
29
|
+
case observability.TracingEventType.SPAN_UPDATED:
|
|
30
|
+
case observability.TracingEventType.SPAN_ENDED: {
|
|
31
|
+
const fn = handler.onTracingEvent ? handler.onTracingEvent.bind(handler) : handler.exportTracingEvent.bind(handler);
|
|
32
|
+
return catchAsyncResult(fn(event), handler.name, "tracing", logger);
|
|
33
|
+
}
|
|
34
|
+
case "log":
|
|
35
|
+
if (handler.onLogEvent) {
|
|
36
|
+
return catchAsyncResult(handler.onLogEvent(event), handler.name, "log", logger);
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
|
+
case "metric":
|
|
40
|
+
if (handler.onMetricEvent) {
|
|
41
|
+
return catchAsyncResult(handler.onMetricEvent(event), handler.name, "metric", logger);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case "score":
|
|
45
|
+
if (handler.onScoreEvent) {
|
|
46
|
+
return catchAsyncResult(handler.onScoreEvent(event), handler.name, "score", logger);
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
case "feedback":
|
|
50
|
+
if (handler.onFeedbackEvent) {
|
|
51
|
+
return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function catchAsyncResult(result, handlerName, signal, logger) {
|
|
60
|
+
if (result && typeof result.then === "function") {
|
|
61
|
+
return result.catch((err) => {
|
|
62
|
+
logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
25
66
|
|
|
26
67
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
27
68
|
var external_exports = {};
|
|
@@ -15901,7 +15942,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
15901
15942
|
this.#trackEvent("log");
|
|
15902
15943
|
if (this.#config.storeLogs) {
|
|
15903
15944
|
const log = event.log;
|
|
15904
|
-
const traceId = log.
|
|
15945
|
+
const traceId = log.traceId;
|
|
15905
15946
|
const logMessage = `[TestExporter] log.${log.level}: "${log.message}"${traceId ? ` (trace: ${traceId.slice(-8)})` : ""}`;
|
|
15906
15947
|
this.#debugLogs.push(logMessage);
|
|
15907
15948
|
}
|
|
@@ -16019,7 +16060,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
16019
16060
|
getByTraceId(traceId) {
|
|
16020
16061
|
const events = this.#tracingEvents.filter((e) => e.exportedSpan.traceId === traceId);
|
|
16021
16062
|
const spans = this.#getUniqueSpansFromEvents(events);
|
|
16022
|
-
const logs = this.#logEvents.filter((e) => e.log.
|
|
16063
|
+
const logs = this.#logEvents.filter((e) => e.log.traceId === traceId).map((e) => e.log);
|
|
16023
16064
|
const scores = this.#scoreEvents.filter((e) => e.score.traceId === traceId).map((e) => e.score);
|
|
16024
16065
|
const feedback = this.#feedbackEvents.filter((e) => e.feedback.traceId === traceId).map((e) => e.feedback);
|
|
16025
16066
|
return { events, spans, logs, scores, feedback };
|
|
@@ -16086,7 +16127,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
16086
16127
|
traceIds.add(event.exportedSpan.traceId);
|
|
16087
16128
|
}
|
|
16088
16129
|
for (const event of this.#logEvents) {
|
|
16089
|
-
if (event.log.
|
|
16130
|
+
if (event.log.traceId) traceIds.add(event.log.traceId);
|
|
16090
16131
|
}
|
|
16091
16132
|
for (const event of this.#scoreEvents) {
|
|
16092
16133
|
traceIds.add(event.score.traceId);
|
|
@@ -16121,7 +16162,7 @@ var TestExporter = class extends BaseExporter {
|
|
|
16121
16162
|
* Get logs for a specific trace
|
|
16122
16163
|
*/
|
|
16123
16164
|
getLogsByTraceId(traceId) {
|
|
16124
|
-
return this.#logEvents.filter((e) => e.log.
|
|
16165
|
+
return this.#logEvents.filter((e) => e.log.traceId === traceId).map((e) => e.log);
|
|
16125
16166
|
}
|
|
16126
16167
|
// ============================================================================
|
|
16127
16168
|
// Metric Query Methods
|
|
@@ -16995,47 +17036,6 @@ var BaseObservabilityEventBus = class _BaseObservabilityEventBus extends base.Ma
|
|
|
16995
17036
|
this.subscribers.clear();
|
|
16996
17037
|
}
|
|
16997
17038
|
};
|
|
16998
|
-
function routeToHandler(handler, event, logger) {
|
|
16999
|
-
try {
|
|
17000
|
-
switch (event.type) {
|
|
17001
|
-
case observability.TracingEventType.SPAN_STARTED:
|
|
17002
|
-
case observability.TracingEventType.SPAN_UPDATED:
|
|
17003
|
-
case observability.TracingEventType.SPAN_ENDED: {
|
|
17004
|
-
const fn = handler.onTracingEvent ? handler.onTracingEvent.bind(handler) : handler.exportTracingEvent.bind(handler);
|
|
17005
|
-
return catchAsyncResult(fn(event), handler.name, "tracing", logger);
|
|
17006
|
-
}
|
|
17007
|
-
case "log":
|
|
17008
|
-
if (handler.onLogEvent) {
|
|
17009
|
-
return catchAsyncResult(handler.onLogEvent(event), handler.name, "log", logger);
|
|
17010
|
-
}
|
|
17011
|
-
break;
|
|
17012
|
-
case "metric":
|
|
17013
|
-
if (handler.onMetricEvent) {
|
|
17014
|
-
return catchAsyncResult(handler.onMetricEvent(event), handler.name, "metric", logger);
|
|
17015
|
-
}
|
|
17016
|
-
break;
|
|
17017
|
-
case "score":
|
|
17018
|
-
if (handler.onScoreEvent) {
|
|
17019
|
-
return catchAsyncResult(handler.onScoreEvent(event), handler.name, "score", logger);
|
|
17020
|
-
}
|
|
17021
|
-
break;
|
|
17022
|
-
case "feedback":
|
|
17023
|
-
if (handler.onFeedbackEvent) {
|
|
17024
|
-
return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
|
|
17025
|
-
}
|
|
17026
|
-
break;
|
|
17027
|
-
}
|
|
17028
|
-
} catch (err) {
|
|
17029
|
-
logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
|
|
17030
|
-
}
|
|
17031
|
-
}
|
|
17032
|
-
function catchAsyncResult(result, handlerName, signal, logger) {
|
|
17033
|
-
if (result && typeof result.then === "function") {
|
|
17034
|
-
return result.catch((err) => {
|
|
17035
|
-
logger.error(`[Observability] ${signal} handler error [handler=${handlerName}]:`, err);
|
|
17036
|
-
});
|
|
17037
|
-
}
|
|
17038
|
-
}
|
|
17039
17039
|
|
|
17040
17040
|
// src/bus/observability-bus.ts
|
|
17041
17041
|
var MAX_FLUSH_ITERATIONS = 3;
|
|
@@ -17195,9 +17195,12 @@ var LoggerContextImpl = class {
|
|
|
17195
17195
|
* mutations after construction do not affect emitted logs.
|
|
17196
17196
|
*/
|
|
17197
17197
|
constructor(config2) {
|
|
17198
|
+
const correlationContext = config2.correlationContext ? { ...config2.correlationContext } : void 0;
|
|
17198
17199
|
this.config = {
|
|
17199
17200
|
...config2,
|
|
17200
|
-
|
|
17201
|
+
traceId: config2.traceId ?? correlationContext?.traceId,
|
|
17202
|
+
spanId: config2.spanId ?? correlationContext?.spanId,
|
|
17203
|
+
correlationContext,
|
|
17201
17204
|
metadata: config2.metadata ? structuredClone(config2.metadata) : void 0
|
|
17202
17205
|
};
|
|
17203
17206
|
}
|
|
@@ -17234,6 +17237,8 @@ var LoggerContextImpl = class {
|
|
|
17234
17237
|
level,
|
|
17235
17238
|
message,
|
|
17236
17239
|
data,
|
|
17240
|
+
traceId: this.config.traceId,
|
|
17241
|
+
spanId: this.config.spanId,
|
|
17237
17242
|
correlationContext: this.config.correlationContext,
|
|
17238
17243
|
metadata: this.config.metadata
|
|
17239
17244
|
};
|
|
@@ -17244,6 +17249,8 @@ var LoggerContextImpl = class {
|
|
|
17244
17249
|
|
|
17245
17250
|
// src/context/metrics.ts
|
|
17246
17251
|
var MetricsContextImpl = class {
|
|
17252
|
+
traceId;
|
|
17253
|
+
spanId;
|
|
17247
17254
|
correlationContext;
|
|
17248
17255
|
metadata;
|
|
17249
17256
|
cardinalityFilter;
|
|
@@ -17254,6 +17261,8 @@ var MetricsContextImpl = class {
|
|
|
17254
17261
|
*/
|
|
17255
17262
|
constructor(config2) {
|
|
17256
17263
|
this.correlationContext = config2.correlationContext ? { ...config2.correlationContext } : void 0;
|
|
17264
|
+
this.traceId = config2.traceId ?? this.correlationContext?.traceId;
|
|
17265
|
+
this.spanId = config2.spanId ?? this.correlationContext?.spanId;
|
|
17257
17266
|
this.metadata = config2.metadata ? structuredClone(config2.metadata) : void 0;
|
|
17258
17267
|
this.cardinalityFilter = config2.cardinalityFilter;
|
|
17259
17268
|
this.observabilityBus = config2.observabilityBus;
|
|
@@ -17267,6 +17276,8 @@ var MetricsContextImpl = class {
|
|
|
17267
17276
|
const costContext = options?.costContext ? cloneCostContext(options.costContext) : void 0;
|
|
17268
17277
|
const exportedMetric = {
|
|
17269
17278
|
timestamp: /* @__PURE__ */ new Date(),
|
|
17279
|
+
traceId: this.traceId,
|
|
17280
|
+
spanId: this.spanId,
|
|
17270
17281
|
name,
|
|
17271
17282
|
value,
|
|
17272
17283
|
labels: filteredLabels,
|
|
@@ -18903,6 +18914,9 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
18903
18914
|
if (this.isEvent) {
|
|
18904
18915
|
return;
|
|
18905
18916
|
}
|
|
18917
|
+
if (options.name !== void 0) {
|
|
18918
|
+
this.name = options.name;
|
|
18919
|
+
}
|
|
18906
18920
|
if (options.input !== void 0) {
|
|
18907
18921
|
this.input = deepClean(options.input, this.deepCleanOptions);
|
|
18908
18922
|
}
|
|
@@ -19198,6 +19212,8 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
19198
19212
|
const correlationContext = span?.getCorrelationContext?.();
|
|
19199
19213
|
const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
|
|
19200
19214
|
return new LoggerContextImpl({
|
|
19215
|
+
traceId: span?.traceId,
|
|
19216
|
+
spanId: span?.id,
|
|
19201
19217
|
correlationContext,
|
|
19202
19218
|
metadata,
|
|
19203
19219
|
observabilityBus: this.observabilityBus
|
|
@@ -19212,6 +19228,8 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
19212
19228
|
const correlationContext = span?.getCorrelationContext?.();
|
|
19213
19229
|
const metadata = span?.metadata ? structuredClone(span.metadata) : void 0;
|
|
19214
19230
|
return new MetricsContextImpl({
|
|
19231
|
+
traceId: span?.traceId,
|
|
19232
|
+
spanId: span?.id,
|
|
19215
19233
|
correlationContext,
|
|
19216
19234
|
metadata,
|
|
19217
19235
|
cardinalityFilter: this.cardinalityFilter,
|
|
@@ -19226,6 +19244,13 @@ var BaseObservabilityInstance = class extends base.MastraBase {
|
|
|
19226
19244
|
emitObservabilityEvent(event) {
|
|
19227
19245
|
this.observabilityBus.emit(event);
|
|
19228
19246
|
}
|
|
19247
|
+
/**
|
|
19248
|
+
* Internal hook used by RecordedTrace/RecordedSpan hydration to route
|
|
19249
|
+
* non-tracing annotation events back through the normal exporter pipeline.
|
|
19250
|
+
*/
|
|
19251
|
+
__emitRecordedEvent(event) {
|
|
19252
|
+
this.emitObservabilityEvent(event);
|
|
19253
|
+
}
|
|
19229
19254
|
// ============================================================================
|
|
19230
19255
|
// Span Lifecycle Management
|
|
19231
19256
|
// ============================================================================
|
|
@@ -19500,6 +19525,311 @@ var DefaultObservabilityInstance = class extends BaseObservabilityInstance {
|
|
|
19500
19525
|
}
|
|
19501
19526
|
};
|
|
19502
19527
|
|
|
19528
|
+
// src/recorded.ts
|
|
19529
|
+
function nullToUndefined(value) {
|
|
19530
|
+
return value ?? void 0;
|
|
19531
|
+
}
|
|
19532
|
+
function mergeMetadata(base, extra) {
|
|
19533
|
+
if (!base && !extra) return void 0;
|
|
19534
|
+
return {
|
|
19535
|
+
...base ?? {},
|
|
19536
|
+
...extra ?? {}
|
|
19537
|
+
};
|
|
19538
|
+
}
|
|
19539
|
+
function normalizeErrorInfo(error48) {
|
|
19540
|
+
if (!error48 || typeof error48 !== "object" || !("message" in error48) || typeof error48.message !== "string") {
|
|
19541
|
+
return void 0;
|
|
19542
|
+
}
|
|
19543
|
+
return {
|
|
19544
|
+
message: error48.message,
|
|
19545
|
+
id: "id" in error48 && typeof error48.id === "string" ? error48.id : void 0,
|
|
19546
|
+
domain: "domain" in error48 && typeof error48.domain === "string" ? error48.domain : void 0,
|
|
19547
|
+
category: "category" in error48 && typeof error48.category === "string" ? error48.category : void 0,
|
|
19548
|
+
details: "details" in error48 && error48.details && typeof error48.details === "object" ? error48.details : void 0
|
|
19549
|
+
};
|
|
19550
|
+
}
|
|
19551
|
+
function buildCorrelationContext(span, rootSpan, parent) {
|
|
19552
|
+
return {
|
|
19553
|
+
tags: rootSpan.tags ?? void 0,
|
|
19554
|
+
entityType: nullToUndefined(span.entityType),
|
|
19555
|
+
entityId: nullToUndefined(span.entityId),
|
|
19556
|
+
entityName: nullToUndefined(span.entityName),
|
|
19557
|
+
parentEntityType: parent?.entityType ?? void 0,
|
|
19558
|
+
parentEntityId: parent?.entityId ?? void 0,
|
|
19559
|
+
parentEntityName: parent?.entityName ?? void 0,
|
|
19560
|
+
rootEntityType: nullToUndefined(rootSpan.entityType),
|
|
19561
|
+
rootEntityId: nullToUndefined(rootSpan.entityId),
|
|
19562
|
+
rootEntityName: nullToUndefined(rootSpan.entityName),
|
|
19563
|
+
userId: nullToUndefined(span.userId),
|
|
19564
|
+
organizationId: nullToUndefined(span.organizationId),
|
|
19565
|
+
resourceId: nullToUndefined(span.resourceId),
|
|
19566
|
+
runId: nullToUndefined(span.runId),
|
|
19567
|
+
sessionId: nullToUndefined(span.sessionId),
|
|
19568
|
+
threadId: nullToUndefined(span.threadId),
|
|
19569
|
+
requestId: nullToUndefined(span.requestId),
|
|
19570
|
+
environment: nullToUndefined(span.environment),
|
|
19571
|
+
source: nullToUndefined(span.source),
|
|
19572
|
+
serviceName: nullToUndefined(span.serviceName),
|
|
19573
|
+
experimentId: nullToUndefined(span.experimentId)
|
|
19574
|
+
};
|
|
19575
|
+
}
|
|
19576
|
+
function buildRecordedScoreEvent(args) {
|
|
19577
|
+
const { span, rootSpan, parent, score, spanId } = args;
|
|
19578
|
+
return {
|
|
19579
|
+
type: "score",
|
|
19580
|
+
score: {
|
|
19581
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
19582
|
+
traceId: span.traceId,
|
|
19583
|
+
spanId,
|
|
19584
|
+
scorerId: score.scorerId,
|
|
19585
|
+
scorerVersion: score.scorerVersion,
|
|
19586
|
+
source: score.source,
|
|
19587
|
+
scoreSource: score.scoreSource,
|
|
19588
|
+
score: score.score,
|
|
19589
|
+
reason: score.reason,
|
|
19590
|
+
experimentId: score.experimentId,
|
|
19591
|
+
scoreTraceId: score.scoreTraceId,
|
|
19592
|
+
correlationContext: buildCorrelationContext(span, rootSpan, parent),
|
|
19593
|
+
metadata: mergeMetadata(span.metadata, score.metadata)
|
|
19594
|
+
}
|
|
19595
|
+
};
|
|
19596
|
+
}
|
|
19597
|
+
function buildRecordedFeedbackEvent(args) {
|
|
19598
|
+
const { span, rootSpan, parent, feedback, spanId } = args;
|
|
19599
|
+
return {
|
|
19600
|
+
type: "feedback",
|
|
19601
|
+
feedback: {
|
|
19602
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
19603
|
+
traceId: span.traceId,
|
|
19604
|
+
spanId,
|
|
19605
|
+
source: feedback.source,
|
|
19606
|
+
feedbackSource: feedback.feedbackSource,
|
|
19607
|
+
feedbackType: feedback.feedbackType,
|
|
19608
|
+
value: feedback.value,
|
|
19609
|
+
userId: feedback.userId,
|
|
19610
|
+
feedbackUserId: feedback.feedbackUserId,
|
|
19611
|
+
comment: feedback.comment,
|
|
19612
|
+
sourceId: feedback.sourceId,
|
|
19613
|
+
experimentId: feedback.experimentId,
|
|
19614
|
+
correlationContext: buildCorrelationContext(span, rootSpan, parent),
|
|
19615
|
+
metadata: mergeMetadata(span.metadata, feedback.metadata)
|
|
19616
|
+
}
|
|
19617
|
+
};
|
|
19618
|
+
}
|
|
19619
|
+
function findSpanById(spans, spanId) {
|
|
19620
|
+
if (!spanId) return void 0;
|
|
19621
|
+
return spans.find((span) => span.spanId === spanId);
|
|
19622
|
+
}
|
|
19623
|
+
function buildRecordedScoreEventFromTrace(args) {
|
|
19624
|
+
const rootSpan = findRootSpan(args.trace.spans);
|
|
19625
|
+
if (!rootSpan) return null;
|
|
19626
|
+
const span = args.spanId ? findSpanById(args.trace.spans, args.spanId) : rootSpan;
|
|
19627
|
+
if (!span) return null;
|
|
19628
|
+
const parent = span.parentSpanId ? findSpanById(args.trace.spans, span.parentSpanId) : void 0;
|
|
19629
|
+
return buildRecordedScoreEvent({
|
|
19630
|
+
span,
|
|
19631
|
+
rootSpan,
|
|
19632
|
+
parent,
|
|
19633
|
+
score: args.score,
|
|
19634
|
+
spanId: args.spanId
|
|
19635
|
+
});
|
|
19636
|
+
}
|
|
19637
|
+
function buildRecordedFeedbackEventFromTrace(args) {
|
|
19638
|
+
const rootSpan = findRootSpan(args.trace.spans);
|
|
19639
|
+
if (!rootSpan) return null;
|
|
19640
|
+
const span = args.spanId ? findSpanById(args.trace.spans, args.spanId) : rootSpan;
|
|
19641
|
+
if (!span) return null;
|
|
19642
|
+
const parent = span.parentSpanId ? findSpanById(args.trace.spans, span.parentSpanId) : void 0;
|
|
19643
|
+
return buildRecordedFeedbackEvent({
|
|
19644
|
+
span,
|
|
19645
|
+
rootSpan,
|
|
19646
|
+
parent,
|
|
19647
|
+
feedback: args.feedback,
|
|
19648
|
+
spanId: args.spanId
|
|
19649
|
+
});
|
|
19650
|
+
}
|
|
19651
|
+
var RecordedSpanImpl = class {
|
|
19652
|
+
id;
|
|
19653
|
+
traceId;
|
|
19654
|
+
name;
|
|
19655
|
+
type;
|
|
19656
|
+
entityType;
|
|
19657
|
+
entityId;
|
|
19658
|
+
entityName;
|
|
19659
|
+
startTime;
|
|
19660
|
+
endTime;
|
|
19661
|
+
attributes;
|
|
19662
|
+
metadata;
|
|
19663
|
+
tags;
|
|
19664
|
+
input;
|
|
19665
|
+
output;
|
|
19666
|
+
errorInfo;
|
|
19667
|
+
requestContext;
|
|
19668
|
+
isEvent;
|
|
19669
|
+
isRootSpan;
|
|
19670
|
+
parentSpanId;
|
|
19671
|
+
parent;
|
|
19672
|
+
children = [];
|
|
19673
|
+
#raw;
|
|
19674
|
+
#rootSpan;
|
|
19675
|
+
#emitRecordedEvent;
|
|
19676
|
+
#canEmitRecordedEvent;
|
|
19677
|
+
#debugRecordedAnnotationUnavailable;
|
|
19678
|
+
constructor(args) {
|
|
19679
|
+
const { raw, rootSpan, emitRecordedEvent, canEmitRecordedEvent, debugRecordedAnnotationUnavailable } = args;
|
|
19680
|
+
this.#raw = raw;
|
|
19681
|
+
this.#rootSpan = rootSpan;
|
|
19682
|
+
this.#emitRecordedEvent = emitRecordedEvent;
|
|
19683
|
+
this.#canEmitRecordedEvent = canEmitRecordedEvent;
|
|
19684
|
+
this.#debugRecordedAnnotationUnavailable = debugRecordedAnnotationUnavailable;
|
|
19685
|
+
this.id = raw.spanId;
|
|
19686
|
+
this.traceId = raw.traceId;
|
|
19687
|
+
this.name = raw.name;
|
|
19688
|
+
this.type = raw.spanType;
|
|
19689
|
+
this.entityType = raw.entityType ?? void 0;
|
|
19690
|
+
this.entityId = raw.entityId ?? void 0;
|
|
19691
|
+
this.entityName = raw.entityName ?? void 0;
|
|
19692
|
+
this.startTime = raw.startedAt;
|
|
19693
|
+
this.endTime = raw.endedAt ?? void 0;
|
|
19694
|
+
this.attributes = raw.attributes ?? void 0;
|
|
19695
|
+
this.metadata = raw.metadata ?? void 0;
|
|
19696
|
+
this.tags = raw.tags ?? void 0;
|
|
19697
|
+
this.input = raw.input ?? void 0;
|
|
19698
|
+
this.output = raw.output ?? void 0;
|
|
19699
|
+
this.errorInfo = normalizeErrorInfo(raw.error);
|
|
19700
|
+
this.requestContext = raw.requestContext ?? void 0;
|
|
19701
|
+
this.isEvent = raw.isEvent;
|
|
19702
|
+
this.isRootSpan = !raw.parentSpanId;
|
|
19703
|
+
this.parentSpanId = raw.parentSpanId ?? void 0;
|
|
19704
|
+
}
|
|
19705
|
+
async addScore(score) {
|
|
19706
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19707
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "score", traceId: this.traceId, spanId: this.id });
|
|
19708
|
+
return;
|
|
19709
|
+
}
|
|
19710
|
+
await this.#emitRecordedEvent(
|
|
19711
|
+
buildRecordedScoreEvent({
|
|
19712
|
+
span: this.#raw,
|
|
19713
|
+
rootSpan: this.#rootSpan,
|
|
19714
|
+
parent: this.parent,
|
|
19715
|
+
score,
|
|
19716
|
+
spanId: this.id
|
|
19717
|
+
})
|
|
19718
|
+
);
|
|
19719
|
+
}
|
|
19720
|
+
async addFeedback(feedback) {
|
|
19721
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19722
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "feedback", traceId: this.traceId, spanId: this.id });
|
|
19723
|
+
return;
|
|
19724
|
+
}
|
|
19725
|
+
await this.#emitRecordedEvent(
|
|
19726
|
+
buildRecordedFeedbackEvent({
|
|
19727
|
+
span: this.#raw,
|
|
19728
|
+
rootSpan: this.#rootSpan,
|
|
19729
|
+
parent: this.parent,
|
|
19730
|
+
feedback,
|
|
19731
|
+
spanId: this.id
|
|
19732
|
+
})
|
|
19733
|
+
);
|
|
19734
|
+
}
|
|
19735
|
+
};
|
|
19736
|
+
var RecordedTraceImpl = class {
|
|
19737
|
+
traceId;
|
|
19738
|
+
rootSpan;
|
|
19739
|
+
spans;
|
|
19740
|
+
#rootRecord;
|
|
19741
|
+
#emitRecordedEvent;
|
|
19742
|
+
#spanMap;
|
|
19743
|
+
#canEmitRecordedEvent;
|
|
19744
|
+
#debugRecordedAnnotationUnavailable;
|
|
19745
|
+
constructor(args) {
|
|
19746
|
+
this.traceId = args.traceId;
|
|
19747
|
+
this.rootSpan = args.rootSpan;
|
|
19748
|
+
this.#rootRecord = args.rootRecord;
|
|
19749
|
+
this.spans = args.spans;
|
|
19750
|
+
this.#emitRecordedEvent = args.emitRecordedEvent;
|
|
19751
|
+
this.#spanMap = new Map(args.spans.map((span) => [span.id, span]));
|
|
19752
|
+
this.#canEmitRecordedEvent = args.canEmitRecordedEvent;
|
|
19753
|
+
this.#debugRecordedAnnotationUnavailable = args.debugRecordedAnnotationUnavailable;
|
|
19754
|
+
}
|
|
19755
|
+
getSpan(spanId) {
|
|
19756
|
+
return this.#spanMap.get(spanId) ?? null;
|
|
19757
|
+
}
|
|
19758
|
+
async addScore(score) {
|
|
19759
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19760
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "score", traceId: this.traceId });
|
|
19761
|
+
return;
|
|
19762
|
+
}
|
|
19763
|
+
await this.#emitRecordedEvent(
|
|
19764
|
+
buildRecordedScoreEvent({
|
|
19765
|
+
span: this.#rootRecord,
|
|
19766
|
+
rootSpan: this.#rootRecord,
|
|
19767
|
+
score
|
|
19768
|
+
})
|
|
19769
|
+
);
|
|
19770
|
+
}
|
|
19771
|
+
async addFeedback(feedback) {
|
|
19772
|
+
if (!this.#canEmitRecordedEvent()) {
|
|
19773
|
+
this.#debugRecordedAnnotationUnavailable({ kind: "feedback", traceId: this.traceId });
|
|
19774
|
+
return;
|
|
19775
|
+
}
|
|
19776
|
+
await this.#emitRecordedEvent(
|
|
19777
|
+
buildRecordedFeedbackEvent({
|
|
19778
|
+
span: this.#rootRecord,
|
|
19779
|
+
rootSpan: this.#rootRecord,
|
|
19780
|
+
feedback
|
|
19781
|
+
})
|
|
19782
|
+
);
|
|
19783
|
+
}
|
|
19784
|
+
};
|
|
19785
|
+
function findRootSpan(spans) {
|
|
19786
|
+
const spanIds = new Set(spans.map((span) => span.spanId));
|
|
19787
|
+
return spans.find((span) => !span.parentSpanId || !spanIds.has(span.parentSpanId)) ?? spans[0];
|
|
19788
|
+
}
|
|
19789
|
+
function hydrateRecordedTrace(args) {
|
|
19790
|
+
const {
|
|
19791
|
+
trace,
|
|
19792
|
+
emitRecordedEvent,
|
|
19793
|
+
canEmitRecordedEvent = () => true,
|
|
19794
|
+
debugRecordedAnnotationUnavailable = () => {
|
|
19795
|
+
}
|
|
19796
|
+
} = args;
|
|
19797
|
+
const rootSpan = findRootSpan(trace.spans);
|
|
19798
|
+
if (!rootSpan) {
|
|
19799
|
+
return null;
|
|
19800
|
+
}
|
|
19801
|
+
const recordedSpans = trace.spans.map(
|
|
19802
|
+
(raw) => new RecordedSpanImpl({
|
|
19803
|
+
raw,
|
|
19804
|
+
rootSpan,
|
|
19805
|
+
emitRecordedEvent,
|
|
19806
|
+
canEmitRecordedEvent,
|
|
19807
|
+
debugRecordedAnnotationUnavailable
|
|
19808
|
+
})
|
|
19809
|
+
);
|
|
19810
|
+
const spanMap = new Map(recordedSpans.map((span) => [span.id, span]));
|
|
19811
|
+
for (const span of recordedSpans) {
|
|
19812
|
+
if (!span.parentSpanId) continue;
|
|
19813
|
+
const parent = spanMap.get(span.parentSpanId);
|
|
19814
|
+
if (!parent) continue;
|
|
19815
|
+
span.parent = parent;
|
|
19816
|
+
parent.children.push(span);
|
|
19817
|
+
}
|
|
19818
|
+
const hydratedRootSpan = spanMap.get(rootSpan.spanId);
|
|
19819
|
+
if (!hydratedRootSpan) {
|
|
19820
|
+
return null;
|
|
19821
|
+
}
|
|
19822
|
+
return new RecordedTraceImpl({
|
|
19823
|
+
traceId: trace.traceId,
|
|
19824
|
+
rootSpan: hydratedRootSpan,
|
|
19825
|
+
rootRecord: rootSpan,
|
|
19826
|
+
spans: recordedSpans,
|
|
19827
|
+
emitRecordedEvent,
|
|
19828
|
+
canEmitRecordedEvent,
|
|
19829
|
+
debugRecordedAnnotationUnavailable
|
|
19830
|
+
});
|
|
19831
|
+
}
|
|
19832
|
+
|
|
19503
19833
|
// src/registry.ts
|
|
19504
19834
|
var ObservabilityRegistry = class {
|
|
19505
19835
|
#instances = /* @__PURE__ */ new Map();
|
|
@@ -19740,6 +20070,7 @@ function isInstance(obj) {
|
|
|
19740
20070
|
}
|
|
19741
20071
|
var Observability = class extends base.MastraBase {
|
|
19742
20072
|
#registry = new ObservabilityRegistry();
|
|
20073
|
+
#mastra;
|
|
19743
20074
|
constructor(config2) {
|
|
19744
20075
|
super({
|
|
19745
20076
|
component: logger.RegisteredLogger.OBSERVABILITY,
|
|
@@ -19814,6 +20145,7 @@ var Observability = class extends base.MastraBase {
|
|
|
19814
20145
|
setMastraContext(options) {
|
|
19815
20146
|
const instances = this.listInstances();
|
|
19816
20147
|
const { mastra } = options;
|
|
20148
|
+
this.#mastra = mastra;
|
|
19817
20149
|
instances.forEach((instance) => {
|
|
19818
20150
|
const config2 = instance.getConfig();
|
|
19819
20151
|
const exporters = instance.getExporters();
|
|
@@ -19842,6 +20174,60 @@ var Observability = class extends base.MastraBase {
|
|
|
19842
20174
|
getSelectedInstance(options) {
|
|
19843
20175
|
return this.#registry.getSelected(options);
|
|
19844
20176
|
}
|
|
20177
|
+
async getRecordedTrace(args) {
|
|
20178
|
+
const observabilityStorage = await this.#getObservabilityStorage();
|
|
20179
|
+
if (!observabilityStorage) {
|
|
20180
|
+
return null;
|
|
20181
|
+
}
|
|
20182
|
+
const trace = await observabilityStorage.getTrace({ traceId: args.traceId });
|
|
20183
|
+
if (!trace) {
|
|
20184
|
+
return null;
|
|
20185
|
+
}
|
|
20186
|
+
return hydrateRecordedTrace({
|
|
20187
|
+
trace,
|
|
20188
|
+
emitRecordedEvent: (event) => this.#emitRecordedEvent(event),
|
|
20189
|
+
canEmitRecordedEvent: () => !!this.#getRecordedTraceInstance(),
|
|
20190
|
+
debugRecordedAnnotationUnavailable: ({ kind, traceId, spanId }) => {
|
|
20191
|
+
this.logger?.debug(
|
|
20192
|
+
kind === "score" ? "addScore() is unavailable; rehydrate the trace before calling addScore()" : "addFeedback() is unavailable; rehydrate the trace before calling addFeedback()",
|
|
20193
|
+
{
|
|
20194
|
+
traceId,
|
|
20195
|
+
spanId
|
|
20196
|
+
}
|
|
20197
|
+
);
|
|
20198
|
+
}
|
|
20199
|
+
});
|
|
20200
|
+
}
|
|
20201
|
+
async addScore(args) {
|
|
20202
|
+
const trace = await this.#getStoredTrace(args.traceId);
|
|
20203
|
+
if (!trace) {
|
|
20204
|
+
return;
|
|
20205
|
+
}
|
|
20206
|
+
const event = buildRecordedScoreEventFromTrace({
|
|
20207
|
+
trace,
|
|
20208
|
+
spanId: args.spanId,
|
|
20209
|
+
score: args.score
|
|
20210
|
+
});
|
|
20211
|
+
if (!event) {
|
|
20212
|
+
return;
|
|
20213
|
+
}
|
|
20214
|
+
await this.#emitRecordedEvent(event);
|
|
20215
|
+
}
|
|
20216
|
+
async addFeedback(args) {
|
|
20217
|
+
const trace = await this.#getStoredTrace(args.traceId);
|
|
20218
|
+
if (!trace) {
|
|
20219
|
+
return;
|
|
20220
|
+
}
|
|
20221
|
+
const event = buildRecordedFeedbackEventFromTrace({
|
|
20222
|
+
trace,
|
|
20223
|
+
spanId: args.spanId,
|
|
20224
|
+
feedback: args.feedback
|
|
20225
|
+
});
|
|
20226
|
+
if (!event) {
|
|
20227
|
+
return;
|
|
20228
|
+
}
|
|
20229
|
+
await this.#emitRecordedEvent(event);
|
|
20230
|
+
}
|
|
19845
20231
|
/** Register a named observability instance, optionally marking it as default. */
|
|
19846
20232
|
registerInstance(name, instance, isDefault = false) {
|
|
19847
20233
|
this.#registry.register(name, instance, isDefault);
|
|
@@ -19878,6 +20264,45 @@ var Observability = class extends base.MastraBase {
|
|
|
19878
20264
|
async shutdown() {
|
|
19879
20265
|
await this.#registry.shutdown();
|
|
19880
20266
|
}
|
|
20267
|
+
async #getObservabilityStorage() {
|
|
20268
|
+
const storage = this.#mastra?.getStorage();
|
|
20269
|
+
if (!storage) {
|
|
20270
|
+
return null;
|
|
20271
|
+
}
|
|
20272
|
+
return await storage.getStore("observability") ?? null;
|
|
20273
|
+
}
|
|
20274
|
+
async #getStoredTrace(traceId) {
|
|
20275
|
+
const observabilityStorage = await this.#getObservabilityStorage();
|
|
20276
|
+
if (!observabilityStorage) {
|
|
20277
|
+
return null;
|
|
20278
|
+
}
|
|
20279
|
+
return observabilityStorage.getTrace({ traceId });
|
|
20280
|
+
}
|
|
20281
|
+
#getRecordedTraceInstance() {
|
|
20282
|
+
return this.getDefaultInstance() ?? Array.from(this.listInstances().values())[0];
|
|
20283
|
+
}
|
|
20284
|
+
async #emitRecordedEvent(event) {
|
|
20285
|
+
const instance = this.#getRecordedTraceInstance();
|
|
20286
|
+
if (!instance) {
|
|
20287
|
+
this.logger?.debug(
|
|
20288
|
+
event.type === "score" ? "Score event was dropped because no observability instance is registered" : "Feedback event was dropped because no observability instance is registered",
|
|
20289
|
+
{ eventType: event.type }
|
|
20290
|
+
);
|
|
20291
|
+
return;
|
|
20292
|
+
}
|
|
20293
|
+
if (instance instanceof BaseObservabilityInstance) {
|
|
20294
|
+
instance.__emitRecordedEvent(event);
|
|
20295
|
+
return;
|
|
20296
|
+
}
|
|
20297
|
+
const bridge = instance.getBridge();
|
|
20298
|
+
const handlerResults = [
|
|
20299
|
+
...instance.getExporters().map((exporter) => routeToHandler(exporter, event, this.logger)),
|
|
20300
|
+
...bridge ? [routeToHandler(bridge, event, this.logger)] : []
|
|
20301
|
+
].filter((result) => !!result && typeof result.then === "function");
|
|
20302
|
+
if (handlerResults.length > 0) {
|
|
20303
|
+
await Promise.allSettled(handlerResults);
|
|
20304
|
+
}
|
|
20305
|
+
}
|
|
19881
20306
|
};
|
|
19882
20307
|
|
|
19883
20308
|
// src/tracing-options.ts
|