@mastra/observability 1.0.0-beta.12 → 1.0.0-beta.13
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 +29 -0
- package/dist/exporters/base.d.ts +10 -0
- package/dist/exporters/base.d.ts.map +1 -1
- package/dist/exporters/cloud.d.ts +7 -1
- package/dist/exporters/cloud.d.ts.map +1 -1
- package/dist/exporters/default.d.ts +8 -2
- package/dist/exporters/default.d.ts.map +1 -1
- package/dist/exporters/tracking.d.ts +16 -0
- package/dist/exporters/tracking.d.ts.map +1 -1
- package/dist/index.cjs +111 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +111 -40
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts +9 -0
- package/dist/instances/base.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -4253,6 +4253,18 @@ var BaseExporter = class {
|
|
|
4253
4253
|
const processedEvent = await this.applySpanFormatter(event);
|
|
4254
4254
|
await this._exportTracingEvent(processedEvent);
|
|
4255
4255
|
}
|
|
4256
|
+
/**
|
|
4257
|
+
* Force flush any buffered/queued spans without shutting down the exporter.
|
|
4258
|
+
*
|
|
4259
|
+
* This is useful in serverless environments where you need to ensure spans
|
|
4260
|
+
* are exported before the runtime instance is terminated, while keeping
|
|
4261
|
+
* the exporter active for future requests.
|
|
4262
|
+
*
|
|
4263
|
+
* Default implementation is a no-op. Override to add flush logic.
|
|
4264
|
+
*/
|
|
4265
|
+
async flush() {
|
|
4266
|
+
this.logger.debug(`${this.name} flush called (no-op in base class)`);
|
|
4267
|
+
}
|
|
4256
4268
|
/**
|
|
4257
4269
|
* Shutdown the exporter and clean up resources
|
|
4258
4270
|
*
|
|
@@ -5140,8 +5152,31 @@ var TrackingExporter = class extends BaseExporter {
|
|
|
5140
5152
|
return this.#traceMap.size;
|
|
5141
5153
|
}
|
|
5142
5154
|
// ============================================================================
|
|
5143
|
-
// Shutdown Hooks (Override in subclass as needed)
|
|
5155
|
+
// Flush and Shutdown Hooks (Override in subclass as needed)
|
|
5144
5156
|
// ============================================================================
|
|
5157
|
+
/**
|
|
5158
|
+
* Hook called by flush() to perform vendor-specific flush logic.
|
|
5159
|
+
* Override to send buffered data to the vendor's API.
|
|
5160
|
+
*
|
|
5161
|
+
* Unlike _postShutdown(), this method should NOT release resources,
|
|
5162
|
+
* as the exporter will continue to be used after flushing.
|
|
5163
|
+
*/
|
|
5164
|
+
async _flush() {
|
|
5165
|
+
}
|
|
5166
|
+
/**
|
|
5167
|
+
* Force flush any buffered data without shutting down the exporter.
|
|
5168
|
+
* This is useful in serverless environments where you need to ensure spans
|
|
5169
|
+
* are exported before the runtime instance is terminated.
|
|
5170
|
+
*
|
|
5171
|
+
* Subclasses should override _flush() to implement vendor-specific flush logic.
|
|
5172
|
+
*/
|
|
5173
|
+
async flush() {
|
|
5174
|
+
if (this.isDisabled) {
|
|
5175
|
+
return;
|
|
5176
|
+
}
|
|
5177
|
+
this.logger.debug(`${this.name}: Flushing`);
|
|
5178
|
+
await this._flush();
|
|
5179
|
+
}
|
|
5145
5180
|
/**
|
|
5146
5181
|
* Hook called at the start of shutdown, before cancelling timers and aborting spans.
|
|
5147
5182
|
* Override to perform vendor-specific pre-shutdown tasks.
|
|
@@ -5310,7 +5345,7 @@ var CloudExporter = class extends BaseExporter {
|
|
|
5310
5345
|
});
|
|
5311
5346
|
}, this.cloudConfig.maxBatchWaitMs);
|
|
5312
5347
|
}
|
|
5313
|
-
async
|
|
5348
|
+
async flushBuffer() {
|
|
5314
5349
|
if (this.flushTimer) {
|
|
5315
5350
|
clearTimeout(this.flushTimer);
|
|
5316
5351
|
this.flushTimer = null;
|
|
@@ -5366,6 +5401,22 @@ var CloudExporter = class extends BaseExporter {
|
|
|
5366
5401
|
this.buffer.firstEventTime = void 0;
|
|
5367
5402
|
this.buffer.totalSize = 0;
|
|
5368
5403
|
}
|
|
5404
|
+
/**
|
|
5405
|
+
* Force flush any buffered spans without shutting down the exporter.
|
|
5406
|
+
* This is useful in serverless environments where you need to ensure spans
|
|
5407
|
+
* are exported before the runtime instance is terminated.
|
|
5408
|
+
*/
|
|
5409
|
+
async flush() {
|
|
5410
|
+
if (this.isDisabled) {
|
|
5411
|
+
return;
|
|
5412
|
+
}
|
|
5413
|
+
if (this.buffer.totalSize > 0) {
|
|
5414
|
+
this.logger.debug("Flushing buffered events", {
|
|
5415
|
+
bufferedEvents: this.buffer.totalSize
|
|
5416
|
+
});
|
|
5417
|
+
await this.flushBuffer();
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5369
5420
|
async shutdown() {
|
|
5370
5421
|
if (this.isDisabled) {
|
|
5371
5422
|
return;
|
|
@@ -5374,27 +5425,22 @@ var CloudExporter = class extends BaseExporter {
|
|
|
5374
5425
|
clearTimeout(this.flushTimer);
|
|
5375
5426
|
this.flushTimer = null;
|
|
5376
5427
|
}
|
|
5377
|
-
|
|
5378
|
-
this.
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
{
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
error
|
|
5394
|
-
);
|
|
5395
|
-
this.logger.trackException(mastraError);
|
|
5396
|
-
this.logger.error("Failed to flush remaining events during shutdown", mastraError);
|
|
5397
|
-
}
|
|
5428
|
+
try {
|
|
5429
|
+
await this.flush();
|
|
5430
|
+
} catch (error) {
|
|
5431
|
+
const mastraError = new MastraError(
|
|
5432
|
+
{
|
|
5433
|
+
id: `CLOUD_EXPORTER_FAILED_TO_FLUSH_REMAINING_EVENTS_DURING_SHUTDOWN`,
|
|
5434
|
+
domain: ErrorDomain.MASTRA_OBSERVABILITY,
|
|
5435
|
+
category: ErrorCategory.USER,
|
|
5436
|
+
details: {
|
|
5437
|
+
remainingEvents: this.buffer.totalSize
|
|
5438
|
+
}
|
|
5439
|
+
},
|
|
5440
|
+
error
|
|
5441
|
+
);
|
|
5442
|
+
this.logger.trackException(mastraError);
|
|
5443
|
+
this.logger.error("Failed to flush remaining events during shutdown", mastraError);
|
|
5398
5444
|
}
|
|
5399
5445
|
this.logger.info("CloudExporter shutdown complete");
|
|
5400
5446
|
}
|
|
@@ -5698,7 +5744,7 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
5698
5744
|
clearTimeout(this.#flushTimer);
|
|
5699
5745
|
}
|
|
5700
5746
|
this.#flushTimer = setTimeout(() => {
|
|
5701
|
-
this.
|
|
5747
|
+
this.flushBuffer().catch((error) => {
|
|
5702
5748
|
this.logger.error("Scheduled flush failed", {
|
|
5703
5749
|
error: error instanceof Error ? error.message : String(error)
|
|
5704
5750
|
});
|
|
@@ -5832,7 +5878,7 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
5832
5878
|
handleBatchWithUpdatesEvent(event) {
|
|
5833
5879
|
this.addToBuffer(event);
|
|
5834
5880
|
if (this.shouldFlush()) {
|
|
5835
|
-
this.
|
|
5881
|
+
this.flushBuffer().catch((error) => {
|
|
5836
5882
|
this.logger.error("Batch flush failed", {
|
|
5837
5883
|
error: error instanceof Error ? error.message : String(error)
|
|
5838
5884
|
});
|
|
@@ -5848,7 +5894,7 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
5848
5894
|
if (event.type === TracingEventType.SPAN_ENDED) {
|
|
5849
5895
|
this.addToBuffer(event);
|
|
5850
5896
|
if (this.shouldFlush()) {
|
|
5851
|
-
this.
|
|
5897
|
+
this.flushBuffer().catch((error) => {
|
|
5852
5898
|
this.logger.error("Batch flush failed", {
|
|
5853
5899
|
error: error instanceof Error ? error.message : String(error)
|
|
5854
5900
|
});
|
|
@@ -5865,9 +5911,9 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
5865
5911
|
return this.#config.retryDelayMs * Math.pow(2, attempt);
|
|
5866
5912
|
}
|
|
5867
5913
|
/**
|
|
5868
|
-
* Flushes the current buffer to storage with retry logic
|
|
5914
|
+
* Flushes the current buffer to storage with retry logic (internal implementation)
|
|
5869
5915
|
*/
|
|
5870
|
-
async
|
|
5916
|
+
async flushBuffer() {
|
|
5871
5917
|
if (!this.#observability) {
|
|
5872
5918
|
this.logger.debug("Cannot flush traces. Observability storage is not initialized");
|
|
5873
5919
|
return;
|
|
@@ -5974,23 +6020,25 @@ var DefaultExporter = class extends BaseExporter {
|
|
|
5974
6020
|
break;
|
|
5975
6021
|
}
|
|
5976
6022
|
}
|
|
6023
|
+
/**
|
|
6024
|
+
* Force flush any buffered spans without shutting down the exporter.
|
|
6025
|
+
* This is useful in serverless environments where you need to ensure spans
|
|
6026
|
+
* are exported before the runtime instance is terminated.
|
|
6027
|
+
*/
|
|
6028
|
+
async flush() {
|
|
6029
|
+
if (this.buffer.totalSize > 0) {
|
|
6030
|
+
this.logger.debug("Flushing buffered events", {
|
|
6031
|
+
bufferedEvents: this.buffer.totalSize
|
|
6032
|
+
});
|
|
6033
|
+
await this.flushBuffer();
|
|
6034
|
+
}
|
|
6035
|
+
}
|
|
5977
6036
|
async shutdown() {
|
|
5978
6037
|
if (this.#flushTimer) {
|
|
5979
6038
|
clearTimeout(this.#flushTimer);
|
|
5980
6039
|
this.#flushTimer = null;
|
|
5981
6040
|
}
|
|
5982
|
-
|
|
5983
|
-
this.logger.info("Flushing remaining events on shutdown", {
|
|
5984
|
-
remainingEvents: this.buffer.totalSize
|
|
5985
|
-
});
|
|
5986
|
-
try {
|
|
5987
|
-
await this.flush();
|
|
5988
|
-
} catch (error) {
|
|
5989
|
-
this.logger.error("Failed to flush remaining events during shutdown", {
|
|
5990
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5991
|
-
});
|
|
5992
|
-
}
|
|
5993
|
-
}
|
|
6041
|
+
await this.flush();
|
|
5994
6042
|
this.logger.info("DefaultExporter shutdown complete");
|
|
5995
6043
|
}
|
|
5996
6044
|
};
|
|
@@ -7364,6 +7412,29 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
7364
7412
|
this.logger.debug(`[Observability] Initialization started [name=${this.name}]`);
|
|
7365
7413
|
this.logger.info(`[Observability] Initialized successfully [name=${this.name}]`);
|
|
7366
7414
|
}
|
|
7415
|
+
/**
|
|
7416
|
+
* Force flush any buffered/queued spans from all exporters and the bridge
|
|
7417
|
+
* without shutting down the observability instance.
|
|
7418
|
+
*
|
|
7419
|
+
* This is useful in serverless environments (like Vercel's fluid compute) where
|
|
7420
|
+
* you need to ensure all spans are exported before the runtime instance is
|
|
7421
|
+
* terminated, while keeping the observability system active for future requests.
|
|
7422
|
+
*/
|
|
7423
|
+
async flush() {
|
|
7424
|
+
this.logger.debug(`[Observability] Flush started [name=${this.name}]`);
|
|
7425
|
+
const flushPromises = [...this.exporters.map((e) => e.flush())];
|
|
7426
|
+
if (this.config.bridge) {
|
|
7427
|
+
flushPromises.push(this.config.bridge.flush());
|
|
7428
|
+
}
|
|
7429
|
+
const results = await Promise.allSettled(flushPromises);
|
|
7430
|
+
results.forEach((result, index) => {
|
|
7431
|
+
if (result.status === "rejected") {
|
|
7432
|
+
const targetName = index < this.exporters.length ? this.exporters[index]?.name : "bridge";
|
|
7433
|
+
this.logger.error(`[Observability] Flush error [target=${targetName}]`, result.reason);
|
|
7434
|
+
}
|
|
7435
|
+
});
|
|
7436
|
+
this.logger.debug(`[Observability] Flush completed [name=${this.name}]`);
|
|
7437
|
+
}
|
|
7367
7438
|
/**
|
|
7368
7439
|
* Shutdown Observability and clean up resources
|
|
7369
7440
|
*/
|