@arizeai/phoenix-otel 0.3.0 → 0.3.1

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.
@@ -1,85 +1,329 @@
1
1
  import { DiagLogLevel } from "@opentelemetry/api";
2
2
  import { Instrumentation } from "@opentelemetry/instrumentation";
3
- import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
3
+ import { NodeTracerProvider, SpanProcessor } from "@opentelemetry/sdk-trace-node";
4
+ /**
5
+ * Type definition for HTTP headers used in OTLP communication
6
+ * @example { "custom-header": "value", "x-api-version": "1.0" }
7
+ */
4
8
  export type Headers = Record<string, string>;
5
9
  /**
6
- * Configuration parameters for registering Phoenix OpenTelemetry tracing
10
+ * Configuration parameters for registering Phoenix OpenTelemetry tracing.
11
+ *
12
+ * This interface defines all the available options for configuring the Phoenix
13
+ * OpenTelemetry integration, including connection details, processing options,
14
+ * and instrumentation settings.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const config: RegisterParams = {
19
+ * projectName: "my-application",
20
+ * url: "https://app.phoenix.arize.com",
21
+ * apiKey: "your-api-key",
22
+ * batch: true,
23
+ * global: true
24
+ * };
25
+ * ```
7
26
  */
8
27
  export type RegisterParams = {
9
28
  /**
10
- * The project the spans should be associated to
29
+ * The project name that spans will be associated with in Phoenix.
30
+ * This helps organize and filter traces in the Phoenix UI.
31
+ *
11
32
  * @default "default"
33
+ * @example "my-web-app"
34
+ * @example "api-service"
12
35
  */
13
36
  projectName?: string;
14
37
  /**
15
- * The URL to the phoenix server. Can be postfixed with tracing path.
16
- * If not provided, environment variables are checked.
38
+ * The URL to the Phoenix server. Can be postfixed with the tracing path.
39
+ * If not provided, the system will check the PHOENIX_COLLECTOR_URL environment variable.
40
+ *
41
+ * The URL will be automatically normalized to include the `/v1/traces` endpoint if not present.
42
+ *
17
43
  * @example "https://app.phoenix.arize.com"
44
+ * @example "https://app.phoenix.arize.com/v1/traces"
45
+ * @example "http://localhost:6006"
18
46
  */
19
47
  url?: string;
20
48
  /**
21
- * The API key for the phoenix instance.
22
- * If not provided, environment variables are checked.
49
+ * The API key for authenticating with the Phoenix instance.
50
+ * If not provided, the system will check the PHOENIX_API_KEY environment variable.
51
+ *
52
+ * The API key will be automatically added to the Authorization header as a Bearer token.
53
+ *
54
+ * @example "phx_1234567890abcdef"
23
55
  */
24
56
  apiKey?: string;
25
57
  /**
26
- * Headers to be used when communicating with the OTLP collector
58
+ * Additional headers to be included when communicating with the OTLP collector.
59
+ * These headers will be merged with any automatically generated headers (like Authorization).
60
+ *
61
+ * @example { "x-custom-header": "value", "x-api-version": "1.0" }
27
62
  */
28
63
  headers?: Headers;
29
64
  /**
30
65
  * Whether to use batching for span processing.
31
- * It is recommended to use batching in production environments
66
+ *
67
+ * - `true` (default): Uses OpenInferenceBatchSpanProcessor for better performance in production
68
+ * - `false`: Uses OpenInferenceSimpleSpanProcessor for immediate span export (useful for debugging)
69
+ *
70
+ * Batching is recommended for production environments as it reduces network overhead
71
+ * and improves performance by sending multiple spans in a single request.
72
+ *
32
73
  * @default true
33
74
  */
34
75
  batch?: boolean;
35
76
  /**
36
- * A list of instrumentation to register.
37
- * Note: this may only work with commonjs projects. ESM projects will require manually applying instrumentation.
77
+ * A list of OpenTelemetry instrumentations to automatically register.
78
+ *
79
+ * **Note**: This feature may only work with CommonJS projects. ESM projects
80
+ * may require manual instrumentation registration.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
85
+ * import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
86
+ *
87
+ * const instrumentations = [
88
+ * new HttpInstrumentation(),
89
+ * new ExpressInstrumentation()
90
+ * ];
91
+ * ```
38
92
  */
39
93
  instrumentations?: Instrumentation[];
40
94
  /**
41
- * Whether to set the tracer as a global provider.
95
+ * Custom span processors to add to the tracer provider.
96
+ *
97
+ * **Important**: When provided, this will override the default span processor
98
+ * created from the `url`, `apiKey`, `headers`, and `batch` parameters.
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
103
+ *
104
+ * const customProcessors = [
105
+ * new BatchSpanProcessor(exporter),
106
+ * new MyCustomSpanProcessor()
107
+ * ];
108
+ * ```
109
+ */
110
+ spanProcessors?: SpanProcessor[];
111
+ /**
112
+ * Whether to register the tracer provider as the global provider.
113
+ *
114
+ * When `true` (default), the provider will be registered globally and can be
115
+ * accessed throughout the application. Set to `false` if you want to manage
116
+ * the provider lifecycle manually or use multiple providers.
117
+ *
42
118
  * @default true
43
119
  */
44
120
  global?: boolean;
45
121
  /**
46
- * The diag log level to set for the built in DiagConsoleLogger instance.
47
- * Omit to disable built in logging.
122
+ * The diagnostic log level for the built-in DiagConsoleLogger.
123
+ *
124
+ * This controls the verbosity of OpenTelemetry's internal logging.
125
+ * Omit this parameter to disable built-in logging entirely.
126
+ *
127
+ * @example DiagLogLevel.INFO
128
+ * @example DiagLogLevel.DEBUG
129
+ * @example DiagLogLevel.ERROR
48
130
  */
49
131
  diagLogLevel?: DiagLogLevel;
50
132
  };
51
133
  /**
52
- * Registers Phoenix OpenTelemetry tracing with the specified configuration
134
+ * Registers Phoenix OpenTelemetry tracing with the specified configuration.
135
+ *
136
+ * This function sets up a complete OpenTelemetry tracing pipeline configured
137
+ * to send traces to a Phoenix instance. It creates a NodeTracerProvider with
138
+ * appropriate span processors, resource attributes, and optional instrumentations.
139
+ *
140
+ * The function handles:
141
+ * - Creating and configuring a NodeTracerProvider
142
+ * - Setting up OTLP trace export to Phoenix
143
+ * - Configuring span processors (batch or simple)
144
+ * - Registering instrumentations (if provided)
145
+ * - Setting up resource attributes for project identification
146
+ * - Optional global provider registration
53
147
  *
54
148
  * @param params - Configuration parameters for Phoenix tracing
55
- * @param params.url - The URL to the phoenix server. Can be postfixed with tracing path
56
- * @param params.apiKey - The API key for the phoenix instance
57
- * @param params.projectName - The project the spans should be associated to
58
- * @param params.instrumentations - A list of instrumentation to register
59
- * @param params.batch - Whether to use batching for span processing
60
- * @param params.global - Whether to set the tracer as a global provider
61
- * @param params.diagLogLevel - the diagnostics log level
62
- * @returns {NodeTracerProvider} The configured NodeTracerProvider instance
149
+ * @returns The configured NodeTracerProvider instance that can be used to create traces
63
150
  *
64
151
  * @example
152
+ * Basic usage with minimal configuration:
65
153
  * ```typescript
66
154
  * import { register } from '@arizeai/phoenix-otel';
67
155
  *
156
+ * // Uses environment variables for URL and API key
157
+ * const provider = register({
158
+ * projectName: 'my-application'
159
+ * });
160
+ * ```
161
+ *
162
+ * @example
163
+ * Full configuration with custom settings:
164
+ * ```typescript
165
+ * import { register } from '@arizeai/phoenix-otel';
166
+ * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
167
+ * import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
168
+ *
169
+ * const provider = register({
170
+ * projectName: 'my-web-app',
171
+ * url: 'https://app.phoenix.arize.com',
172
+ * apiKey: 'phx_1234567890abcdef',
173
+ * batch: true,
174
+ * global: true,
175
+ * instrumentations: [
176
+ * new HttpInstrumentation(),
177
+ * new ExpressInstrumentation()
178
+ * ],
179
+ * diagLogLevel: DiagLogLevel.INFO
180
+ * });
181
+ * ```
182
+ *
183
+ * @example
184
+ * Custom span processors:
185
+ * ```typescript
186
+ * import { register } from '@arizeai/phoenix-otel';
187
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
188
+ * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
189
+ *
190
+ * const exporter = new OTLPTraceExporter({
191
+ * url: 'https://app.phoenix.arize.com/v1/traces',
192
+ * headers: { 'Authorization': 'Bearer your-api-key' }
193
+ * });
194
+ *
68
195
  * const provider = register({
69
196
  * projectName: 'my-app',
197
+ * spanProcessors: [new BatchSpanProcessor(exporter)],
198
+ * global: false // Manual provider management
199
+ * });
200
+ * ```
201
+ *
202
+ * @example
203
+ * Debugging configuration:
204
+ * ```typescript
205
+ * const provider = register({
206
+ * projectName: 'debug-app',
207
+ * url: 'http://localhost:6006',
208
+ * batch: false, // Immediate span export for debugging
209
+ * diagLogLevel: DiagLogLevel.DEBUG
210
+ * });
211
+ * ```
212
+ */
213
+ export declare function register(params: RegisterParams): NodeTracerProvider;
214
+ /**
215
+ * Creates a default span processor configured for Phoenix OpenTelemetry tracing.
216
+ *
217
+ * This function creates an appropriate span processor (batch or simple) based on
218
+ * the provided configuration parameters. It handles URL normalization, header
219
+ * configuration, and API key authentication automatically.
220
+ *
221
+ * The function will:
222
+ * - Normalize the collector URL to include the `/v1/traces` endpoint if needed
223
+ * - Configure authentication headers using the provided API key
224
+ * - Merge any additional custom headers
225
+ * - Create either a batch or simple span processor based on the `batch` parameter
226
+ *
227
+ * @param params - Configuration parameters for the span processor
228
+ * @param params.url - The URL to the Phoenix server (will be normalized to include `/v1/traces`)
229
+ * @param params.apiKey - The API key for authenticating with the Phoenix instance
230
+ * @param params.headers - Additional headers to include in OTLP requests
231
+ * @param params.batch - Whether to use batching for span processing (recommended for production)
232
+ * @returns A configured SpanProcessor instance ready for use with a NodeTracerProvider
233
+ *
234
+ * @example
235
+ * Basic usage with environment variables:
236
+ * ```typescript
237
+ * const processor = getDefaultSpanProcessor({
238
+ * batch: true
239
+ * });
240
+ * ```
241
+ *
242
+ * @example
243
+ * Full configuration with custom settings:
244
+ * ```typescript
245
+ * const processor = getDefaultSpanProcessor({
246
+ * url: 'https://app.phoenix.arize.com',
247
+ * apiKey: 'phx_1234567890abcdef',
248
+ * headers: { 'x-custom-header': 'value' },
249
+ * batch: true
250
+ * });
251
+ * ```
252
+ *
253
+ * @example
254
+ * Debugging configuration with immediate export:
255
+ * ```typescript
256
+ * const processor = getDefaultSpanProcessor({
257
+ * url: 'http://localhost:6006',
258
+ * batch: false // Immediate span export for debugging
259
+ * });
260
+ * ```
261
+ *
262
+ * @example
263
+ * Using with custom headers:
264
+ * ```typescript
265
+ * const processor = getDefaultSpanProcessor({
70
266
  * url: 'https://app.phoenix.arize.com',
71
267
  * apiKey: 'your-api-key',
268
+ * headers: {
269
+ * 'x-api-version': '1.0',
270
+ * 'x-client-name': 'my-app'
271
+ * },
72
272
  * batch: true
73
273
  * });
74
274
  * ```
75
275
  */
76
- export declare function register({ url: paramsUrl, apiKey: paramsApiKey, headers: paramsHeaders, projectName, instrumentations, batch, global, diagLogLevel, }: RegisterParams): NodeTracerProvider;
276
+ export declare function getDefaultSpanProcessor({ url: paramsUrl, apiKey: paramsApiKey, headers: paramsHeaders, batch, }: Pick<RegisterParams, "url" | "apiKey" | "batch" | "headers">): SpanProcessor;
77
277
  /**
78
- * A utility method to normalize the URL to be HTTP compatible.
79
- * Assumes we are using HTTP over gRPC and ensures the URL ends with the correct traces endpoint.
278
+ * Normalizes a Phoenix server URL to ensure it includes the correct OTLP traces endpoint.
279
+ *
280
+ * This utility function ensures that any Phoenix server URL is properly formatted
281
+ * to include the `/v1/traces` endpoint required for OTLP trace export. It handles
282
+ * various URL formats and automatically appends the endpoint if missing.
80
283
  *
81
- * @param url - The URL to the phoenix server. May contain a slug
82
- * @returns {string} The normalized URL with the '/v1/traces' endpoint
284
+ * The function:
285
+ * - Checks if the URL already contains `/v1/traces`
286
+ * - If missing, appends `/v1/traces` to the base URL
287
+ * - Returns a properly formatted URL string
288
+ * - Assumes HTTP over gRPC protocol for OTLP communication
289
+ *
290
+ * @param url - The base URL to the Phoenix server (may or may not include the traces endpoint)
291
+ * @returns A normalized URL string that includes the `/v1/traces` endpoint
292
+ *
293
+ * @example
294
+ * URL without traces endpoint:
295
+ * ```typescript
296
+ * const normalized = ensureCollectorEndpoint('https://app.phoenix.arize.com');
297
+ * // Returns: 'https://app.phoenix.arize.com/v1/traces'
298
+ * ```
299
+ *
300
+ * @example
301
+ * URL that already includes traces endpoint:
302
+ * ```typescript
303
+ * const normalized = ensureCollectorEndpoint('https://app.phoenix.arize.com/v1/traces');
304
+ * // Returns: 'https://app.phoenix.arize.com/v1/traces'
305
+ * ```
306
+ *
307
+ * @example
308
+ * Local development URL:
309
+ * ```typescript
310
+ * const normalized = ensureCollectorEndpoint('http://localhost:6006');
311
+ * // Returns: 'http://localhost:6006/v1/traces'
312
+ * ```
313
+ *
314
+ * @example
315
+ * URL with custom port and path:
316
+ * ```typescript
317
+ * const normalized = ensureCollectorEndpoint('https://phoenix.example.com:8080');
318
+ * // Returns: 'https://phoenix.example.com:8080/v1/traces'
319
+ * ```
320
+ *
321
+ * @example
322
+ * URL with existing path (edge case):
323
+ * ```typescript
324
+ * const normalized = ensureCollectorEndpoint('https://app.phoenix.arize.com/api');
325
+ * // Returns: 'https://app.phoenix.arize.com/api/v1/traces'
326
+ * ```
83
327
  */
84
328
  export declare function ensureCollectorEndpoint(url: string): string;
85
329
  //# sourceMappingURL=register.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAQA,OAAO,EAA2B,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EACL,eAAe,EAEhB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,kBAAkB,EAEnB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,aAAkB,EAC3B,WAAuB,EACvB,gBAAgB,EAChB,KAAY,EACZ,MAAa,EACb,YAAY,GACb,EAAE,cAAc,GAAG,kBAAkB,CA0CrC;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK3D"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAQA,OAAO,EAA2B,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EACL,eAAe,EAEhB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACd,MAAM,+BAA+B,CAAC;AAEvC;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IAErC;;;;;;;;;;;;;;;OAeG;IACH,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IAEjC;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,kBAAkB,CA6BnE;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,aAAkB,EAC3B,KAAY,GACb,EAAE,IAAI,CACL,cAAc,EACd,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CACvC,GAAG,aAAa,CAuBhB;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAa3D"}
@@ -7,34 +7,170 @@ import { registerInstrumentations, } from "@opentelemetry/instrumentation";
7
7
  import { resourceFromAttributes } from "@opentelemetry/resources";
8
8
  import { NodeTracerProvider, } from "@opentelemetry/sdk-trace-node";
9
9
  /**
10
- * Registers Phoenix OpenTelemetry tracing with the specified configuration
10
+ * Registers Phoenix OpenTelemetry tracing with the specified configuration.
11
+ *
12
+ * This function sets up a complete OpenTelemetry tracing pipeline configured
13
+ * to send traces to a Phoenix instance. It creates a NodeTracerProvider with
14
+ * appropriate span processors, resource attributes, and optional instrumentations.
15
+ *
16
+ * The function handles:
17
+ * - Creating and configuring a NodeTracerProvider
18
+ * - Setting up OTLP trace export to Phoenix
19
+ * - Configuring span processors (batch or simple)
20
+ * - Registering instrumentations (if provided)
21
+ * - Setting up resource attributes for project identification
22
+ * - Optional global provider registration
11
23
  *
12
24
  * @param params - Configuration parameters for Phoenix tracing
13
- * @param params.url - The URL to the phoenix server. Can be postfixed with tracing path
14
- * @param params.apiKey - The API key for the phoenix instance
15
- * @param params.projectName - The project the spans should be associated to
16
- * @param params.instrumentations - A list of instrumentation to register
17
- * @param params.batch - Whether to use batching for span processing
18
- * @param params.global - Whether to set the tracer as a global provider
19
- * @param params.diagLogLevel - the diagnostics log level
20
- * @returns {NodeTracerProvider} The configured NodeTracerProvider instance
25
+ * @returns The configured NodeTracerProvider instance that can be used to create traces
21
26
  *
22
27
  * @example
28
+ * Basic usage with minimal configuration:
23
29
  * ```typescript
24
30
  * import { register } from '@arizeai/phoenix-otel';
25
31
  *
32
+ * // Uses environment variables for URL and API key
26
33
  * const provider = register({
27
- * projectName: 'my-app',
34
+ * projectName: 'my-application'
35
+ * });
36
+ * ```
37
+ *
38
+ * @example
39
+ * Full configuration with custom settings:
40
+ * ```typescript
41
+ * import { register } from '@arizeai/phoenix-otel';
42
+ * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
43
+ * import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
44
+ *
45
+ * const provider = register({
46
+ * projectName: 'my-web-app',
28
47
  * url: 'https://app.phoenix.arize.com',
29
- * apiKey: 'your-api-key',
30
- * batch: true
48
+ * apiKey: 'phx_1234567890abcdef',
49
+ * batch: true,
50
+ * global: true,
51
+ * instrumentations: [
52
+ * new HttpInstrumentation(),
53
+ * new ExpressInstrumentation()
54
+ * ],
55
+ * diagLogLevel: DiagLogLevel.INFO
56
+ * });
57
+ * ```
58
+ *
59
+ * @example
60
+ * Custom span processors:
61
+ * ```typescript
62
+ * import { register } from '@arizeai/phoenix-otel';
63
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
64
+ * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
65
+ *
66
+ * const exporter = new OTLPTraceExporter({
67
+ * url: 'https://app.phoenix.arize.com/v1/traces',
68
+ * headers: { 'Authorization': 'Bearer your-api-key' }
69
+ * });
70
+ *
71
+ * const provider = register({
72
+ * projectName: 'my-app',
73
+ * spanProcessors: [new BatchSpanProcessor(exporter)],
74
+ * global: false // Manual provider management
75
+ * });
76
+ * ```
77
+ *
78
+ * @example
79
+ * Debugging configuration:
80
+ * ```typescript
81
+ * const provider = register({
82
+ * projectName: 'debug-app',
83
+ * url: 'http://localhost:6006',
84
+ * batch: false, // Immediate span export for debugging
85
+ * diagLogLevel: DiagLogLevel.DEBUG
31
86
  * });
32
87
  * ```
33
88
  */
34
- export function register({ url: paramsUrl, apiKey: paramsApiKey, headers: paramsHeaders = {}, projectName = "default", instrumentations, batch = true, global = true, diagLogLevel, }) {
89
+ export function register(params) {
90
+ const { projectName = "default", instrumentations, global = true, diagLogLevel, spanProcessors, } = params;
35
91
  if (diagLogLevel) {
36
92
  diag.setLogger(new DiagConsoleLogger(), diagLogLevel);
37
93
  }
94
+ const provider = new NodeTracerProvider({
95
+ resource: resourceFromAttributes({
96
+ [SEMRESATTRS_PROJECT_NAME]: projectName,
97
+ }),
98
+ spanProcessors: spanProcessors || [getDefaultSpanProcessor(params)],
99
+ });
100
+ if (instrumentations) {
101
+ registerInstrumentations({
102
+ instrumentations,
103
+ tracerProvider: provider,
104
+ });
105
+ }
106
+ if (global) {
107
+ provider.register();
108
+ }
109
+ return provider;
110
+ }
111
+ /**
112
+ * Creates a default span processor configured for Phoenix OpenTelemetry tracing.
113
+ *
114
+ * This function creates an appropriate span processor (batch or simple) based on
115
+ * the provided configuration parameters. It handles URL normalization, header
116
+ * configuration, and API key authentication automatically.
117
+ *
118
+ * The function will:
119
+ * - Normalize the collector URL to include the `/v1/traces` endpoint if needed
120
+ * - Configure authentication headers using the provided API key
121
+ * - Merge any additional custom headers
122
+ * - Create either a batch or simple span processor based on the `batch` parameter
123
+ *
124
+ * @param params - Configuration parameters for the span processor
125
+ * @param params.url - The URL to the Phoenix server (will be normalized to include `/v1/traces`)
126
+ * @param params.apiKey - The API key for authenticating with the Phoenix instance
127
+ * @param params.headers - Additional headers to include in OTLP requests
128
+ * @param params.batch - Whether to use batching for span processing (recommended for production)
129
+ * @returns A configured SpanProcessor instance ready for use with a NodeTracerProvider
130
+ *
131
+ * @example
132
+ * Basic usage with environment variables:
133
+ * ```typescript
134
+ * const processor = getDefaultSpanProcessor({
135
+ * batch: true
136
+ * });
137
+ * ```
138
+ *
139
+ * @example
140
+ * Full configuration with custom settings:
141
+ * ```typescript
142
+ * const processor = getDefaultSpanProcessor({
143
+ * url: 'https://app.phoenix.arize.com',
144
+ * apiKey: 'phx_1234567890abcdef',
145
+ * headers: { 'x-custom-header': 'value' },
146
+ * batch: true
147
+ * });
148
+ * ```
149
+ *
150
+ * @example
151
+ * Debugging configuration with immediate export:
152
+ * ```typescript
153
+ * const processor = getDefaultSpanProcessor({
154
+ * url: 'http://localhost:6006',
155
+ * batch: false // Immediate span export for debugging
156
+ * });
157
+ * ```
158
+ *
159
+ * @example
160
+ * Using with custom headers:
161
+ * ```typescript
162
+ * const processor = getDefaultSpanProcessor({
163
+ * url: 'https://app.phoenix.arize.com',
164
+ * apiKey: 'your-api-key',
165
+ * headers: {
166
+ * 'x-api-version': '1.0',
167
+ * 'x-client-name': 'my-app'
168
+ * },
169
+ * batch: true
170
+ * });
171
+ * ```
172
+ */
173
+ export function getDefaultSpanProcessor({ url: paramsUrl, apiKey: paramsApiKey, headers: paramsHeaders = {}, batch = true, }) {
38
174
  const url = ensureCollectorEndpoint(paramsUrl || getEnvCollectorURL() || "http://localhost:6006");
39
175
  const apiKey = paramsApiKey || getEnvApiKey();
40
176
  const headers = Array.isArray(paramsHeaders)
@@ -55,33 +191,70 @@ export function register({ url: paramsUrl, apiKey: paramsApiKey, headers: params
55
191
  else {
56
192
  spanProcessor = new OpenInferenceSimpleSpanProcessor({ exporter });
57
193
  }
58
- const provider = new NodeTracerProvider({
59
- resource: resourceFromAttributes({
60
- [SEMRESATTRS_PROJECT_NAME]: projectName,
61
- }),
62
- spanProcessors: [spanProcessor],
63
- });
64
- if (instrumentations) {
65
- registerInstrumentations({
66
- instrumentations,
67
- tracerProvider: provider,
68
- });
69
- }
70
- if (global) {
71
- provider.register();
72
- }
73
- return provider;
194
+ return spanProcessor;
74
195
  }
75
196
  /**
76
- * A utility method to normalize the URL to be HTTP compatible.
77
- * Assumes we are using HTTP over gRPC and ensures the URL ends with the correct traces endpoint.
197
+ * Normalizes a Phoenix server URL to ensure it includes the correct OTLP traces endpoint.
198
+ *
199
+ * This utility function ensures that any Phoenix server URL is properly formatted
200
+ * to include the `/v1/traces` endpoint required for OTLP trace export. It handles
201
+ * various URL formats and automatically appends the endpoint if missing.
202
+ *
203
+ * The function:
204
+ * - Checks if the URL already contains `/v1/traces`
205
+ * - If missing, appends `/v1/traces` to the base URL
206
+ * - Returns a properly formatted URL string
207
+ * - Assumes HTTP over gRPC protocol for OTLP communication
208
+ *
209
+ * @param url - The base URL to the Phoenix server (may or may not include the traces endpoint)
210
+ * @returns A normalized URL string that includes the `/v1/traces` endpoint
211
+ *
212
+ * @example
213
+ * URL without traces endpoint:
214
+ * ```typescript
215
+ * const normalized = ensureCollectorEndpoint('https://app.phoenix.arize.com');
216
+ * // Returns: 'https://app.phoenix.arize.com/v1/traces'
217
+ * ```
218
+ *
219
+ * @example
220
+ * URL that already includes traces endpoint:
221
+ * ```typescript
222
+ * const normalized = ensureCollectorEndpoint('https://app.phoenix.arize.com/v1/traces');
223
+ * // Returns: 'https://app.phoenix.arize.com/v1/traces'
224
+ * ```
225
+ *
226
+ * @example
227
+ * Local development URL:
228
+ * ```typescript
229
+ * const normalized = ensureCollectorEndpoint('http://localhost:6006');
230
+ * // Returns: 'http://localhost:6006/v1/traces'
231
+ * ```
78
232
  *
79
- * @param url - The URL to the phoenix server. May contain a slug
80
- * @returns {string} The normalized URL with the '/v1/traces' endpoint
233
+ * @example
234
+ * URL with custom port and path:
235
+ * ```typescript
236
+ * const normalized = ensureCollectorEndpoint('https://phoenix.example.com:8080');
237
+ * // Returns: 'https://phoenix.example.com:8080/v1/traces'
238
+ * ```
239
+ *
240
+ * @example
241
+ * URL with existing path (edge case):
242
+ * ```typescript
243
+ * const normalized = ensureCollectorEndpoint('https://app.phoenix.arize.com/api');
244
+ * // Returns: 'https://app.phoenix.arize.com/api/v1/traces'
245
+ * ```
81
246
  */
82
247
  export function ensureCollectorEndpoint(url) {
83
248
  if (!url.includes("/v1/traces")) {
84
- return new URL("/v1/traces", url).toString();
249
+ // Ensure the base URL has a trailing slash for proper path concatenation
250
+ // Without this, the URL constructor treats the last segment as a file and replaces it
251
+ const baseUrl = new URL(url);
252
+ if (!baseUrl.pathname.endsWith("/")) {
253
+ baseUrl.pathname += "/";
254
+ }
255
+ // Append v1/traces to the pathname (without leading slash to append, not replace)
256
+ baseUrl.pathname += "v1/traces";
257
+ return baseUrl.toString();
85
258
  }
86
259
  return new URL(url).toString();
87
260
  }
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAgB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAEL,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EACL,kBAAkB,GAEnB,MAAM,+BAA+B,CAAC;AAmDvC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,aAAa,GAAG,EAAE,EAC3B,WAAW,GAAG,SAAS,EACvB,gBAAgB,EAChB,KAAK,GAAG,IAAI,EACZ,MAAM,GAAG,IAAI,EACb,YAAY,GACG;IACf,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC,SAAS,CAAC,IAAI,iBAAiB,EAAE,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,GAAG,GAAG,uBAAuB,CACjC,SAAS,IAAI,kBAAkB,EAAE,IAAI,uBAAuB,CAC7D,CAAC;IACF,MAAM,MAAM,GAAG,YAAY,IAAI,YAAY,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAY,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QACnD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC;QACnC,CAAC,CAAC,aAAa,CAAC;IAClB,MAAM,gBAAgB,GAAG,OAAO,MAAM,IAAI,QAAQ,CAAC;IACnD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;QACrC,GAAG;QACH,OAAO;KACR,CAAC,CAAC;IACH,IAAI,aAA4B,CAAC;IACjC,IAAI,KAAK,EAAE,CAAC;QACV,aAAa,GAAG,IAAI,+BAA+B,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,aAAa,GAAG,IAAI,gCAAgC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC;QACtC,QAAQ,EAAE,sBAAsB,CAAC;YAC/B,CAAC,wBAAwB,CAAC,EAAE,WAAW;SACxC,CAAC;QACF,cAAc,EAAE,CAAC,aAAa,CAAC;KAChC,CAAC,CAAC;IAEH,IAAI,gBAAgB,EAAE,CAAC;QACrB,wBAAwB,CAAC;YACvB,gBAAgB;YAChB,cAAc,EAAE,QAAQ;SACzB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAW;IACjD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAgB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAEL,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EACL,kBAAkB,GAEnB,MAAM,+BAA+B,CAAC;AA6IvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAsB;IAC7C,MAAM,EACJ,WAAW,GAAG,SAAS,EACvB,gBAAgB,EAChB,MAAM,GAAG,IAAI,EACb,YAAY,EACZ,cAAc,GACf,GAAG,MAAM,CAAC;IAEX,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC,SAAS,CAAC,IAAI,iBAAiB,EAAE,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC;QACtC,QAAQ,EAAE,sBAAsB,CAAC;YAC/B,CAAC,wBAAwB,CAAC,EAAE,WAAW;SACxC,CAAC;QACF,cAAc,EAAE,cAAc,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;KACpE,CAAC,CAAC;IAEH,IAAI,gBAAgB,EAAE,CAAC;QACrB,wBAAwB,CAAC;YACvB,gBAAgB;YAChB,cAAc,EAAE,QAAQ;SACzB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,aAAa,GAAG,EAAE,EAC3B,KAAK,GAAG,IAAI,GAIb;IACC,MAAM,GAAG,GAAG,uBAAuB,CACjC,SAAS,IAAI,kBAAkB,EAAE,IAAI,uBAAuB,CAC7D,CAAC;IACF,MAAM,MAAM,GAAG,YAAY,IAAI,YAAY,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAY,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QACnD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC;QACnC,CAAC,CAAC,aAAa,CAAC;IAClB,MAAM,gBAAgB,GAAG,OAAO,MAAM,IAAI,QAAQ,CAAC;IACnD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;QACrC,GAAG;QACH,OAAO;KACR,CAAC,CAAC;IACH,IAAI,aAA4B,CAAC;IACjC,IAAI,KAAK,EAAE,CAAC;QACV,aAAa,GAAG,IAAI,+BAA+B,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;SAAM,CAAC;QACN,aAAa,GAAG,IAAI,gCAAgC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAW;IACjD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,yEAAyE;QACzE,sFAAsF;QACtF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC;QAC1B,CAAC;QACD,kFAAkF;QAClF,OAAO,CAAC,QAAQ,IAAI,WAAW,CAAC;QAChC,OAAO,OAAO,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;AACjC,CAAC"}