@atrim/instrument-node 0.5.0-c05e3a1-20251119131235 → 0.5.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,4 +1,4 @@
1
- import { Layer, FiberSet as FiberSet$1, Effect } from 'effect';
1
+ import { Layer, Effect, FiberSet as FiberSet$1 } from 'effect';
2
2
  import { InstrumentationConfig } from '@atrim/instrument-core';
3
3
  import * as effect_Runtime from 'effect/Runtime';
4
4
  import * as effect_FiberId from 'effect/FiberId';
@@ -142,23 +142,111 @@ declare const EffectInstrumentationLive: Layer.Layer<never, never, never>;
142
142
 
143
143
  /**
144
144
  * Effect-specific span annotation helpers
145
+ *
146
+ * Provides reusable helper functions for adding common span attributes.
147
+ * These helpers follow OpenTelemetry semantic conventions and platform patterns.
148
+ *
149
+ * Usage:
150
+ * ```typescript
151
+ * Effect.gen(function* () {
152
+ * yield* annotateUser(userId, email)
153
+ * yield* annotateBatch(items.length, 5)
154
+ * const results = yield* storage.writeBatch(items)
155
+ * yield* annotateBatch(items.length, 5, results.success, results.failures)
156
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
157
+ * ```
145
158
  */
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;
159
+
160
+ /**
161
+ * Annotate span with user context
162
+ *
163
+ * @param userId - User identifier
164
+ * @param email - Optional user email
165
+ * @param username - Optional username
166
+ */
167
+ declare function annotateUser(userId: string, email?: string, username?: string): Effect.Effect<void, never, never>;
168
+ /**
169
+ * Annotate span with data size metrics
170
+ *
171
+ * @param bytes - Total bytes processed
172
+ * @param items - Number of items
173
+ * @param compressionRatio - Optional compression ratio
174
+ */
175
+ declare function annotateDataSize(bytes: number, items: number, compressionRatio?: number): Effect.Effect<void, never, never>;
176
+ /**
177
+ * Annotate span with batch operation metadata
178
+ *
179
+ * @param totalItems - Total number of items in batch
180
+ * @param batchSize - Size of each batch
181
+ * @param successCount - Optional number of successful items
182
+ * @param failureCount - Optional number of failed items
183
+ */
184
+ declare function annotateBatch(totalItems: number, batchSize: number, successCount?: number, failureCount?: number): Effect.Effect<void, never, never>;
185
+ /**
186
+ * Annotate span with LLM operation metadata
187
+ *
188
+ * @param model - Model name (e.g., 'gpt-4', 'claude-3-opus')
189
+ * @param provider - LLM provider (e.g., 'openai', 'anthropic')
190
+ * @param tokens - Optional token usage information
191
+ */
192
+ declare function annotateLLM(model: string, provider: string, tokens?: {
193
+ prompt?: number;
194
+ completion?: number;
195
+ total?: number;
196
+ }): Effect.Effect<void, never, never>;
197
+ /**
198
+ * Annotate span with database query metadata
199
+ *
200
+ * @param query - SQL query or query description
201
+ * @param duration - Optional query duration in milliseconds
202
+ * @param rowCount - Optional number of rows returned/affected
203
+ * @param database - Optional database name
204
+ */
205
+ declare function annotateQuery(query: string, duration?: number, rowCount?: number, database?: string): Effect.Effect<void, never, never>;
206
+ /**
207
+ * Annotate span with HTTP request metadata
208
+ *
209
+ * @param method - HTTP method (GET, POST, etc.)
210
+ * @param url - Request URL
211
+ * @param statusCode - Optional HTTP status code
212
+ * @param contentLength - Optional response content length
213
+ */
214
+ declare function annotateHttpRequest(method: string, url: string, statusCode?: number, contentLength?: number): Effect.Effect<void, never, never>;
215
+ /**
216
+ * Annotate span with error context
217
+ *
218
+ * @param error - Error object or message
219
+ * @param recoverable - Whether the error is recoverable
220
+ * @param errorType - Optional error type/category
221
+ */
222
+ declare function annotateError(error: Error | string, recoverable: boolean, errorType?: string): Effect.Effect<void, never, never>;
223
+ /**
224
+ * Annotate span with operation priority
225
+ *
226
+ * @param priority - Priority level (high, medium, low)
227
+ * @param reason - Optional reason for priority level
228
+ */
229
+ declare function annotatePriority(priority: 'high' | 'medium' | 'low', reason?: string): Effect.Effect<void, never, never>;
230
+ /**
231
+ * Annotate span with cache operation metadata
232
+ *
233
+ * @param hit - Whether the cache was hit
234
+ * @param key - Cache key
235
+ * @param ttl - Optional time-to-live in seconds
236
+ */
237
+ declare function annotateCache(hit: boolean, key: string, ttl?: number): Effect.Effect<void, never, never>;
155
238
 
156
239
  /**
157
240
  * Effect metadata extraction
158
241
  *
159
242
  * Automatically extracts metadata from Effect fibers and adds them as span attributes.
160
243
  * This provides valuable context about the Effect execution environment.
244
+ *
245
+ * Uses Effect's public APIs:
246
+ * - Fiber.getCurrentFiber() - Get current fiber information
247
+ * - Effect.currentSpan - Detect parent spans and nesting
161
248
  */
249
+
162
250
  /**
163
251
  * Metadata extracted from Effect fibers
164
252
  */
@@ -166,8 +254,95 @@ interface EffectMetadata {
166
254
  'effect.fiber.id'?: string;
167
255
  'effect.fiber.status'?: string;
168
256
  'effect.operation.root'?: boolean;
169
- 'effect.operation.interrupted'?: boolean;
257
+ 'effect.operation.nested'?: boolean;
258
+ 'effect.parent.span.id'?: string;
259
+ 'effect.parent.span.name'?: string;
260
+ 'effect.parent.trace.id'?: string;
170
261
  }
262
+ /**
263
+ * Extract Effect-native metadata from current execution context
264
+ *
265
+ * Uses Effect's native APIs:
266
+ * - Fiber.getCurrentFiber() - Get current fiber information
267
+ * - Effect.currentSpan - Detect parent spans and nesting
268
+ *
269
+ * @returns Effect that yields extracted metadata
270
+ */
271
+ declare function extractEffectMetadata(): Effect.Effect<EffectMetadata>;
272
+
273
+ /**
274
+ * Effect Auto-Enrichment Utilities
275
+ *
276
+ * Provides utilities for automatically extracting and enriching spans with Effect-native metadata.
277
+ *
278
+ * Usage:
279
+ * ```typescript
280
+ * import { autoEnrichSpan, withAutoEnrichedSpan } from '@atrim/instrument-node/effect'
281
+ *
282
+ * // Option 1: Manual enrichment
283
+ * Effect.gen(function* () {
284
+ * yield* autoEnrichSpan() // Auto-add Effect metadata
285
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
286
+ * const result = yield* storage.writeBatch(items)
287
+ * return result
288
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
289
+ *
290
+ * // Option 2: Automatic enrichment wrapper
291
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
292
+ * Effect.gen(function* () {
293
+ * yield* annotateBatch(items.length, 10)
294
+ * return yield* storage.writeBatch(items)
295
+ * })
296
+ * )
297
+ * ```
298
+ */
299
+
300
+ /**
301
+ * Auto-enrich the current span with Effect metadata
302
+ *
303
+ * This function should be called within an Effect.withSpan() context.
304
+ * It extracts Effect metadata (fiber ID, status, parent span info)
305
+ * and adds it as span attributes.
306
+ *
307
+ * Best practice: Call this at the start of your instrumented Effect:
308
+ *
309
+ * ```typescript
310
+ * Effect.gen(function* () {
311
+ * yield* autoEnrichSpan() // Auto-add metadata
312
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
313
+ * const result = yield* storage.writeBatch(items)
314
+ * return result
315
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
316
+ * ```
317
+ *
318
+ * @returns Effect that annotates the current span with Effect metadata
319
+ */
320
+ declare function autoEnrichSpan(): Effect.Effect<void>;
321
+ /**
322
+ * Create a wrapper that combines Effect.withSpan with automatic enrichment
323
+ *
324
+ * This is a convenience function that wraps an Effect with both:
325
+ * 1. A span (via Effect.withSpan)
326
+ * 2. Automatic metadata extraction (via autoEnrichSpan)
327
+ *
328
+ * Usage:
329
+ * ```typescript
330
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
331
+ * Effect.gen(function* () {
332
+ * yield* annotateBatch(items.length, 10)
333
+ * return yield* storage.writeBatch(items)
334
+ * })
335
+ * )
336
+ * ```
337
+ *
338
+ * @param spanName - The name of the span
339
+ * @param options - Optional span options
340
+ * @returns Function that wraps an Effect with an auto-enriched span
341
+ */
342
+ declare function withAutoEnrichedSpan<A, E, R>(spanName: string, options?: {
343
+ readonly attributes?: Record<string, unknown>;
344
+ readonly kind?: 'client' | 'server' | 'producer' | 'consumer' | 'internal';
345
+ }): (self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
171
346
 
172
347
  /**
173
348
  * Options for span isolation when running effects in FiberSet
@@ -356,4 +531,4 @@ declare const FiberSet: {
356
531
  }) => Effect.Effect<RuntimeFiber<A, E>, never, R>;
357
532
  };
358
533
 
359
- export { EffectInstrumentationLive, type EffectMetadata, FiberSet, type IsolationOptions, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, createEffectInstrumentation, runIsolated, runWithSpan };
534
+ 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,4 @@
1
- import { Layer, FiberSet as FiberSet$1, Effect } from 'effect';
1
+ import { Layer, Effect, FiberSet as FiberSet$1 } from 'effect';
2
2
  import { InstrumentationConfig } from '@atrim/instrument-core';
3
3
  import * as effect_Runtime from 'effect/Runtime';
4
4
  import * as effect_FiberId from 'effect/FiberId';
@@ -142,23 +142,111 @@ declare const EffectInstrumentationLive: Layer.Layer<never, never, never>;
142
142
 
143
143
  /**
144
144
  * Effect-specific span annotation helpers
145
+ *
146
+ * Provides reusable helper functions for adding common span attributes.
147
+ * These helpers follow OpenTelemetry semantic conventions and platform patterns.
148
+ *
149
+ * Usage:
150
+ * ```typescript
151
+ * Effect.gen(function* () {
152
+ * yield* annotateUser(userId, email)
153
+ * yield* annotateBatch(items.length, 5)
154
+ * const results = yield* storage.writeBatch(items)
155
+ * yield* annotateBatch(items.length, 5, results.success, results.failures)
156
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
157
+ * ```
145
158
  */
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;
159
+
160
+ /**
161
+ * Annotate span with user context
162
+ *
163
+ * @param userId - User identifier
164
+ * @param email - Optional user email
165
+ * @param username - Optional username
166
+ */
167
+ declare function annotateUser(userId: string, email?: string, username?: string): Effect.Effect<void, never, never>;
168
+ /**
169
+ * Annotate span with data size metrics
170
+ *
171
+ * @param bytes - Total bytes processed
172
+ * @param items - Number of items
173
+ * @param compressionRatio - Optional compression ratio
174
+ */
175
+ declare function annotateDataSize(bytes: number, items: number, compressionRatio?: number): Effect.Effect<void, never, never>;
176
+ /**
177
+ * Annotate span with batch operation metadata
178
+ *
179
+ * @param totalItems - Total number of items in batch
180
+ * @param batchSize - Size of each batch
181
+ * @param successCount - Optional number of successful items
182
+ * @param failureCount - Optional number of failed items
183
+ */
184
+ declare function annotateBatch(totalItems: number, batchSize: number, successCount?: number, failureCount?: number): Effect.Effect<void, never, never>;
185
+ /**
186
+ * Annotate span with LLM operation metadata
187
+ *
188
+ * @param model - Model name (e.g., 'gpt-4', 'claude-3-opus')
189
+ * @param provider - LLM provider (e.g., 'openai', 'anthropic')
190
+ * @param tokens - Optional token usage information
191
+ */
192
+ declare function annotateLLM(model: string, provider: string, tokens?: {
193
+ prompt?: number;
194
+ completion?: number;
195
+ total?: number;
196
+ }): Effect.Effect<void, never, never>;
197
+ /**
198
+ * Annotate span with database query metadata
199
+ *
200
+ * @param query - SQL query or query description
201
+ * @param duration - Optional query duration in milliseconds
202
+ * @param rowCount - Optional number of rows returned/affected
203
+ * @param database - Optional database name
204
+ */
205
+ declare function annotateQuery(query: string, duration?: number, rowCount?: number, database?: string): Effect.Effect<void, never, never>;
206
+ /**
207
+ * Annotate span with HTTP request metadata
208
+ *
209
+ * @param method - HTTP method (GET, POST, etc.)
210
+ * @param url - Request URL
211
+ * @param statusCode - Optional HTTP status code
212
+ * @param contentLength - Optional response content length
213
+ */
214
+ declare function annotateHttpRequest(method: string, url: string, statusCode?: number, contentLength?: number): Effect.Effect<void, never, never>;
215
+ /**
216
+ * Annotate span with error context
217
+ *
218
+ * @param error - Error object or message
219
+ * @param recoverable - Whether the error is recoverable
220
+ * @param errorType - Optional error type/category
221
+ */
222
+ declare function annotateError(error: Error | string, recoverable: boolean, errorType?: string): Effect.Effect<void, never, never>;
223
+ /**
224
+ * Annotate span with operation priority
225
+ *
226
+ * @param priority - Priority level (high, medium, low)
227
+ * @param reason - Optional reason for priority level
228
+ */
229
+ declare function annotatePriority(priority: 'high' | 'medium' | 'low', reason?: string): Effect.Effect<void, never, never>;
230
+ /**
231
+ * Annotate span with cache operation metadata
232
+ *
233
+ * @param hit - Whether the cache was hit
234
+ * @param key - Cache key
235
+ * @param ttl - Optional time-to-live in seconds
236
+ */
237
+ declare function annotateCache(hit: boolean, key: string, ttl?: number): Effect.Effect<void, never, never>;
155
238
 
156
239
  /**
157
240
  * Effect metadata extraction
158
241
  *
159
242
  * Automatically extracts metadata from Effect fibers and adds them as span attributes.
160
243
  * This provides valuable context about the Effect execution environment.
244
+ *
245
+ * Uses Effect's public APIs:
246
+ * - Fiber.getCurrentFiber() - Get current fiber information
247
+ * - Effect.currentSpan - Detect parent spans and nesting
161
248
  */
249
+
162
250
  /**
163
251
  * Metadata extracted from Effect fibers
164
252
  */
@@ -166,8 +254,95 @@ interface EffectMetadata {
166
254
  'effect.fiber.id'?: string;
167
255
  'effect.fiber.status'?: string;
168
256
  'effect.operation.root'?: boolean;
169
- 'effect.operation.interrupted'?: boolean;
257
+ 'effect.operation.nested'?: boolean;
258
+ 'effect.parent.span.id'?: string;
259
+ 'effect.parent.span.name'?: string;
260
+ 'effect.parent.trace.id'?: string;
170
261
  }
262
+ /**
263
+ * Extract Effect-native metadata from current execution context
264
+ *
265
+ * Uses Effect's native APIs:
266
+ * - Fiber.getCurrentFiber() - Get current fiber information
267
+ * - Effect.currentSpan - Detect parent spans and nesting
268
+ *
269
+ * @returns Effect that yields extracted metadata
270
+ */
271
+ declare function extractEffectMetadata(): Effect.Effect<EffectMetadata>;
272
+
273
+ /**
274
+ * Effect Auto-Enrichment Utilities
275
+ *
276
+ * Provides utilities for automatically extracting and enriching spans with Effect-native metadata.
277
+ *
278
+ * Usage:
279
+ * ```typescript
280
+ * import { autoEnrichSpan, withAutoEnrichedSpan } from '@atrim/instrument-node/effect'
281
+ *
282
+ * // Option 1: Manual enrichment
283
+ * Effect.gen(function* () {
284
+ * yield* autoEnrichSpan() // Auto-add Effect metadata
285
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
286
+ * const result = yield* storage.writeBatch(items)
287
+ * return result
288
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
289
+ *
290
+ * // Option 2: Automatic enrichment wrapper
291
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
292
+ * Effect.gen(function* () {
293
+ * yield* annotateBatch(items.length, 10)
294
+ * return yield* storage.writeBatch(items)
295
+ * })
296
+ * )
297
+ * ```
298
+ */
299
+
300
+ /**
301
+ * Auto-enrich the current span with Effect metadata
302
+ *
303
+ * This function should be called within an Effect.withSpan() context.
304
+ * It extracts Effect metadata (fiber ID, status, parent span info)
305
+ * and adds it as span attributes.
306
+ *
307
+ * Best practice: Call this at the start of your instrumented Effect:
308
+ *
309
+ * ```typescript
310
+ * Effect.gen(function* () {
311
+ * yield* autoEnrichSpan() // Auto-add metadata
312
+ * yield* annotateBatch(items.length, 10) // Add custom attributes
313
+ * const result = yield* storage.writeBatch(items)
314
+ * return result
315
+ * }).pipe(Effect.withSpan('storage.writeBatch'))
316
+ * ```
317
+ *
318
+ * @returns Effect that annotates the current span with Effect metadata
319
+ */
320
+ declare function autoEnrichSpan(): Effect.Effect<void>;
321
+ /**
322
+ * Create a wrapper that combines Effect.withSpan with automatic enrichment
323
+ *
324
+ * This is a convenience function that wraps an Effect with both:
325
+ * 1. A span (via Effect.withSpan)
326
+ * 2. Automatic metadata extraction (via autoEnrichSpan)
327
+ *
328
+ * Usage:
329
+ * ```typescript
330
+ * const instrumented = withAutoEnrichedSpan('storage.writeBatch')(
331
+ * Effect.gen(function* () {
332
+ * yield* annotateBatch(items.length, 10)
333
+ * return yield* storage.writeBatch(items)
334
+ * })
335
+ * )
336
+ * ```
337
+ *
338
+ * @param spanName - The name of the span
339
+ * @param options - Optional span options
340
+ * @returns Function that wraps an Effect with an auto-enriched span
341
+ */
342
+ declare function withAutoEnrichedSpan<A, E, R>(spanName: string, options?: {
343
+ readonly attributes?: Record<string, unknown>;
344
+ readonly kind?: 'client' | 'server' | 'producer' | 'consumer' | 'internal';
345
+ }): (self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
171
346
 
172
347
  /**
173
348
  * Options for span isolation when running effects in FiberSet
@@ -356,4 +531,4 @@ declare const FiberSet: {
356
531
  }) => Effect.Effect<RuntimeFiber<A, E>, never, R>;
357
532
  };
358
533
 
359
- export { EffectInstrumentationLive, type EffectMetadata, FiberSet, type IsolationOptions, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, createEffectInstrumentation, runIsolated, runWithSpan };
534
+ 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,4 @@
1
- import { Data, Context, Effect, Layer, FiberSet as FiberSet$1, Tracer } from 'effect';
1
+ import { Data, Context, Effect, Layer, FiberSet as FiberSet$1, Fiber, Option, FiberId, Tracer } from 'effect';
2
2
  import * as Otlp from '@effect/opentelemetry/Otlp';
3
3
  import { FetchHttpClient } from '@effect/platform';
4
4
  import { TraceFlags, trace, context } from '@opentelemetry/api';
@@ -10,6 +10,11 @@ import { z } from 'zod';
10
10
  import { NodeContext } from '@effect/platform-node';
11
11
 
12
12
  // src/integrations/effect/effect-tracer.ts
13
+
14
+ // ../../node_modules/.pnpm/@opentelemetry+semantic-conventions@1.38.0/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js
15
+ var ATTR_TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language";
16
+ var TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS = "nodejs";
17
+ var ATTR_TELEMETRY_SDK_NAME = "telemetry.sdk.name";
13
18
  var __defProp = Object.defineProperty;
14
19
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15
20
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -478,6 +483,7 @@ async function loadConfigWithOptions(options = {}) {
478
483
  }
479
484
 
480
485
  // src/integrations/effect/effect-tracer.ts
486
+ var SDK_NAME = "@effect/opentelemetry-otlp";
481
487
  function createEffectInstrumentation(options = {}) {
482
488
  return Layer.unwrapEffect(
483
489
  Effect.gen(function* () {
@@ -511,7 +517,9 @@ function createEffectInstrumentation(options = {}) {
511
517
  attributes: {
512
518
  "platform.component": "effect",
513
519
  "effect.auto_metadata": autoExtractMetadata,
514
- "effect.context_propagation": continueExistingTraces
520
+ "effect.context_propagation": continueExistingTraces,
521
+ [ATTR_TELEMETRY_SDK_LANGUAGE]: TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
522
+ [ATTR_TELEMETRY_SDK_NAME]: SDK_NAME
515
523
  }
516
524
  },
517
525
  // Bridge Effect context to OpenTelemetry global context
@@ -550,7 +558,9 @@ var EffectInstrumentationLive = Effect.sync(() => {
550
558
  serviceName,
551
559
  serviceVersion,
552
560
  attributes: {
553
- "platform.component": "effect"
561
+ "platform.component": "effect",
562
+ [ATTR_TELEMETRY_SDK_LANGUAGE]: TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
563
+ [ATTR_TELEMETRY_SDK_NAME]: SDK_NAME
554
564
  }
555
565
  },
556
566
  // CRITICAL: Bridge Effect context to OpenTelemetry global context
@@ -569,25 +579,144 @@ var EffectInstrumentationLive = Effect.sync(() => {
569
579
  }
570
580
  }).pipe(Layer.provide(FetchHttpClient.layer));
571
581
  }).pipe(Layer.unwrapEffect);
572
-
573
- // src/integrations/effect/effect-helpers.ts
574
- function annotateUser(_userId, _email) {
582
+ function annotateUser(userId, email, username) {
583
+ const attributes = {
584
+ "user.id": userId
585
+ };
586
+ if (email) attributes["user.email"] = email;
587
+ if (username) attributes["user.name"] = username;
588
+ return Effect.annotateCurrentSpan(attributes);
589
+ }
590
+ function annotateDataSize(bytes, items, compressionRatio) {
591
+ const attributes = {
592
+ "data.size.bytes": bytes,
593
+ "data.size.items": items
594
+ };
595
+ if (compressionRatio !== void 0) {
596
+ attributes["data.compression.ratio"] = compressionRatio;
597
+ }
598
+ return Effect.annotateCurrentSpan(attributes);
575
599
  }
576
- function annotateDataSize(_bytes, _count) {
600
+ function annotateBatch(totalItems, batchSize, successCount, failureCount) {
601
+ const attributes = {
602
+ "batch.size": batchSize,
603
+ "batch.total_items": totalItems,
604
+ "batch.count": Math.ceil(totalItems / batchSize)
605
+ };
606
+ if (successCount !== void 0) {
607
+ attributes["batch.success_count"] = successCount;
608
+ }
609
+ if (failureCount !== void 0) {
610
+ attributes["batch.failure_count"] = failureCount;
611
+ }
612
+ return Effect.annotateCurrentSpan(attributes);
577
613
  }
578
- function annotateBatch(_size, _batchSize) {
614
+ function annotateLLM(model, provider, tokens) {
615
+ const attributes = {
616
+ "llm.model": model,
617
+ "llm.provider": provider
618
+ };
619
+ if (tokens) {
620
+ if (tokens.prompt !== void 0) attributes["llm.tokens.prompt"] = tokens.prompt;
621
+ if (tokens.completion !== void 0) attributes["llm.tokens.completion"] = tokens.completion;
622
+ if (tokens.total !== void 0) attributes["llm.tokens.total"] = tokens.total;
623
+ }
624
+ return Effect.annotateCurrentSpan(attributes);
579
625
  }
580
- function annotateLLM(_model, _operation, _inputTokens, _outputTokens) {
626
+ function annotateQuery(query, duration, rowCount, database) {
627
+ const attributes = {
628
+ "db.statement": query.length > 1e3 ? query.substring(0, 1e3) + "..." : query
629
+ };
630
+ if (duration !== void 0) attributes["db.duration.ms"] = duration;
631
+ if (rowCount !== void 0) attributes["db.row_count"] = rowCount;
632
+ if (database) attributes["db.name"] = database;
633
+ return Effect.annotateCurrentSpan(attributes);
581
634
  }
582
- function annotateQuery(_query, _database) {
635
+ function annotateHttpRequest(method, url, statusCode, contentLength) {
636
+ const attributes = {
637
+ "http.method": method,
638
+ "http.url": url
639
+ };
640
+ if (statusCode !== void 0) attributes["http.status_code"] = statusCode;
641
+ if (contentLength !== void 0) attributes["http.response.content_length"] = contentLength;
642
+ return Effect.annotateCurrentSpan(attributes);
583
643
  }
584
- function annotateHttpRequest(_method, _url, _statusCode) {
644
+ function annotateError(error, recoverable, errorType) {
645
+ const errorMessage = typeof error === "string" ? error : error.message;
646
+ const errorStack = typeof error === "string" ? void 0 : error.stack;
647
+ const attributes = {
648
+ "error.message": errorMessage,
649
+ "error.recoverable": recoverable
650
+ };
651
+ if (errorType) attributes["error.type"] = errorType;
652
+ if (errorStack) attributes["error.stack"] = errorStack;
653
+ return Effect.annotateCurrentSpan(attributes);
585
654
  }
586
- function annotateError(_error, _context) {
655
+ function annotatePriority(priority, reason) {
656
+ const attributes = {
657
+ "operation.priority": priority
658
+ };
659
+ if (reason) attributes["operation.priority.reason"] = reason;
660
+ return Effect.annotateCurrentSpan(attributes);
587
661
  }
588
- function annotatePriority(_priority) {
662
+ function annotateCache(hit, key, ttl) {
663
+ const attributes = {
664
+ "cache.hit": hit,
665
+ "cache.key": key
666
+ };
667
+ if (ttl !== void 0) attributes["cache.ttl.seconds"] = ttl;
668
+ return Effect.annotateCurrentSpan(attributes);
589
669
  }
590
- function annotateCache(_operation, _hit) {
670
+ function extractEffectMetadata() {
671
+ return Effect.gen(function* () {
672
+ const metadata = {};
673
+ const currentFiber = Fiber.getCurrentFiber();
674
+ if (Option.isSome(currentFiber)) {
675
+ const fiber = currentFiber.value;
676
+ const fiberId = fiber.id();
677
+ metadata["effect.fiber.id"] = FiberId.threadName(fiberId);
678
+ const status = yield* Fiber.status(fiber);
679
+ if (status._tag) {
680
+ metadata["effect.fiber.status"] = status._tag;
681
+ }
682
+ }
683
+ const parentSpanResult = yield* Effect.currentSpan.pipe(
684
+ Effect.option
685
+ // Convert NoSuchElementException to Option
686
+ );
687
+ if (Option.isSome(parentSpanResult)) {
688
+ const parentSpan = parentSpanResult.value;
689
+ metadata["effect.operation.nested"] = true;
690
+ metadata["effect.operation.root"] = false;
691
+ if (parentSpan.spanId) {
692
+ metadata["effect.parent.span.id"] = parentSpan.spanId;
693
+ }
694
+ if (parentSpan.name) {
695
+ metadata["effect.parent.span.name"] = parentSpan.name;
696
+ }
697
+ if (parentSpan.traceId) {
698
+ metadata["effect.parent.trace.id"] = parentSpan.traceId;
699
+ }
700
+ } else {
701
+ metadata["effect.operation.nested"] = false;
702
+ metadata["effect.operation.root"] = true;
703
+ }
704
+ return metadata;
705
+ });
706
+ }
707
+ function autoEnrichSpan() {
708
+ return Effect.gen(function* () {
709
+ const metadata = yield* extractEffectMetadata();
710
+ yield* Effect.annotateCurrentSpan(metadata);
711
+ });
712
+ }
713
+ function withAutoEnrichedSpan(spanName, options) {
714
+ return (self) => {
715
+ return Effect.gen(function* () {
716
+ yield* autoEnrichSpan();
717
+ return yield* self;
718
+ }).pipe(Effect.withSpan(spanName, options));
719
+ };
591
720
  }
592
721
  var createLogicalParentLink = (parentSpan, useSpanLinks) => {
593
722
  if (!useSpanLinks) {
@@ -714,6 +843,6 @@ var FiberSet = {
714
843
  runWithSpan
715
844
  };
716
845
 
717
- export { EffectInstrumentationLive, FiberSet, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, createEffectInstrumentation, runIsolated, runWithSpan };
846
+ export { EffectInstrumentationLive, FiberSet, annotateBatch, annotateCache, annotateDataSize, annotateError, annotateHttpRequest, annotateLLM, annotatePriority, annotateQuery, annotateSpawnedTasks, annotateUser, autoEnrichSpan, createEffectInstrumentation, extractEffectMetadata, runIsolated, runWithSpan, withAutoEnrichedSpan };
718
847
  //# sourceMappingURL=index.js.map
719
848
  //# sourceMappingURL=index.js.map