@mastra/observability 1.8.0 → 1.9.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 CHANGED
@@ -1,5 +1,51 @@
1
1
  # @mastra/observability
2
2
 
3
+ ## 1.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added support for project-scoped CloudExporter collector routes for organization API keys. ([#15189](https://github.com/mastra-ai/mastra/pull/15189))
8
+
9
+ **What changed**
10
+ CloudExporter now accepts a `projectId` option and reads `MASTRA_PROJECT_ID` so remote writes can target project-scoped collector URLs when you authenticate with an organization API key.
11
+
12
+ ```ts
13
+ new CloudExporter({
14
+ accessToken: process.env.MASTRA_CLOUD_ACCESS_TOKEN,
15
+ projectId: process.env.MASTRA_PROJECT_ID,
16
+ });
17
+ ```
18
+
19
+ When `projectId` is set, base endpoints resolve to `/projects/:projectId/ai/{signal}/publish`. Without it, existing JWT-style `/ai/{signal}/publish` routes still work as before.
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [[`ef94400`](https://github.com/mastra-ai/mastra/commit/ef9440049402596b31f2ab976c5e4508f6cb6c91), [`3db852b`](https://github.com/mastra-ai/mastra/commit/3db852bff74e29f60d415a7b0f1583d6ce2bad92)]:
24
+ - @mastra/core@1.24.1
25
+
26
+ ## 1.9.0-alpha.0
27
+
28
+ ### Minor Changes
29
+
30
+ - Added support for project-scoped CloudExporter collector routes for organization API keys. ([#15189](https://github.com/mastra-ai/mastra/pull/15189))
31
+
32
+ **What changed**
33
+ CloudExporter now accepts a `projectId` option and reads `MASTRA_PROJECT_ID` so remote writes can target project-scoped collector URLs when you authenticate with an organization API key.
34
+
35
+ ```ts
36
+ new CloudExporter({
37
+ accessToken: process.env.MASTRA_CLOUD_ACCESS_TOKEN,
38
+ projectId: process.env.MASTRA_PROJECT_ID,
39
+ });
40
+ ```
41
+
42
+ When `projectId` is set, base endpoints resolve to `/projects/:projectId/ai/{signal}/publish`. Without it, existing JWT-style `/ai/{signal}/publish` routes still work as before.
43
+
44
+ ### Patch Changes
45
+
46
+ - Updated dependencies [[`ef94400`](https://github.com/mastra-ai/mastra/commit/ef9440049402596b31f2ab976c5e4508f6cb6c91)]:
47
+ - @mastra/core@1.24.1-alpha.0
48
+
3
49
  ## 1.8.0
4
50
 
5
51
  ### Minor Changes
@@ -6,6 +6,7 @@ export interface CloudExporterConfig extends BaseExporterConfig {
6
6
  maxBatchWaitMs?: number;
7
7
  maxRetries?: number;
8
8
  accessToken?: string;
9
+ projectId?: string;
9
10
  endpoint?: string;
10
11
  tracesEndpoint?: string;
11
12
  logsEndpoint?: string;
@@ -15,7 +16,7 @@ export interface CloudExporterConfig extends BaseExporterConfig {
15
16
  }
16
17
  export declare class CloudExporter extends BaseExporter {
17
18
  name: string;
18
- private cloudConfig;
19
+ private readonly cloudConfig;
19
20
  private buffer;
20
21
  private flushTimer;
21
22
  private inFlightFlushes;
@@ -1 +1 @@
1
- {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/exporters/cloud.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAgLD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,IAAI,SAAyC;IAE7C,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAA4B;gBAEvC,MAAM,GAAE,mBAAwB;cA0D5B,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjE,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1D,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;YAMR,mBAAmB;IAYjC,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,aAAa;YAoBP,WAAW;IAoDzB;;OAEG;YACW,WAAW;YAuBX,gBAAgB;IA+B9B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAiChC"}
1
+ {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/exporters/cloud.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EAEZ,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA+LD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,IAAI,SAAyC;IAE7C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,eAAe,CAA4B;gBAEvC,MAAM,GAAE,mBAAwB;cAgE5B,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjE,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAShD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1D,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,cAAc;YAMR,mBAAmB;IAYjC,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,aAAa;YAoBP,WAAW;IAoDzB;;OAEG;YACW,WAAW;YAuBX,gBAAgB;IA+B9B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAiChC"}
package/dist/index.cjs CHANGED
@@ -15051,14 +15051,7 @@ var SIGNAL_PUBLISH_SUFFIXES = {
15051
15051
  scores: "/scores/publish",
15052
15052
  feedback: "/feedback/publish"
15053
15053
  };
15054
- var SIGNAL_PUBLISH_PATHS = {
15055
- traces: "/ai/spans/publish",
15056
- logs: "/ai/logs/publish",
15057
- metrics: "/ai/metrics/publish",
15058
- scores: "/ai/scores/publish",
15059
- feedback: "/ai/feedback/publish"
15060
- };
15061
- var SIGNAL_PAYLOAD_KEYS = {
15054
+ var SIGNAL_PUBLISH_SEGMENTS = {
15062
15055
  traces: "spans",
15063
15056
  logs: "logs",
15064
15057
  metrics: "metrics",
@@ -15087,6 +15080,18 @@ function createInvalidEndpointError(endpoint, text, cause) {
15087
15080
  cause
15088
15081
  );
15089
15082
  }
15083
+ var VALID_PROJECT_ID = /^[a-zA-Z0-9_-]+$/;
15084
+ function createInvalidProjectIdError(projectId) {
15085
+ return new error$1.MastraError({
15086
+ id: `CLOUD_EXPORTER_INVALID_PROJECT_ID`,
15087
+ text: "CloudExporter projectId must only contain letters, numbers, hyphens, and underscores.",
15088
+ domain: error$1.ErrorDomain.MASTRA_OBSERVABILITY,
15089
+ category: error$1.ErrorCategory.USER,
15090
+ details: {
15091
+ projectId
15092
+ }
15093
+ });
15094
+ }
15090
15095
  function resolveBaseEndpoint(baseEndpoint) {
15091
15096
  const normalizedEndpoint = trimTrailingSlashes(baseEndpoint);
15092
15097
  const invalidText = 'CloudExporter endpoint must be a base origin like "https://collector.example.com" with no path, search, or hash.';
@@ -15103,10 +15108,17 @@ function resolveBaseEndpoint(baseEndpoint) {
15103
15108
  throw createInvalidEndpointError(baseEndpoint, invalidText, error48);
15104
15109
  }
15105
15110
  }
15106
- function buildSignalEndpoint(baseEndpoint, signal) {
15107
- return `${baseEndpoint}${SIGNAL_PUBLISH_PATHS[signal]}`;
15111
+ function buildSignalPath(signal, projectId) {
15112
+ const signalSegment = SIGNAL_PUBLISH_SEGMENTS[signal];
15113
+ if (!projectId) {
15114
+ return `/ai/${signalSegment}/publish`;
15115
+ }
15116
+ return `/projects/${projectId}/ai/${signalSegment}/publish`;
15117
+ }
15118
+ function buildSignalEndpoint(baseEndpoint, signal, projectId) {
15119
+ return `${baseEndpoint}${buildSignalPath(signal, projectId)}`;
15108
15120
  }
15109
- function resolveExplicitSignalEndpoint(signal, endpoint) {
15121
+ function resolveExplicitSignalEndpoint(signal, endpoint, projectId) {
15110
15122
  const normalizedEndpoint = trimTrailingSlashes(endpoint);
15111
15123
  const invalidText = `CloudExporter ${signal}Endpoint must be a base origin like "https://collector.example.com" or a full ${signal} publish URL ending in "${SIGNAL_PUBLISH_SUFFIXES[signal]}".`;
15112
15124
  try {
@@ -15117,7 +15129,7 @@ function resolveExplicitSignalEndpoint(signal, endpoint) {
15117
15129
  const normalizedOrigin = trimTrailingSlashes(parsedEndpoint.origin);
15118
15130
  const normalizedPathname = trimTrailingSlashes(parsedEndpoint.pathname);
15119
15131
  if (!normalizedPathname || normalizedPathname === "/") {
15120
- return buildSignalEndpoint(normalizedOrigin, signal);
15132
+ return buildSignalEndpoint(normalizedOrigin, signal, projectId);
15121
15133
  }
15122
15134
  if (normalizedPathname.endsWith(SIGNAL_PUBLISH_SUFFIXES[signal])) {
15123
15135
  return `${normalizedOrigin}${normalizedPathname}`;
@@ -15160,7 +15172,12 @@ var CloudExporter = class extends BaseExporter {
15160
15172
  inFlightFlushes = /* @__PURE__ */ new Set();
15161
15173
  constructor(config2 = {}) {
15162
15174
  super(config2);
15175
+ if (config2.projectId !== void 0 && !VALID_PROJECT_ID.test(config2.projectId)) {
15176
+ throw createInvalidProjectIdError(config2.projectId);
15177
+ }
15163
15178
  const accessToken = config2.accessToken ?? process.env.MASTRA_CLOUD_ACCESS_TOKEN;
15179
+ const rawProjectId = config2.projectId ?? process.env.MASTRA_PROJECT_ID;
15180
+ const projectId = rawProjectId && VALID_PROJECT_ID.test(rawProjectId) ? rawProjectId : void 0;
15164
15181
  if (!accessToken) {
15165
15182
  this.setDisabled("MASTRA_CLOUD_ACCESS_TOKEN environment variable not set.");
15166
15183
  }
@@ -15168,19 +15185,19 @@ var CloudExporter = class extends BaseExporter {
15168
15185
  let baseEndpoint;
15169
15186
  let tracesEndpoint;
15170
15187
  if (tracesEndpointOverride) {
15171
- tracesEndpoint = resolveExplicitSignalEndpoint("traces", tracesEndpointOverride);
15188
+ tracesEndpoint = resolveExplicitSignalEndpoint("traces", tracesEndpointOverride, projectId);
15172
15189
  } else {
15173
15190
  baseEndpoint = resolveBaseEndpoint(config2.endpoint ?? DEFAULT_CLOUD_ENDPOINT);
15174
- tracesEndpoint = buildSignalEndpoint(baseEndpoint, "traces");
15191
+ tracesEndpoint = buildSignalEndpoint(baseEndpoint, "traces", projectId);
15175
15192
  }
15176
15193
  const resolveConfiguredSignalEndpoint = (signal, explicitEndpoint) => {
15177
15194
  if (explicitEndpoint) {
15178
- return resolveExplicitSignalEndpoint(signal, explicitEndpoint);
15195
+ return resolveExplicitSignalEndpoint(signal, explicitEndpoint, projectId);
15179
15196
  }
15180
15197
  if (tracesEndpointOverride) {
15181
15198
  return deriveSignalEndpointFromTracesEndpoint(signal, tracesEndpoint);
15182
15199
  }
15183
- return buildSignalEndpoint(baseEndpoint, signal);
15200
+ return buildSignalEndpoint(baseEndpoint, signal, projectId);
15184
15201
  };
15185
15202
  this.cloudConfig = {
15186
15203
  logger: this.logger,
@@ -15404,7 +15421,7 @@ var CloudExporter = class extends BaseExporter {
15404
15421
  const options = {
15405
15422
  method: "POST",
15406
15423
  headers,
15407
- body: JSON.stringify({ [SIGNAL_PAYLOAD_KEYS[signal]]: records })
15424
+ body: JSON.stringify({ [SIGNAL_PUBLISH_SEGMENTS[signal]]: records })
15408
15425
  };
15409
15426
  await utils.fetchWithRetry(endpointMap[signal], options, this.cloudConfig.maxRetries);
15410
15427
  }