@atrim/instrument-web 0.1.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.
@@ -0,0 +1,413 @@
1
+ import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
2
+ import { InstrumentationConfig, ConfigLoader } from '@atrim/instrument-core';
3
+ export { ConfigError, ConfigFileError, ConfigUrlError, ConfigValidationError, ExportError, InitializationError, InstrumentationConfig, PatternConfig, PatternMatcher, ShutdownError, clearPatternMatcher, getPatternMatcher, initializePatternMatcher, shouldInstrumentSpan } from '@atrim/instrument-core';
4
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
5
+ import { Layer } from 'effect';
6
+ import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
7
+ import { Context, Span } from '@opentelemetry/api';
8
+
9
+ /**
10
+ * SDK Initializer for Browser
11
+ *
12
+ * Initializes the OpenTelemetry WebTracerProvider with:
13
+ * - Auto-instrumentation (fetch, XHR, document load, user interactions)
14
+ * - Pattern-based span filtering
15
+ * - OTLP HTTP export
16
+ */
17
+
18
+ interface SdkInitializationOptions {
19
+ /**
20
+ * Service name (required for browser - no auto-detection)
21
+ * @example 'my-app-frontend'
22
+ */
23
+ serviceName: string;
24
+ /**
25
+ * Service version (optional)
26
+ * @example '1.0.0'
27
+ */
28
+ serviceVersion?: string;
29
+ /**
30
+ * Path to instrumentation.yaml file
31
+ * Note: Only works if file is publicly accessible
32
+ */
33
+ configPath?: string;
34
+ /**
35
+ * URL to remote instrumentation.yaml
36
+ * @example 'https://config.company.com/instrumentation.yaml'
37
+ */
38
+ configUrl?: string;
39
+ /**
40
+ * Inline configuration object (takes precedence over file/URL)
41
+ */
42
+ config?: InstrumentationConfig;
43
+ /**
44
+ * OTLP endpoint URL
45
+ * @default 'http://localhost:4318/v1/traces'
46
+ */
47
+ otlpEndpoint?: string;
48
+ /**
49
+ * OTLP HTTP headers
50
+ * @example { 'Authorization': 'Bearer token' }
51
+ */
52
+ otlpHeaders?: Record<string, string>;
53
+ /**
54
+ * Enable document load instrumentation
55
+ * @default true
56
+ */
57
+ enableDocumentLoad?: boolean;
58
+ /**
59
+ * Enable user interaction instrumentation
60
+ * @default true
61
+ */
62
+ enableUserInteraction?: boolean;
63
+ /**
64
+ * Enable fetch API instrumentation
65
+ * @default true
66
+ */
67
+ enableFetch?: boolean;
68
+ /**
69
+ * Enable XMLHttpRequest instrumentation
70
+ * @default true
71
+ */
72
+ enableXhr?: boolean;
73
+ }
74
+ /**
75
+ * Get the current SDK instance
76
+ *
77
+ * @returns WebTracerProvider instance or null if not initialized
78
+ */
79
+ declare function getSdkInstance(): WebTracerProvider | null;
80
+ /**
81
+ * Shutdown the SDK gracefully
82
+ *
83
+ * Flushes pending spans and releases resources
84
+ */
85
+ declare function shutdownSdk(): Promise<void>;
86
+ /**
87
+ * Reset the SDK instance (for testing)
88
+ *
89
+ * Does not shutdown - just clears the singleton
90
+ */
91
+ declare function resetSdk(): void;
92
+
93
+ /**
94
+ * Public API for @atrim/instrument-web
95
+ *
96
+ * Main initialization functions for browser instrumentation
97
+ */
98
+
99
+ /**
100
+ * Initialize OpenTelemetry instrumentation for browser
101
+ *
102
+ * This is the main entry point for setting up tracing in browser applications.
103
+ * Call this function once at application startup, before any other code runs.
104
+ *
105
+ * @param options - Initialization options
106
+ * @returns WebTracerProvider instance
107
+ * @throws {Error} If initialization fails
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * import { initializeInstrumentation } from '@atrim/instrument-web'
112
+ *
113
+ * await initializeInstrumentation({
114
+ * serviceName: 'my-app',
115
+ * otlpEndpoint: 'http://localhost:4318/v1/traces'
116
+ * })
117
+ * ```
118
+ *
119
+ * @example With pattern-based filtering
120
+ * ```typescript
121
+ * await initializeInstrumentation({
122
+ * serviceName: 'my-app',
123
+ * configUrl: 'https://config.company.com/instrumentation.yaml'
124
+ * })
125
+ * ```
126
+ *
127
+ * @example Disable specific instrumentations
128
+ * ```typescript
129
+ * await initializeInstrumentation({
130
+ * serviceName: 'my-app',
131
+ * enableUserInteraction: false, // Disable click tracking
132
+ * enableXhr: false // Disable XMLHttpRequest tracking
133
+ * })
134
+ * ```
135
+ */
136
+ declare function initializeInstrumentation(options: SdkInitializationOptions): Promise<WebTracerProvider>;
137
+
138
+ /**
139
+ * OTLP Exporter Factory for Browser
140
+ *
141
+ * Creates OTLP HTTP exporters for sending traces from the browser.
142
+ * Browser only supports HTTP/JSON protocol (no gRPC).
143
+ */
144
+
145
+ interface OtlpExporterOptions {
146
+ /**
147
+ * OTLP endpoint URL
148
+ * Must end in /v1/traces for browser exporter
149
+ * @default 'http://localhost:4318/v1/traces'
150
+ */
151
+ endpoint?: string;
152
+ /**
153
+ * Custom HTTP headers (e.g., for authentication)
154
+ * @example { 'Authorization': 'Bearer token' }
155
+ */
156
+ headers?: Record<string, string>;
157
+ /**
158
+ * Request timeout in milliseconds
159
+ * @default 10000
160
+ */
161
+ timeout?: number;
162
+ }
163
+ /**
164
+ * Create an OTLP HTTP trace exporter for browser
165
+ *
166
+ * @param options - Exporter configuration options
167
+ * @returns OTLPTraceExporter instance
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const exporter = createOtlpExporter({
172
+ * endpoint: 'http://localhost:4318/v1/traces',
173
+ * headers: { 'x-api-key': 'secret' }
174
+ * })
175
+ * ```
176
+ */
177
+ declare function createOtlpExporter(options?: OtlpExporterOptions): OTLPTraceExporter;
178
+ /**
179
+ * Get OTLP endpoint from environment or use default
180
+ *
181
+ * Checks in order:
182
+ * 1. import.meta.env.VITE_OTEL_EXPORTER_OTLP_ENDPOINT (Vite)
183
+ * 2. window.OTEL_EXPORTER_OTLP_ENDPOINT (runtime config)
184
+ * 3. Default: http://localhost:4318/v1/traces
185
+ *
186
+ * @returns OTLP endpoint URL
187
+ */
188
+ declare function getOtlpEndpoint(): string;
189
+
190
+ /**
191
+ * Browser configuration loader using Effect Platform
192
+ *
193
+ * Provides HttpClient layer for the core ConfigLoader service
194
+ * (No FileSystem in browser)
195
+ */
196
+
197
+ /**
198
+ * Complete ConfigLoader layer with browser platform dependencies
199
+ *
200
+ * Provides:
201
+ * - ConfigLoader service
202
+ * - HttpClient (from FetchHttpClient)
203
+ * - No FileSystem (browser doesn't have filesystem access)
204
+ */
205
+ declare const WebConfigLoaderLive: Layer.Layer<ConfigLoader, never, never>;
206
+ /**
207
+ * Load configuration from URI (Promise-based convenience API)
208
+ *
209
+ * Automatically provides browser platform layers (HttpClient only)
210
+ *
211
+ * @param uri - Configuration URI (http://, https://, or relative path)
212
+ * @returns Promise that resolves to validated configuration
213
+ */
214
+ declare function loadConfig(uri: string): Promise<InstrumentationConfig>;
215
+ /**
216
+ * Load configuration from inline content (Promise-based convenience API)
217
+ *
218
+ * @param content - YAML string, JSON string, or plain object
219
+ * @returns Promise that resolves to validated configuration
220
+ */
221
+ declare function loadConfigFromInline(content: string | unknown): Promise<InstrumentationConfig>;
222
+
223
+ /**
224
+ * Pattern-Based Span Processor for Browser
225
+ *
226
+ * Filters spans based on patterns defined in instrumentation.yaml
227
+ * Re-uses pattern matching logic from @atrim/instrument-core
228
+ */
229
+
230
+ /**
231
+ * Span processor that filters spans based on pattern matching
232
+ *
233
+ * This processor runs BEFORE export and drops spans that don't match
234
+ * the configured patterns in instrumentation.yaml.
235
+ *
236
+ * @example
237
+ * ```yaml
238
+ * # instrumentation.yaml
239
+ * instrumentation:
240
+ * instrument_patterns:
241
+ * - pattern: "^documentLoad"
242
+ * - pattern: "^HTTP (GET|POST)"
243
+ * ignore_patterns:
244
+ * - pattern: "^HTTP GET /health"
245
+ * ```
246
+ */
247
+ declare class PatternSpanProcessor implements SpanProcessor {
248
+ /**
249
+ * Called when a span is started
250
+ * No-op for this processor
251
+ */
252
+ onStart(_span: ReadableSpan, _parentContext: Context): void;
253
+ /**
254
+ * Called when a span ends
255
+ * Filters out spans that don't match patterns
256
+ */
257
+ onEnd(span: ReadableSpan): void;
258
+ /**
259
+ * Shutdown the processor
260
+ * No-op for this processor
261
+ */
262
+ shutdown(): Promise<void>;
263
+ /**
264
+ * Force flush pending spans
265
+ * No-op for this processor
266
+ */
267
+ forceFlush(): Promise<void>;
268
+ }
269
+
270
+ /**
271
+ * Browser Span Helpers
272
+ *
273
+ * Utility functions for adding metadata to spans in browser applications
274
+ */
275
+
276
+ /**
277
+ * Set multiple attributes on a span
278
+ *
279
+ * @param span - OpenTelemetry span
280
+ * @param attributes - Key-value pairs to set as attributes
281
+ *
282
+ * @example
283
+ * ```typescript
284
+ * setSpanAttributes(span, {
285
+ * 'user.id': '123',
286
+ * 'page.url': window.location.href
287
+ * })
288
+ * ```
289
+ */
290
+ declare function setSpanAttributes(span: Span, attributes: Record<string, string | number | boolean>): void;
291
+ /**
292
+ * Record an exception on a span
293
+ *
294
+ * @param span - OpenTelemetry span
295
+ * @param error - Error object to record
296
+ * @param context - Additional context attributes
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * try {
301
+ * // ...
302
+ * } catch (error) {
303
+ * recordException(span, error, { 'page.url': window.location.href })
304
+ * }
305
+ * ```
306
+ */
307
+ declare function recordException(span: Span, error: Error, context?: Record<string, string | number | boolean>): void;
308
+ /**
309
+ * Mark a span as successful
310
+ *
311
+ * Sets status to OK and adds optional attributes
312
+ *
313
+ * @param span - OpenTelemetry span
314
+ * @param attributes - Optional attributes to add
315
+ */
316
+ declare function markSpanSuccess(span: Span, attributes?: Record<string, string | number | boolean>): void;
317
+ /**
318
+ * Mark a span as failed
319
+ *
320
+ * Sets status to ERROR and adds optional error message/attributes
321
+ *
322
+ * @param span - OpenTelemetry span
323
+ * @param message - Error message
324
+ * @param attributes - Optional attributes to add
325
+ */
326
+ declare function markSpanError(span: Span, message?: string, attributes?: Record<string, string | number | boolean>): void;
327
+ /**
328
+ * Annotate span with HTTP request details
329
+ *
330
+ * @param span - OpenTelemetry span
331
+ * @param options - HTTP request details
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * annotateHttpRequest(span, {
336
+ * method: 'GET',
337
+ * url: 'https://api.example.com/users',
338
+ * statusCode: 200,
339
+ * responseTime: 150
340
+ * })
341
+ * ```
342
+ */
343
+ declare function annotateHttpRequest(span: Span, options: {
344
+ method?: string;
345
+ url?: string;
346
+ statusCode?: number;
347
+ responseTime?: number;
348
+ requestSize?: number;
349
+ responseSize?: number;
350
+ }): void;
351
+ /**
352
+ * Annotate span with cache operation details
353
+ *
354
+ * @param span - OpenTelemetry span
355
+ * @param options - Cache operation details
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * annotate CacheOperation(span, {
360
+ * operation: 'get',
361
+ * key: 'user:123',
362
+ * hit: true
363
+ * })
364
+ * ```
365
+ */
366
+ declare function annotateCacheOperation(span: Span, options: {
367
+ operation: 'get' | 'set' | 'delete' | 'clear';
368
+ key?: string;
369
+ hit?: boolean;
370
+ size?: number;
371
+ }): void;
372
+ /**
373
+ * Annotate span with user interaction details
374
+ *
375
+ * @param span - OpenTelemetry span
376
+ * @param options - User interaction details
377
+ *
378
+ * @example
379
+ * ```typescript
380
+ * annotateUserInteraction(span, {
381
+ * type: 'click',
382
+ * target: 'button#submit',
383
+ * page: '/checkout'
384
+ * })
385
+ * ```
386
+ */
387
+ declare function annotateUserInteraction(span: Span, options: {
388
+ type: 'click' | 'submit' | 'input' | 'navigation';
389
+ target?: string;
390
+ page?: string;
391
+ }): void;
392
+ /**
393
+ * Annotate span with page navigation details
394
+ *
395
+ * @param span - OpenTelemetry span
396
+ * @param options - Navigation details
397
+ *
398
+ * @example
399
+ * ```typescript
400
+ * annotateNavigation(span, {
401
+ * from: '/home',
402
+ * to: '/profile',
403
+ * type: 'client-side'
404
+ * })
405
+ * ```
406
+ */
407
+ declare function annotateNavigation(span: Span, options: {
408
+ from?: string;
409
+ to?: string;
410
+ type?: 'client-side' | 'server-side' | 'initial';
411
+ }): void;
412
+
413
+ export { type OtlpExporterOptions, PatternSpanProcessor, type SdkInitializationOptions, WebConfigLoaderLive, annotateCacheOperation, annotateHttpRequest, annotateNavigation, annotateUserInteraction, createOtlpExporter, getOtlpEndpoint, getSdkInstance, initializeInstrumentation, loadConfig, loadConfigFromInline, markSpanError, markSpanSuccess, recordException, resetSdk, setSpanAttributes, shutdownSdk };