@mastra/otel-exporter 1.0.0-beta.11 → 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 CHANGED
@@ -1,5 +1,75 @@
1
1
  # @mastra/otel-exporter
2
2
 
3
+ ## 1.0.0-beta.13
4
+
5
+ ### Minor Changes
6
+
7
+ - Added `TrackingExporter` base class with improved handling for: ([#11870](https://github.com/mastra-ai/mastra/pull/11870))
8
+ - **Out-of-order span processing**: Spans that arrive before their parents are now queued and processed once dependencies are available
9
+ - **Delayed cleanup**: Trace data is retained briefly after spans end to handle late-arriving updates
10
+ - **Memory management**: Configurable limits on pending and total traces to prevent memory leaks
11
+
12
+ New configuration options on `TrackingExporterConfig`:
13
+ - `earlyQueueMaxAttempts` - Max retry attempts for queued events (default: 5)
14
+ - `earlyQueueTTLMs` - TTL for queued events in ms (default: 30000)
15
+ - `traceCleanupDelayMs` - Delay before cleaning up completed traces (default: 30000)
16
+ - `maxPendingCleanupTraces` - Soft cap on traces awaiting cleanup (default: 100)
17
+ - `maxTotalTraces` - Hard cap on total traces (default: 500)
18
+
19
+ Updated @mastra/braintrust, @mastra/langfuse, @mastra/langsmith, @mastra/posthog to use the new TrackingExporter
20
+
21
+ - Export getAttributes and getSpanName GenAI semantic convention helpers ([#11890](https://github.com/mastra-ai/mastra/pull/11890))
22
+
23
+ These functions were previously internal but are now exported to support:
24
+ - The new @mastra/sentry exporter which uses them for consistent attribute formatting
25
+ - Custom exporter implementations that want to follow GenAI semantic conventions
26
+
27
+ ### Patch Changes
28
+
29
+ - Fixed formatting of model_step, model_chunk, and tool_call spans in Arize Exporter. ([#11922](https://github.com/mastra-ai/mastra/pull/11922))
30
+
31
+ Also removed `tools` output from `model_step` spans for all exporters.
32
+
33
+ - Updated dependencies [[`ebae12a`](https://github.com/mastra-ai/mastra/commit/ebae12a2dd0212e75478981053b148a2c246962d), [`c61a0a5`](https://github.com/mastra-ai/mastra/commit/c61a0a5de4904c88fd8b3718bc26d1be1c2ec6e7), [`69136e7`](https://github.com/mastra-ai/mastra/commit/69136e748e32f57297728a4e0f9a75988462f1a7), [`449aed2`](https://github.com/mastra-ai/mastra/commit/449aed2ba9d507b75bf93d427646ea94f734dfd1), [`eb648a2`](https://github.com/mastra-ai/mastra/commit/eb648a2cc1728f7678768dd70cd77619b448dab9), [`0131105`](https://github.com/mastra-ai/mastra/commit/0131105532e83bdcbb73352fc7d0879eebf140dc), [`9d5059e`](https://github.com/mastra-ai/mastra/commit/9d5059eae810829935fb08e81a9bb7ecd5b144a7), [`ef756c6`](https://github.com/mastra-ai/mastra/commit/ef756c65f82d16531c43f49a27290a416611e526), [`b00ccd3`](https://github.com/mastra-ai/mastra/commit/b00ccd325ebd5d9e37e34dd0a105caae67eb568f), [`3bdfa75`](https://github.com/mastra-ai/mastra/commit/3bdfa7507a91db66f176ba8221aa28dd546e464a), [`e770de9`](https://github.com/mastra-ai/mastra/commit/e770de941a287a49b1964d44db5a5763d19890a6), [`52e2716`](https://github.com/mastra-ai/mastra/commit/52e2716b42df6eff443de72360ae83e86ec23993), [`27b4040`](https://github.com/mastra-ai/mastra/commit/27b4040bfa1a95d92546f420a02a626b1419a1d6), [`610a70b`](https://github.com/mastra-ai/mastra/commit/610a70bdad282079f0c630e0d7bb284578f20151), [`8dc7f55`](https://github.com/mastra-ai/mastra/commit/8dc7f55900395771da851dc7d78d53ae84fe34ec), [`8379099`](https://github.com/mastra-ai/mastra/commit/8379099fc467af6bef54dd7f80c9bd75bf8bbddf), [`b06be72`](https://github.com/mastra-ai/mastra/commit/b06be7223d5ef23edc98c01a67ef713c6cc039f9), [`8c0ec25`](https://github.com/mastra-ai/mastra/commit/8c0ec25646c8a7df253ed1e5ff4863a0d3f1316c), [`ff4d9a6`](https://github.com/mastra-ai/mastra/commit/ff4d9a6704fc87b31a380a76ed22736fdedbba5a), [`69821ef`](https://github.com/mastra-ai/mastra/commit/69821ef806482e2c44e2197ac0b050c3fe3a5285), [`1ed5716`](https://github.com/mastra-ai/mastra/commit/1ed5716830867b3774c4a1b43cc0d82935f32b96), [`4186bdd`](https://github.com/mastra-ai/mastra/commit/4186bdd00731305726fa06adba0b076a1d50b49f), [`7aaf973`](https://github.com/mastra-ai/mastra/commit/7aaf973f83fbbe9521f1f9e7a4fd99b8de464617)]:
34
+ - @mastra/core@1.0.0-beta.22
35
+ - @mastra/observability@1.0.0-beta.11
36
+
37
+ ## 1.0.0-beta.12
38
+
39
+ ### Minor Changes
40
+
41
+ - feat(observability): add zero-config environment variable support for all exporters ([#11686](https://github.com/mastra-ai/mastra/pull/11686))
42
+
43
+ All observability exporters now support zero-config setup via environment variables. Set the appropriate environment variables and instantiate exporters with no configuration:
44
+ - **Langfuse**: `LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, `LANGFUSE_BASE_URL`
45
+ - **Braintrust**: `BRAINTRUST_API_KEY`, `BRAINTRUST_ENDPOINT`
46
+ - **PostHog**: `POSTHOG_API_KEY`, `POSTHOG_HOST`
47
+ - **Arize/Phoenix**: `ARIZE_SPACE_ID`, `ARIZE_API_KEY`, `ARIZE_PROJECT_NAME`, `PHOENIX_ENDPOINT`, `PHOENIX_API_KEY`, `PHOENIX_PROJECT_NAME`
48
+ - **OTEL Providers**:
49
+ - Dash0: `DASH0_API_KEY`, `DASH0_ENDPOINT`, `DASH0_DATASET`
50
+ - SigNoz: `SIGNOZ_API_KEY`, `SIGNOZ_REGION`, `SIGNOZ_ENDPOINT`
51
+ - New Relic: `NEW_RELIC_LICENSE_KEY`, `NEW_RELIC_ENDPOINT`
52
+ - Traceloop: `TRACELOOP_API_KEY`, `TRACELOOP_DESTINATION_ID`, `TRACELOOP_ENDPOINT`
53
+ - Laminar: `LMNR_PROJECT_API_KEY`, `LAMINAR_ENDPOINT`
54
+
55
+ Example usage:
56
+
57
+ ```typescript
58
+ // Zero-config - reads from environment variables
59
+ new LangfuseExporter();
60
+ new BraintrustExporter();
61
+ new PosthogExporter();
62
+ new ArizeExporter();
63
+ new OtelExporter({ provider: { signoz: {} } });
64
+ ```
65
+
66
+ Explicit configuration still works and takes precedence over environment variables.
67
+
68
+ ### Patch Changes
69
+
70
+ - Updated dependencies [[`08766f1`](https://github.com/mastra-ai/mastra/commit/08766f15e13ac0692fde2a8bd366c2e16e4321df), [`ae8baf7`](https://github.com/mastra-ai/mastra/commit/ae8baf7d8adcb0ff9dac11880400452bc49b33ff), [`cfabdd4`](https://github.com/mastra-ai/mastra/commit/cfabdd4aae7a726b706942d6836eeca110fb6267), [`a0e437f`](https://github.com/mastra-ai/mastra/commit/a0e437fac561b28ee719e0302d72b2f9b4c138f0), [`bec5efd`](https://github.com/mastra-ai/mastra/commit/bec5efde96653ccae6604e68c696d1bc6c1a0bf5), [`9eedf7d`](https://github.com/mastra-ai/mastra/commit/9eedf7de1d6e0022a2f4e5e9e6fe1ec468f9b43c)]:
71
+ - @mastra/core@1.0.0-beta.21
72
+
3
73
  ## 1.0.0-beta.11
4
74
 
5
75
  ### Patch Changes
package/README.md CHANGED
@@ -4,6 +4,18 @@ Export Mastra traces to any OpenTelemetry-compatible observability platform.
4
4
 
5
5
  > **⚠️ Important:** This package requires you to install an additional exporter package based on your provider. Each provider section below includes the specific installation command.
6
6
 
7
+ ## Environment Variables
8
+
9
+ All providers support zero-config setup via environment variables. Set the appropriate variables and the exporter will automatically use them:
10
+
11
+ | Provider | Environment Variables |
12
+ | --------- | ------------------------------------------------------------------------------------------- |
13
+ | Dash0 | `DASH0_API_KEY` (required), `DASH0_ENDPOINT` (required), `DASH0_DATASET` (optional) |
14
+ | SigNoz | `SIGNOZ_API_KEY` (required), `SIGNOZ_REGION` (optional), `SIGNOZ_ENDPOINT` (optional) |
15
+ | New Relic | `NEW_RELIC_LICENSE_KEY` (required), `NEW_RELIC_ENDPOINT` (optional) |
16
+ | Traceloop | `TRACELOOP_API_KEY` (required), `TRACELOOP_DESTINATION_ID`, `TRACELOOP_ENDPOINT` (optional) |
17
+ | Laminar | `LMNR_PROJECT_API_KEY` (required), `LAMINAR_ENDPOINT` (optional) |
18
+
7
19
  ## Supported Providers
8
20
 
9
21
  ### Dash0
@@ -15,7 +27,16 @@ Export Mastra traces to any OpenTelemetry-compatible observability platform.
15
27
  npm install @mastra/otel-exporter @opentelemetry/exporter-trace-otlp-grpc @grpc/grpc-js
16
28
  ```
17
29
 
18
- #### Configuration
30
+ #### Zero-Config Setup
31
+
32
+ ```bash
33
+ # Required
34
+ DASH0_API_KEY=your-api-key
35
+ DASH0_ENDPOINT=ingress.us-west-2.aws.dash0.com:4317
36
+
37
+ # Optional
38
+ DASH0_DATASET=production
39
+ ```
19
40
 
20
41
  ```typescript
21
42
  import { OtelExporter } from '@mastra/otel-exporter';
@@ -26,24 +47,28 @@ const mastra = new Mastra({
26
47
  observability: {
27
48
  configs: {
28
49
  otel: {
29
- serviceName: 'mastra-service',
30
- exporters: [
31
- new OtelExporter({
32
- provider: {
33
- dash0: {
34
- apiKey: process.env.DASH0_API_KEY, // Required at runtime
35
- endpoint: 'ingress.us-west-2.aws.dash0.com:4317', // Required at runtime
36
- dataset: 'production', // Optional: dataset name
37
- }
38
- },
39
- })
40
- ],
50
+ serviceName: 'my-service',
51
+ exporters: [new OtelExporter({ provider: { dash0: {} } })],
41
52
  },
42
53
  },
43
54
  },
44
55
  });
45
56
  ```
46
57
 
58
+ #### Explicit Configuration
59
+
60
+ ```typescript
61
+ new OtelExporter({
62
+ provider: {
63
+ dash0: {
64
+ apiKey: 'your-api-key',
65
+ endpoint: 'ingress.us-west-2.aws.dash0.com:4317',
66
+ dataset: 'production', // Optional
67
+ },
68
+ },
69
+ });
70
+ ```
71
+
47
72
  **Note:** Get your endpoint from your Dash0 dashboard. It should be in the format `ingress.{region}.aws.dash0.com:4317`.
48
73
 
49
74
  ### SigNoz
@@ -54,7 +79,16 @@ const mastra = new Mastra({
54
79
  npm install @mastra/otel-exporter @opentelemetry/exporter-trace-otlp-proto
55
80
  ```
56
81
 
57
- #### Configuration
82
+ #### Zero-Config Setup
83
+
84
+ ```bash
85
+ # Required
86
+ SIGNOZ_API_KEY=your-api-key
87
+
88
+ # Optional
89
+ SIGNOZ_REGION=us # 'us' | 'eu' | 'in'
90
+ SIGNOZ_ENDPOINT=https://my-signoz.example.com # For self-hosted
91
+ ```
58
92
 
59
93
  ```typescript
60
94
  import { OtelExporter } from '@mastra/otel-exporter';
@@ -65,24 +99,28 @@ const mastra = new Mastra({
65
99
  observability: {
66
100
  configs: {
67
101
  otel: {
68
- serviceName: 'mastra-service',
69
- exporters: [
70
- new OtelExporter({
71
- provider: {
72
- signoz: {
73
- apiKey: process.env.SIGNOZ_API_KEY, // Required at runtime
74
- region: 'us', // Optional: 'us' | 'eu' | 'in', defaults to 'us'
75
- // endpoint: 'https://my-signoz.example.com', // Optional: for self-hosted
76
- }
77
- },
78
- })
79
- ],
102
+ serviceName: 'my-service',
103
+ exporters: [new OtelExporter({ provider: { signoz: {} } })],
80
104
  },
81
105
  },
82
106
  },
83
107
  });
84
108
  ```
85
109
 
110
+ #### Explicit Configuration
111
+
112
+ ```typescript
113
+ new OtelExporter({
114
+ provider: {
115
+ signoz: {
116
+ apiKey: 'your-api-key',
117
+ region: 'us', // Optional: 'us' | 'eu' | 'in'
118
+ endpoint: 'https://my-signoz.example.com', // Optional: for self-hosted
119
+ },
120
+ },
121
+ });
122
+ ```
123
+
86
124
  ### New Relic
87
125
 
88
126
  #### Installation
@@ -91,7 +129,15 @@ const mastra = new Mastra({
91
129
  npm install @mastra/otel-exporter @opentelemetry/exporter-trace-otlp-proto
92
130
  ```
93
131
 
94
- #### Configuration
132
+ #### Zero-Config Setup
133
+
134
+ ```bash
135
+ # Required
136
+ NEW_RELIC_LICENSE_KEY=your-license-key
137
+
138
+ # Optional
139
+ NEW_RELIC_ENDPOINT=https://otlp.eu01.nr-data.net # For EU region
140
+ ```
95
141
 
96
142
  ```typescript
97
143
  import { OtelExporter } from '@mastra/otel-exporter';
@@ -102,23 +148,27 @@ const mastra = new Mastra({
102
148
  observability: {
103
149
  configs: {
104
150
  otel: {
105
- serviceName: 'mastra-service',
106
- exporters: [
107
- new OtelExporter({
108
- provider: {
109
- newrelic: {
110
- apiKey: process.env.NEW_RELIC_LICENSE_KEY, // Required at runtime
111
- // endpoint: 'https://otlp.eu01.nr-data.net', // Optional: for EU region
112
- }
113
- },
114
- })
115
- ],
151
+ serviceName: 'my-service',
152
+ exporters: [new OtelExporter({ provider: { newrelic: {} } })],
116
153
  },
117
154
  },
118
155
  },
119
156
  });
120
157
  ```
121
158
 
159
+ #### Explicit Configuration
160
+
161
+ ```typescript
162
+ new OtelExporter({
163
+ provider: {
164
+ newrelic: {
165
+ apiKey: 'your-license-key',
166
+ endpoint: 'https://otlp.eu01.nr-data.net', // Optional: for EU region
167
+ },
168
+ },
169
+ });
170
+ ```
171
+
122
172
  ### Traceloop
123
173
 
124
174
  #### Installation
@@ -128,7 +178,16 @@ const mastra = new Mastra({
128
178
  npm install @mastra/otel-exporter @opentelemetry/exporter-trace-otlp-http
129
179
  ```
130
180
 
131
- #### Configuration
181
+ #### Zero-Config Setup
182
+
183
+ ```bash
184
+ # Required
185
+ TRACELOOP_API_KEY=your-api-key
186
+
187
+ # Optional
188
+ TRACELOOP_DESTINATION_ID=my-destination
189
+ TRACELOOP_ENDPOINT=https://custom.traceloop.com
190
+ ```
132
191
 
133
192
  ```typescript
134
193
  import { OtelExporter } from '@mastra/otel-exporter';
@@ -139,24 +198,28 @@ const mastra = new Mastra({
139
198
  observability: {
140
199
  configs: {
141
200
  otel: {
142
- serviceName: 'mastra-service',
143
- exporters: [
144
- new OtelExporter({
145
- provider: {
146
- traceloop: {
147
- apiKey: process.env.TRACELOOP_API_KEY, // Required at runtime
148
- destinationId: 'my-destination', // Optional
149
- // endpoint: 'https://custom.traceloop.com', // Optional
150
- }
151
- },
152
- })
153
- ],
201
+ serviceName: 'my-service',
202
+ exporters: [new OtelExporter({ provider: { traceloop: {} } })],
154
203
  },
155
204
  },
156
205
  },
157
206
  });
158
207
  ```
159
208
 
209
+ #### Explicit Configuration
210
+
211
+ ```typescript
212
+ new OtelExporter({
213
+ provider: {
214
+ traceloop: {
215
+ apiKey: 'your-api-key',
216
+ destinationId: 'my-destination', // Optional
217
+ endpoint: 'https://custom.traceloop.com', // Optional
218
+ },
219
+ },
220
+ });
221
+ ```
222
+
160
223
  ### Laminar
161
224
 
162
225
  #### Installation
@@ -165,7 +228,15 @@ const mastra = new Mastra({
165
228
  npm install @mastra/otel-exporter @opentelemetry/exporter-trace-otlp-proto
166
229
  ```
167
230
 
168
- #### Configuration
231
+ #### Zero-Config Setup
232
+
233
+ ```bash
234
+ # Required
235
+ LMNR_PROJECT_API_KEY=your-api-key
236
+
237
+ # Optional
238
+ LAMINAR_ENDPOINT=https://api.lmnr.ai/v1/traces
239
+ ```
169
240
 
170
241
  ```typescript
171
242
  import { OtelExporter } from '@mastra/otel-exporter';
@@ -176,25 +247,26 @@ const mastra = new Mastra({
176
247
  observability: {
177
248
  configs: {
178
249
  otel: {
179
- serviceName: 'mastra-service',
180
- exporters: [
181
- new OtelExporter({
182
- provider: {
183
- laminar: {
184
- apiKey: process.env.LMNR_PROJECT_API_KEY, // Required at runtime
185
- // teamId: process.env.LAMINAR_TEAM_ID, // Optional, for backwards compatibility
186
- // endpoint: 'https://api.lmnr.ai/v1/traces', // Optional
187
- }
188
- },
189
- })
190
- ],
250
+ serviceName: 'my-service',
251
+ exporters: [new OtelExporter({ provider: { laminar: {} } })],
191
252
  },
192
253
  },
193
254
  },
194
255
  });
195
256
  ```
196
257
 
197
- **Note:** Laminar now only requires the `LMNR_PROJECT_API_KEY`. The `teamId` is optional.
258
+ #### Explicit Configuration
259
+
260
+ ```typescript
261
+ new OtelExporter({
262
+ provider: {
263
+ laminar: {
264
+ apiKey: 'your-api-key',
265
+ endpoint: 'https://api.lmnr.ai/v1/traces', // Optional
266
+ },
267
+ },
268
+ });
269
+ ```
198
270
 
199
271
  ### Zipkin
200
272
 
@@ -340,7 +412,7 @@ The OtelExporter uses OpenTelemetry's `BatchSpanProcessor` for efficient span ex
340
412
  - **Default batch size**: 512 spans (configurable via `batchSize`)
341
413
  - **Export interval**: Every 5 seconds or when batch is full
342
414
  - **Queue size**: Up to 2048 spans queued in memory
343
- - **Production-ready**: Optimized for high-throughput applications
415
+ - **High-throughput support**: Handles large volumes of spans efficiently
344
416
 
345
417
  This approach ensures:
346
418
 
package/dist/index.cjs CHANGED
@@ -106,24 +106,31 @@ function resolveProviderConfig(config) {
106
106
  }
107
107
  }
108
108
  function resolveDash0Config(config) {
109
- if (!config.apiKey) {
110
- console.error("[OtelExporter] Dash0 configuration requires apiKey. Tracing will be disabled.");
109
+ const apiKey = config.apiKey ?? process.env.DASH0_API_KEY;
110
+ const configEndpoint = config.endpoint ?? process.env.DASH0_ENDPOINT;
111
+ const dataset = config.dataset ?? process.env.DASH0_DATASET;
112
+ if (!apiKey) {
113
+ console.error(
114
+ "[OtelExporter] Dash0 configuration requires apiKey. Set DASH0_API_KEY environment variable or pass it in config. Tracing will be disabled."
115
+ );
111
116
  return null;
112
117
  }
113
- if (!config.endpoint) {
114
- console.error("[OtelExporter] Dash0 configuration requires endpoint. Tracing will be disabled.");
118
+ if (!configEndpoint) {
119
+ console.error(
120
+ "[OtelExporter] Dash0 configuration requires endpoint. Set DASH0_ENDPOINT environment variable or pass it in config. Tracing will be disabled."
121
+ );
115
122
  return null;
116
123
  }
117
- let endpoint = config.endpoint;
124
+ let endpoint = configEndpoint;
118
125
  if (!endpoint.includes("/v1/traces")) {
119
126
  endpoint = `${endpoint}/v1/traces`;
120
127
  }
121
128
  const headers = {
122
- authorization: `Bearer ${config.apiKey}`
129
+ authorization: `Bearer ${apiKey}`
123
130
  // lowercase for gRPC metadata
124
131
  };
125
- if (config.dataset) {
126
- headers["dash0-dataset"] = config.dataset;
132
+ if (dataset) {
133
+ headers["dash0-dataset"] = dataset;
127
134
  }
128
135
  return {
129
136
  endpoint,
@@ -133,44 +140,58 @@ function resolveDash0Config(config) {
133
140
  };
134
141
  }
135
142
  function resolveSignozConfig(config) {
136
- if (!config.apiKey) {
137
- console.error("[OtelExporter] SigNoz configuration requires apiKey. Tracing will be disabled.");
143
+ const apiKey = config.apiKey ?? process.env.SIGNOZ_API_KEY;
144
+ const region = config.region ?? process.env.SIGNOZ_REGION;
145
+ const configEndpoint = config.endpoint ?? process.env.SIGNOZ_ENDPOINT;
146
+ if (!apiKey) {
147
+ console.error(
148
+ "[OtelExporter] SigNoz configuration requires apiKey. Set SIGNOZ_API_KEY environment variable or pass it in config. Tracing will be disabled."
149
+ );
138
150
  return null;
139
151
  }
140
- const endpoint = config.endpoint || `https://ingest.${config.region || "us"}.signoz.cloud:443/v1/traces`;
152
+ const endpoint = configEndpoint || `https://ingest.${region || "us"}.signoz.cloud:443/v1/traces`;
141
153
  return {
142
154
  endpoint,
143
155
  headers: {
144
- "signoz-ingestion-key": config.apiKey
156
+ "signoz-ingestion-key": apiKey
145
157
  },
146
158
  protocol: "http/protobuf"
147
159
  };
148
160
  }
149
161
  function resolveNewRelicConfig(config) {
150
- if (!config.apiKey) {
151
- console.error("[OtelExporter] New Relic configuration requires apiKey (license key). Tracing will be disabled.");
162
+ const apiKey = config.apiKey ?? process.env.NEW_RELIC_LICENSE_KEY;
163
+ const configEndpoint = config.endpoint ?? process.env.NEW_RELIC_ENDPOINT;
164
+ if (!apiKey) {
165
+ console.error(
166
+ "[OtelExporter] New Relic configuration requires apiKey (license key). Set NEW_RELIC_LICENSE_KEY environment variable or pass it in config. Tracing will be disabled."
167
+ );
152
168
  return null;
153
169
  }
154
- const endpoint = config.endpoint || "https://otlp.nr-data.net:443/v1/traces";
170
+ const endpoint = configEndpoint || "https://otlp.nr-data.net:443/v1/traces";
155
171
  return {
156
172
  endpoint,
157
173
  headers: {
158
- "api-key": config.apiKey
174
+ "api-key": apiKey
159
175
  },
160
176
  protocol: "http/protobuf"
161
177
  };
162
178
  }
163
179
  function resolveTraceloopConfig(config) {
164
- if (!config.apiKey) {
165
- console.error("[OtelExporter] Traceloop configuration requires apiKey. Tracing will be disabled.");
180
+ const apiKey = config.apiKey ?? process.env.TRACELOOP_API_KEY;
181
+ const destinationId = config.destinationId ?? process.env.TRACELOOP_DESTINATION_ID;
182
+ const configEndpoint = config.endpoint ?? process.env.TRACELOOP_ENDPOINT;
183
+ if (!apiKey) {
184
+ console.error(
185
+ "[OtelExporter] Traceloop configuration requires apiKey. Set TRACELOOP_API_KEY environment variable or pass it in config. Tracing will be disabled."
186
+ );
166
187
  return null;
167
188
  }
168
- const endpoint = config.endpoint || "https://api.traceloop.com/v1/traces";
189
+ const endpoint = configEndpoint || "https://api.traceloop.com/v1/traces";
169
190
  const headers = {
170
- Authorization: `Bearer ${config.apiKey}`
191
+ Authorization: `Bearer ${apiKey}`
171
192
  };
172
- if (config.destinationId) {
173
- headers["x-traceloop-destination-id"] = config.destinationId;
193
+ if (destinationId) {
194
+ headers["x-traceloop-destination-id"] = destinationId;
174
195
  }
175
196
  return {
176
197
  endpoint,
@@ -179,17 +200,18 @@ function resolveTraceloopConfig(config) {
179
200
  };
180
201
  }
181
202
  function resolveLaminarConfig(config) {
182
- if (!config.apiKey) {
183
- console.error("[OtelExporter] Laminar configuration requires apiKey. Tracing will be disabled.");
203
+ const apiKey = config.apiKey ?? process.env.LMNR_PROJECT_API_KEY;
204
+ const configEndpoint = config.endpoint ?? process.env.LAMINAR_ENDPOINT;
205
+ if (!apiKey) {
206
+ console.error(
207
+ "[OtelExporter] Laminar configuration requires apiKey. Set LMNR_PROJECT_API_KEY environment variable or pass it in config. Tracing will be disabled."
208
+ );
184
209
  return null;
185
210
  }
186
- const endpoint = config.endpoint || "https://api.lmnr.ai/v1/traces";
211
+ const endpoint = configEndpoint || "https://api.lmnr.ai/v1/traces";
187
212
  const headers = {
188
- Authorization: `Bearer ${config.apiKey}`
213
+ Authorization: `Bearer ${apiKey}`
189
214
  };
190
- if (config.teamId) {
191
- headers["x-laminar-team-id"] = config.teamId;
192
- }
193
215
  return {
194
216
  endpoint,
195
217
  headers,
@@ -334,10 +356,10 @@ function getSpanIdentifier(span) {
334
356
  switch (span.type) {
335
357
  case observability.SpanType.MODEL_GENERATION: {
336
358
  const attrs = span.attributes;
337
- return attrs?.model ?? "unknown";
359
+ return attrs?.model;
338
360
  }
339
361
  default:
340
- return span.entityName ?? span.entityId ?? "unknown";
362
+ return span.entityName ?? span.entityId;
341
363
  }
342
364
  }
343
365
  function getSpanName(span) {
@@ -701,16 +723,15 @@ var OtelExporter = class extends observability$1.BaseExporter {
701
723
  async setupExporter() {
702
724
  if (this.isSetup || this.exporter) return;
703
725
  if (!this.config.provider) {
704
- this.logger.error(
726
+ this.setDisabled(
705
727
  '[OtelExporter] Provider configuration is required. Use the "custom" provider for generic endpoints.'
706
728
  );
707
- this.isDisabled = true;
708
729
  this.isSetup = true;
709
730
  return;
710
731
  }
711
732
  const resolved = resolveProviderConfig(this.config.provider);
712
733
  if (!resolved) {
713
- this.isDisabled = true;
734
+ this.setDisabled("[OtelExporter] Provider configuration validation failed.");
714
735
  this.isSetup = true;
715
736
  return;
716
737
  }
@@ -724,7 +745,7 @@ var OtelExporter = class extends observability$1.BaseExporter {
724
745
  const providerName = Object.keys(this.config.provider)[0];
725
746
  const ExporterClass = await loadExporter(protocol, providerName);
726
747
  if (!ExporterClass) {
727
- this.isDisabled = true;
748
+ this.setDisabled(`[OtelExporter] Exporter not available for protocol: ${protocol}`);
728
749
  this.isSetup = true;
729
750
  return;
730
751
  }
@@ -743,13 +764,11 @@ var OtelExporter = class extends observability$1.BaseExporter {
743
764
  metadata.set(key, value);
744
765
  });
745
766
  } catch (grpcError) {
746
- this.logger.error(
767
+ this.setDisabled(
747
768
  `[OtelExporter] Failed to load gRPC metadata. Install required packages:
748
- npm install @opentelemetry/exporter-trace-otlp-grpc @grpc/grpc-js
749
- `,
750
- grpcError
769
+ npm install @opentelemetry/exporter-trace-otlp-grpc @grpc/grpc-js`
751
770
  );
752
- this.isDisabled = true;
771
+ this.logger.error("[OtelExporter] gRPC error details:", grpcError);
753
772
  this.isSetup = true;
754
773
  return;
755
774
  }
@@ -766,8 +785,8 @@ var OtelExporter = class extends observability$1.BaseExporter {
766
785
  });
767
786
  }
768
787
  } catch (error) {
769
- this.logger.error(`[OtelExporter] Failed to create exporter:`, error);
770
- this.isDisabled = true;
788
+ this.setDisabled("[OtelExporter] Failed to create exporter.");
789
+ this.logger.error("[OtelExporter] Exporter creation error details:", error);
771
790
  this.isSetup = true;
772
791
  return;
773
792
  }
@@ -836,6 +855,8 @@ var OtelExporter = class extends observability$1.BaseExporter {
836
855
 
837
856
  exports.OtelExporter = OtelExporter;
838
857
  exports.SpanConverter = SpanConverter;
858
+ exports.getAttributes = getAttributes;
839
859
  exports.getSpanKind = getSpanKind;
860
+ exports.getSpanName = getSpanName;
840
861
  //# sourceMappingURL=index.cjs.map
841
862
  //# sourceMappingURL=index.cjs.map