@atrim/instrument-node 0.4.1 → 0.5.0-14fdea7-20260109020503

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,4 +1,5 @@
1
- import { Layer, FiberSet as FiberSet$1, Effect } from 'effect';
1
+ import { Layer, Effect, FiberSet as FiberSet$1 } from 'effect';
2
+ import * as Tracer from '@effect/opentelemetry/Tracer';
2
3
  import { InstrumentationConfig } from '@atrim/instrument-core';
3
4
  import * as effect_Runtime from 'effect/Runtime';
4
5
  import * as effect_FiberId from 'effect/FiberId';
@@ -6,9 +7,10 @@ import * as effect_Scope from 'effect/Scope';
6
7
  import { RuntimeFiber } from 'effect/Fiber';
7
8
 
8
9
  /**
9
- * Node.js configuration loader using Effect Platform
10
+ * Node.js configuration loader
10
11
  *
11
- * Provides FileSystem and HttpClient layers for the core ConfigLoader service
12
+ * Provides configuration loading using native Node.js APIs (fs, fetch)
13
+ * This module doesn't require Effect Platform, making it work without Effect installed.
12
14
  */
13
15
 
14
16
  /**
@@ -46,17 +48,12 @@ interface ConfigLoaderOptions {
46
48
  */
47
49
  interface EffectInstrumentationOptions extends ConfigLoaderOptions {
48
50
  /**
49
- * OTLP endpoint URL
50
- * @default process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318'
51
- */
52
- otlpEndpoint?: string;
53
- /**
54
- * Service name
51
+ * Service name for Effect spans
55
52
  * @default process.env.OTEL_SERVICE_NAME || 'effect-service'
56
53
  */
57
54
  serviceName?: string;
58
55
  /**
59
- * Service version
56
+ * Service version for Effect spans
60
57
  * @default process.env.npm_package_version || '1.0.0'
61
58
  */
62
59
  serviceVersion?: string;
@@ -66,20 +63,17 @@ interface EffectInstrumentationOptions extends ConfigLoaderOptions {
66
63
  */
67
64
  autoExtractMetadata?: boolean;
68
65
  /**
69
- * Whether to continue existing traces from NodeSDK auto-instrumentation
70
- *
71
- * When true (default):
72
- * - Effect spans become children of existing NodeSDK spans
73
- * - Example: HTTP request span → Effect business logic span
74
- * - Uses OpenTelemetry Context API for propagation
75
- *
76
- * When false:
77
- * - Effect operations always create new root spans
78
- * - Not recommended unless you have specific requirements
79
- *
80
- * @default true
66
+ * OTLP endpoint URL (only used when exporter mode is 'standalone')
67
+ * @default process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318'
81
68
  */
82
- continueExistingTraces?: boolean;
69
+ otlpEndpoint?: string;
70
+ /**
71
+ * Exporter mode:
72
+ * - 'unified': Use global TracerProvider from Node SDK (recommended, enables filtering)
73
+ * - 'standalone': Use Effect's own OTLP exporter (bypasses Node SDK filtering)
74
+ * @default 'unified'
75
+ */
76
+ exporterMode?: 'unified' | 'standalone';
83
77
  }
84
78
  /**
85
79
  * Create Effect instrumentation layer with custom options
@@ -118,11 +112,12 @@ declare function createEffectInstrumentation(options?: EffectInstrumentationOpti
118
112
  *
119
113
  * Uses the global OpenTelemetry tracer provider that was set up by
120
114
  * initializeInstrumentation(). This ensures all traces (Express, Effect, etc.)
121
- * go to the same OTLP endpoint.
115
+ * go through the same TracerProvider and PatternSpanProcessor.
122
116
  *
123
117
  * Context Propagation:
124
118
  * - Automatically continues traces from NodeSDK auto-instrumentation
125
119
  * - Effect spans become children of HTTP request spans
120
+ * - Respects http.ignore_incoming_paths and other filtering patterns
126
121
  * - No configuration needed
127
122
  *
128
123
  * @example
@@ -138,27 +133,115 @@ declare function createEffectInstrumentation(options?: EffectInstrumentationOpti
138
133
  * )
139
134
  * ```
140
135
  */
141
- declare const EffectInstrumentationLive: Layer.Layer<never, never, never>;
136
+ declare const EffectInstrumentationLive: Layer.Layer<Tracer.OtelTracer, never, never>;
142
137
 
143
138
  /**
144
139
  * Effect-specific span annotation helpers
140
+ *
141
+ * Provides reusable helper functions for adding common span attributes.
142
+ * These helpers follow OpenTelemetry semantic conventions and platform patterns.
143
+ *
144
+ * Usage:
145
+ * ```typescript
146
+ * Effect.gen(function* () {
147
+ * yield* annotateUser(userId, email)
148
+ * yield* annotateBatch(items.length, 5)
149
+ * const results = yield* storage.writeBatch(items)
150
+ * yield* annotateBatch(items.length, 5, results.success, results.failures)
151
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
152
+ * ```
145
153
  */
146
- declare function annotateUser(_userId: string, _email?: string): void;
147
- declare function annotateDataSize(_bytes: number, _count: number): void;
148
- declare function annotateBatch(_size: number, _batchSize: number): void;
149
- declare function annotateLLM(_model: string, _operation: string, _inputTokens: number, _outputTokens: number): void;
150
- declare function annotateQuery(_query: string, _database: string): void;
151
- declare function annotateHttpRequest(_method: string, _url: string, _statusCode: number): void;
152
- declare function annotateError(_error: Error, _context?: Record<string, string | number | boolean>): void;
153
- declare function annotatePriority(_priority: string): void;
154
- declare function annotateCache(_operation: string, _hit: boolean): void;
154
+
155
+ /**
156
+ * Annotate span with user context
157
+ *
158
+ * @param userId - User identifier
159
+ * @param email - Optional user email
160
+ * @param username - Optional username
161
+ */
162
+ declare function annotateUser(userId: string, email?: string, username?: string): Effect.Effect<void, never, never>;
163
+ /**
164
+ * Annotate span with data size metrics
165
+ *
166
+ * @param bytes - Total bytes processed
167
+ * @param items - Number of items
168
+ * @param compressionRatio - Optional compression ratio
169
+ */
170
+ declare function annotateDataSize(bytes: number, items: number, compressionRatio?: number): Effect.Effect<void, never, never>;
171
+ /**
172
+ * Annotate span with batch operation metadata
173
+ *
174
+ * @param totalItems - Total number of items in batch
175
+ * @param batchSize - Size of each batch
176
+ * @param successCount - Optional number of successful items
177
+ * @param failureCount - Optional number of failed items
178
+ */
179
+ declare function annotateBatch(totalItems: number, batchSize: number, successCount?: number, failureCount?: number): Effect.Effect<void, never, never>;
180
+ /**
181
+ * Annotate span with LLM operation metadata
182
+ *
183
+ * @param model - Model name (e.g., 'gpt-4', 'claude-3-opus')
184
+ * @param provider - LLM provider (e.g., 'openai', 'anthropic')
185
+ * @param tokens - Optional token usage information
186
+ */
187
+ declare function annotateLLM(model: string, provider: string, tokens?: {
188
+ prompt?: number;
189
+ completion?: number;
190
+ total?: number;
191
+ }): Effect.Effect<void, never, never>;
192
+ /**
193
+ * Annotate span with database query metadata
194
+ *
195
+ * @param query - SQL query or query description
196
+ * @param duration - Optional query duration in milliseconds
197
+ * @param rowCount - Optional number of rows returned/affected
198
+ * @param database - Optional database name
199
+ */
200
+ declare function annotateQuery(query: string, duration?: number, rowCount?: number, database?: string): Effect.Effect<void, never, never>;
201
+ /**
202
+ * Annotate span with HTTP request metadata
203
+ *
204
+ * @param method - HTTP method (GET, POST, etc.)
205
+ * @param url - Request URL
206
+ * @param statusCode - Optional HTTP status code
207
+ * @param contentLength - Optional response content length
208
+ */
209
+ declare function annotateHttpRequest(method: string, url: string, statusCode?: number, contentLength?: number): Effect.Effect<void, never, never>;
210
+ /**
211
+ * Annotate span with error context
212
+ *
213
+ * @param error - Error object or message
214
+ * @param recoverable - Whether the error is recoverable
215
+ * @param errorType - Optional error type/category
216
+ */
217
+ declare function annotateError(error: Error | string, recoverable: boolean, errorType?: string): Effect.Effect<void, never, never>;
218
+ /**
219
+ * Annotate span with operation priority
220
+ *
221
+ * @param priority - Priority level (high, medium, low)
222
+ * @param reason - Optional reason for priority level
223
+ */
224
+ declare function annotatePriority(priority: 'high' | 'medium' | 'low', reason?: string): Effect.Effect<void, never, never>;
225
+ /**
226
+ * Annotate span with cache operation metadata
227
+ *
228
+ * @param hit - Whether the cache was hit
229
+ * @param key - Cache key
230
+ * @param ttl - Optional time-to-live in seconds
231
+ */
232
+ declare function annotateCache(hit: boolean, key: string, ttl?: number): Effect.Effect<void, never, never>;
155
233
 
156
234
  /**
157
235
  * Effect metadata extraction
158
236
  *
159
237
  * Automatically extracts metadata from Effect fibers and adds them as span attributes.
160
238
  * This provides valuable context about the Effect execution environment.
239
+ *
240
+ * Uses Effect's public APIs:
241
+ * - Fiber.getCurrentFiber() - Get current fiber information
242
+ * - Effect.currentSpan - Detect parent spans and nesting
161
243
  */
244
+
162
245
  /**
163
246
  * Metadata extracted from Effect fibers
164
247
  */
@@ -166,8 +249,95 @@ interface EffectMetadata {
166
249
  'effect.fiber.id'?: string;
167
250
  'effect.fiber.status'?: string;
168
251
  'effect.operation.root'?: boolean;
169
- 'effect.operation.interrupted'?: boolean;
252
+ 'effect.operation.nested'?: boolean;
253
+ 'effect.parent.span.id'?: string;
254
+ 'effect.parent.span.name'?: string;
255
+ 'effect.parent.trace.id'?: string;
170
256
  }
257
+ /**
258
+ * Extract Effect-native metadata from current execution context
259
+ *
260
+ * Uses Effect's native APIs:
261
+ * - Fiber.getCurrentFiber() - Get current fiber information
262
+ * - Effect.currentSpan - Detect parent spans and nesting
263
+ *
264
+ * @returns Effect that yields extracted metadata
265
+ */
266
+ declare function extractEffectMetadata(): Effect.Effect<EffectMetadata>;
267
+
268
+ /**
269
+ * Effect Auto-Enrichment Utilities
270
+ *
271
+ * Provides utilities for automatically extracting and enriching spans with Effect-native metadata.
272
+ *
273
+ * Usage:
274
+ * ```typescript
275
+ * import { autoEnrichSpan, withAutoEnrichedSpan } from '@atrim/instrument-node/effect'
276
+ *
277
+ * // Option 1: Manual enrichment
278
+ * Effect.gen(function* () {
279
+ * yield* autoEnrichSpan() // Auto-add Effect metadata
280
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
281
+ * const result = yield* storage.writeBatch(items)
282
+ * return result
283
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
284
+ *
285
+ * // Option 2: Automatic enrichment wrapper
286
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
287
+ * Effect.gen(function* () {
288
+ * yield* annotateBatch(items.length, 10)
289
+ * return yield* storage.writeBatch(items)
290
+ * })
291
+ * )
292
+ * ```
293
+ */
294
+
295
+ /**
296
+ * Auto-enrich the current span with Effect metadata
297
+ *
298
+ * This function should be called within an Effect.withSpan() context.
299
+ * It extracts Effect metadata (fiber ID, status, parent span info)
300
+ * and adds it as span attributes.
301
+ *
302
+ * Best practice: Call this at the start of your instrumented Effect:
303
+ *
304
+ * ```typescript
305
+ * Effect.gen(function* () {
306
+ * yield* autoEnrichSpan() // Auto-add metadata
307
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
308
+ * const result = yield* storage.writeBatch(items)
309
+ * return result
310
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
311
+ * ```
312
+ *
313
+ * @returns Effect that annotates the current span with Effect metadata
314
+ */
315
+ declare function autoEnrichSpan(): Effect.Effect<void>;
316
+ /**
317
+ * Create a wrapper that combines Effect.withSpan with automatic enrichment
318
+ *
319
+ * This is a convenience function that wraps an Effect with both:
320
+ * 1. A span (via Effect.withSpan)
321
+ * 2. Automatic metadata extraction (via autoEnrichSpan)
322
+ *
323
+ * Usage:
324
+ * ```typescript
325
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
326
+ * Effect.gen(function* () {
327
+ * yield* annotateBatch(items.length, 10)
328
+ * return yield* storage.writeBatch(items)
329
+ * })
330
+ * )
331
+ * ```
332
+ *
333
+ * @param spanName - The name of the span
334
+ * @param options - Optional span options
335
+ * @returns Function that wraps an Effect with an auto-enriched span
336
+ */
337
+ declare function withAutoEnrichedSpan<A, E, R>(spanName: string, options?: {
338
+ readonly attributes?: Record<string, unknown>;
339
+ readonly kind?: 'client' | 'server' | 'producer' | 'consumer' | 'internal';
340
+ }): (self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
171
341
 
172
342
  /**
173
343
  * Options for span isolation when running effects in FiberSet
@@ -356,4 +526,4 @@ declare const FiberSet: {
356
526
  }) => Effect.Effect<RuntimeFiber<A, E>, never, R>;
357
527
  };
358
528
 
359
- export { EffectInstrumentationLive, type EffectMetadata, FiberSet, type IsolationOptions, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, createEffectInstrumentation, runIsolated, runWithSpan };
529
+ export { EffectInstrumentationLive, type EffectMetadata, FiberSet, type IsolationOptions, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, autoEnrichSpan, createEffectInstrumentation, extractEffectMetadata, runIsolated, runWithSpan, withAutoEnrichedSpan };
@@ -1,4 +1,5 @@
1
- import { Layer, FiberSet as FiberSet$1, Effect } from 'effect';
1
+ import { Layer, Effect, FiberSet as FiberSet$1 } from 'effect';
2
+ import * as Tracer from '@effect/opentelemetry/Tracer';
2
3
  import { InstrumentationConfig } from '@atrim/instrument-core';
3
4
  import * as effect_Runtime from 'effect/Runtime';
4
5
  import * as effect_FiberId from 'effect/FiberId';
@@ -6,9 +7,10 @@ import * as effect_Scope from 'effect/Scope';
6
7
  import { RuntimeFiber } from 'effect/Fiber';
7
8
 
8
9
  /**
9
- * Node.js configuration loader using Effect Platform
10
+ * Node.js configuration loader
10
11
  *
11
- * Provides FileSystem and HttpClient layers for the core ConfigLoader service
12
+ * Provides configuration loading using native Node.js APIs (fs, fetch)
13
+ * This module doesn't require Effect Platform, making it work without Effect installed.
12
14
  */
13
15
 
14
16
  /**
@@ -46,17 +48,12 @@ interface ConfigLoaderOptions {
46
48
  */
47
49
  interface EffectInstrumentationOptions extends ConfigLoaderOptions {
48
50
  /**
49
- * OTLP endpoint URL
50
- * @default process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318'
51
- */
52
- otlpEndpoint?: string;
53
- /**
54
- * Service name
51
+ * Service name for Effect spans
55
52
  * @default process.env.OTEL_SERVICE_NAME || 'effect-service'
56
53
  */
57
54
  serviceName?: string;
58
55
  /**
59
- * Service version
56
+ * Service version for Effect spans
60
57
  * @default process.env.npm_package_version || '1.0.0'
61
58
  */
62
59
  serviceVersion?: string;
@@ -66,20 +63,17 @@ interface EffectInstrumentationOptions extends ConfigLoaderOptions {
66
63
  */
67
64
  autoExtractMetadata?: boolean;
68
65
  /**
69
- * Whether to continue existing traces from NodeSDK auto-instrumentation
70
- *
71
- * When true (default):
72
- * - Effect spans become children of existing NodeSDK spans
73
- * - Example: HTTP request span → Effect business logic span
74
- * - Uses OpenTelemetry Context API for propagation
75
- *
76
- * When false:
77
- * - Effect operations always create new root spans
78
- * - Not recommended unless you have specific requirements
79
- *
80
- * @default true
66
+ * OTLP endpoint URL (only used when exporter mode is 'standalone')
67
+ * @default process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318'
81
68
  */
82
- continueExistingTraces?: boolean;
69
+ otlpEndpoint?: string;
70
+ /**
71
+ * Exporter mode:
72
+ * - 'unified': Use global TracerProvider from Node SDK (recommended, enables filtering)
73
+ * - 'standalone': Use Effect's own OTLP exporter (bypasses Node SDK filtering)
74
+ * @default 'unified'
75
+ */
76
+ exporterMode?: 'unified' | 'standalone';
83
77
  }
84
78
  /**
85
79
  * Create Effect instrumentation layer with custom options
@@ -118,11 +112,12 @@ declare function createEffectInstrumentation(options?: EffectInstrumentationOpti
118
112
  *
119
113
  * Uses the global OpenTelemetry tracer provider that was set up by
120
114
  * initializeInstrumentation(). This ensures all traces (Express, Effect, etc.)
121
- * go to the same OTLP endpoint.
115
+ * go through the same TracerProvider and PatternSpanProcessor.
122
116
  *
123
117
  * Context Propagation:
124
118
  * - Automatically continues traces from NodeSDK auto-instrumentation
125
119
  * - Effect spans become children of HTTP request spans
120
+ * - Respects http.ignore_incoming_paths and other filtering patterns
126
121
  * - No configuration needed
127
122
  *
128
123
  * @example
@@ -138,27 +133,115 @@ declare function createEffectInstrumentation(options?: EffectInstrumentationOpti
138
133
  * )
139
134
  * ```
140
135
  */
141
- declare const EffectInstrumentationLive: Layer.Layer<never, never, never>;
136
+ declare const EffectInstrumentationLive: Layer.Layer<Tracer.OtelTracer, never, never>;
142
137
 
143
138
  /**
144
139
  * Effect-specific span annotation helpers
140
+ *
141
+ * Provides reusable helper functions for adding common span attributes.
142
+ * These helpers follow OpenTelemetry semantic conventions and platform patterns.
143
+ *
144
+ * Usage:
145
+ * ```typescript
146
+ * Effect.gen(function* () {
147
+ * yield* annotateUser(userId, email)
148
+ * yield* annotateBatch(items.length, 5)
149
+ * const results = yield* storage.writeBatch(items)
150
+ * yield* annotateBatch(items.length, 5, results.success, results.failures)
151
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
152
+ * ```
145
153
  */
146
- declare function annotateUser(_userId: string, _email?: string): void;
147
- declare function annotateDataSize(_bytes: number, _count: number): void;
148
- declare function annotateBatch(_size: number, _batchSize: number): void;
149
- declare function annotateLLM(_model: string, _operation: string, _inputTokens: number, _outputTokens: number): void;
150
- declare function annotateQuery(_query: string, _database: string): void;
151
- declare function annotateHttpRequest(_method: string, _url: string, _statusCode: number): void;
152
- declare function annotateError(_error: Error, _context?: Record<string, string | number | boolean>): void;
153
- declare function annotatePriority(_priority: string): void;
154
- declare function annotateCache(_operation: string, _hit: boolean): void;
154
+
155
+ /**
156
+ * Annotate span with user context
157
+ *
158
+ * @param userId - User identifier
159
+ * @param email - Optional user email
160
+ * @param username - Optional username
161
+ */
162
+ declare function annotateUser(userId: string, email?: string, username?: string): Effect.Effect<void, never, never>;
163
+ /**
164
+ * Annotate span with data size metrics
165
+ *
166
+ * @param bytes - Total bytes processed
167
+ * @param items - Number of items
168
+ * @param compressionRatio - Optional compression ratio
169
+ */
170
+ declare function annotateDataSize(bytes: number, items: number, compressionRatio?: number): Effect.Effect<void, never, never>;
171
+ /**
172
+ * Annotate span with batch operation metadata
173
+ *
174
+ * @param totalItems - Total number of items in batch
175
+ * @param batchSize - Size of each batch
176
+ * @param successCount - Optional number of successful items
177
+ * @param failureCount - Optional number of failed items
178
+ */
179
+ declare function annotateBatch(totalItems: number, batchSize: number, successCount?: number, failureCount?: number): Effect.Effect<void, never, never>;
180
+ /**
181
+ * Annotate span with LLM operation metadata
182
+ *
183
+ * @param model - Model name (e.g., 'gpt-4', 'claude-3-opus')
184
+ * @param provider - LLM provider (e.g., 'openai', 'anthropic')
185
+ * @param tokens - Optional token usage information
186
+ */
187
+ declare function annotateLLM(model: string, provider: string, tokens?: {
188
+ prompt?: number;
189
+ completion?: number;
190
+ total?: number;
191
+ }): Effect.Effect<void, never, never>;
192
+ /**
193
+ * Annotate span with database query metadata
194
+ *
195
+ * @param query - SQL query or query description
196
+ * @param duration - Optional query duration in milliseconds
197
+ * @param rowCount - Optional number of rows returned/affected
198
+ * @param database - Optional database name
199
+ */
200
+ declare function annotateQuery(query: string, duration?: number, rowCount?: number, database?: string): Effect.Effect<void, never, never>;
201
+ /**
202
+ * Annotate span with HTTP request metadata
203
+ *
204
+ * @param method - HTTP method (GET, POST, etc.)
205
+ * @param url - Request URL
206
+ * @param statusCode - Optional HTTP status code
207
+ * @param contentLength - Optional response content length
208
+ */
209
+ declare function annotateHttpRequest(method: string, url: string, statusCode?: number, contentLength?: number): Effect.Effect<void, never, never>;
210
+ /**
211
+ * Annotate span with error context
212
+ *
213
+ * @param error - Error object or message
214
+ * @param recoverable - Whether the error is recoverable
215
+ * @param errorType - Optional error type/category
216
+ */
217
+ declare function annotateError(error: Error | string, recoverable: boolean, errorType?: string): Effect.Effect<void, never, never>;
218
+ /**
219
+ * Annotate span with operation priority
220
+ *
221
+ * @param priority - Priority level (high, medium, low)
222
+ * @param reason - Optional reason for priority level
223
+ */
224
+ declare function annotatePriority(priority: 'high' | 'medium' | 'low', reason?: string): Effect.Effect<void, never, never>;
225
+ /**
226
+ * Annotate span with cache operation metadata
227
+ *
228
+ * @param hit - Whether the cache was hit
229
+ * @param key - Cache key
230
+ * @param ttl - Optional time-to-live in seconds
231
+ */
232
+ declare function annotateCache(hit: boolean, key: string, ttl?: number): Effect.Effect<void, never, never>;
155
233
 
156
234
  /**
157
235
  * Effect metadata extraction
158
236
  *
159
237
  * Automatically extracts metadata from Effect fibers and adds them as span attributes.
160
238
  * This provides valuable context about the Effect execution environment.
239
+ *
240
+ * Uses Effect's public APIs:
241
+ * - Fiber.getCurrentFiber() - Get current fiber information
242
+ * - Effect.currentSpan - Detect parent spans and nesting
161
243
  */
244
+
162
245
  /**
163
246
  * Metadata extracted from Effect fibers
164
247
  */
@@ -166,8 +249,95 @@ interface EffectMetadata {
166
249
  'effect.fiber.id'?: string;
167
250
  'effect.fiber.status'?: string;
168
251
  'effect.operation.root'?: boolean;
169
- 'effect.operation.interrupted'?: boolean;
252
+ 'effect.operation.nested'?: boolean;
253
+ 'effect.parent.span.id'?: string;
254
+ 'effect.parent.span.name'?: string;
255
+ 'effect.parent.trace.id'?: string;
170
256
  }
257
+ /**
258
+ * Extract Effect-native metadata from current execution context
259
+ *
260
+ * Uses Effect's native APIs:
261
+ * - Fiber.getCurrentFiber() - Get current fiber information
262
+ * - Effect.currentSpan - Detect parent spans and nesting
263
+ *
264
+ * @returns Effect that yields extracted metadata
265
+ */
266
+ declare function extractEffectMetadata(): Effect.Effect<EffectMetadata>;
267
+
268
+ /**
269
+ * Effect Auto-Enrichment Utilities
270
+ *
271
+ * Provides utilities for automatically extracting and enriching spans with Effect-native metadata.
272
+ *
273
+ * Usage:
274
+ * ```typescript
275
+ * import { autoEnrichSpan, withAutoEnrichedSpan } from '@atrim/instrument-node/effect'
276
+ *
277
+ * // Option 1: Manual enrichment
278
+ * Effect.gen(function* () {
279
+ * yield* autoEnrichSpan() // Auto-add Effect metadata
280
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
281
+ * const result = yield* storage.writeBatch(items)
282
+ * return result
283
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
284
+ *
285
+ * // Option 2: Automatic enrichment wrapper
286
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
287
+ * Effect.gen(function* () {
288
+ * yield* annotateBatch(items.length, 10)
289
+ * return yield* storage.writeBatch(items)
290
+ * })
291
+ * )
292
+ * ```
293
+ */
294
+
295
+ /**
296
+ * Auto-enrich the current span with Effect metadata
297
+ *
298
+ * This function should be called within an Effect.withSpan() context.
299
+ * It extracts Effect metadata (fiber ID, status, parent span info)
300
+ * and adds it as span attributes.
301
+ *
302
+ * Best practice: Call this at the start of your instrumented Effect:
303
+ *
304
+ * ```typescript
305
+ * Effect.gen(function* () {
306
+ * yield* autoEnrichSpan() // Auto-add metadata
307
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
308
+ * const result = yield* storage.writeBatch(items)
309
+ * return result
310
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
311
+ * ```
312
+ *
313
+ * @returns Effect that annotates the current span with Effect metadata
314
+ */
315
+ declare function autoEnrichSpan(): Effect.Effect<void>;
316
+ /**
317
+ * Create a wrapper that combines Effect.withSpan with automatic enrichment
318
+ *
319
+ * This is a convenience function that wraps an Effect with both:
320
+ * 1. A span (via Effect.withSpan)
321
+ * 2. Automatic metadata extraction (via autoEnrichSpan)
322
+ *
323
+ * Usage:
324
+ * ```typescript
325
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
326
+ * Effect.gen(function* () {
327
+ * yield* annotateBatch(items.length, 10)
328
+ * return yield* storage.writeBatch(items)
329
+ * })
330
+ * )
331
+ * ```
332
+ *
333
+ * @param spanName - The name of the span
334
+ * @param options - Optional span options
335
+ * @returns Function that wraps an Effect with an auto-enriched span
336
+ */
337
+ declare function withAutoEnrichedSpan<A, E, R>(spanName: string, options?: {
338
+ readonly attributes?: Record<string, unknown>;
339
+ readonly kind?: 'client' | 'server' | 'producer' | 'consumer' | 'internal';
340
+ }): (self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
171
341
 
172
342
  /**
173
343
  * Options for span isolation when running effects in FiberSet
@@ -356,4 +526,4 @@ declare const FiberSet: {
356
526
  }) => Effect.Effect<RuntimeFiber<A, E>, never, R>;
357
527
  };
358
528
 
359
- export { EffectInstrumentationLive, type EffectMetadata, FiberSet, type IsolationOptions, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, createEffectInstrumentation, runIsolated, runWithSpan };
529
+ export { EffectInstrumentationLive, type EffectMetadata, FiberSet, type IsolationOptions, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, autoEnrichSpan, createEffectInstrumentation, extractEffectMetadata, runIsolated, runWithSpan, withAutoEnrichedSpan };