@atrim/instrument-node 0.8.1-dev.ae570af.20260116212440 → 0.9.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.
@@ -1,359 +1,8 @@
1
- import { Layer, Supervisor, Effect, Context, Option, Fiber, Exit, FiberRef } from 'effect';
2
- import * as OtelApi from '@opentelemetry/api';
3
- import { AutoInstrumentationConfig, InstrumentationConfig } from '@atrim/instrument-core';
1
+ import { Context, Layer, Effect, FiberRef, Option, Supervisor, Fiber, Exit } from 'effect';
2
+ import { InstrumentationConfig, AutoInstrumentationConfig } from '@atrim/instrument-core';
4
3
  export { AutoInstrumentationConfig } from '@atrim/instrument-core';
5
4
  import * as effect_Fiber from 'effect/Fiber';
6
5
 
7
- /**
8
- * Effect-Native Tracing Layer
9
- *
10
- * Uses @effect/opentelemetry's NodeSdk.layer for proper Effect integration.
11
- * This provides automatic HTTP request tracing and Effect.withSpan() support.
12
- *
13
- * Requires @effect/opentelemetry peer dependency to be installed.
14
- */
15
-
16
- /**
17
- * Create a layer that provides Effect-native tracing via NodeSdk.layer
18
- *
19
- * This integrates with Effect's built-in tracing system, which means:
20
- * - HTTP requests are automatically traced by @effect/platform
21
- * - Effect.withSpan() creates proper OTel spans
22
- * - Parent-child span relationships work correctly
23
- * - No need to fork fibers for tracing to work
24
- *
25
- * Configuration is loaded from instrumentation.yaml (exporter_config section).
26
- *
27
- * @example
28
- * ```typescript
29
- * import { EffectTracingLive } from '@atrim/instrument-node/effect/auto'
30
- *
31
- * // HTTP requests automatically traced!
32
- * const HttpLive = router.pipe(
33
- * HttpServer.serve(),
34
- * Layer.provide(ServerLive),
35
- * Layer.provide(EffectTracingLive),
36
- * )
37
- * ```
38
- */
39
- declare const createEffectTracingLayer: () => Layer.Layer<never>;
40
- /**
41
- * Effect-native tracing layer using @effect/opentelemetry
42
- *
43
- * This is the **recommended** layer for Effect HTTP applications. It provides:
44
- * - Automatic HTTP request tracing (built into @effect/platform)
45
- * - Full Effect.withSpan() support for manual spans
46
- * - Proper parent-child span relationships
47
- * - No need to fork fibers manually
48
- *
49
- * Configuration is loaded from your instrumentation.yaml file.
50
- *
51
- * @example
52
- * ```yaml
53
- * # instrumentation.yaml
54
- * effect:
55
- * exporter_config:
56
- * type: otlp # or 'console' for dev
57
- * endpoint: http://localhost:4318
58
- * headers:
59
- * x-api-key: your-key
60
- * processor: batch # or 'simple' for immediate export
61
- * ```
62
- *
63
- * @example
64
- * ```typescript
65
- * import { EffectTracingLive } from '@atrim/instrument-node/effect/auto'
66
- * import { HttpRouter, HttpServer } from "@effect/platform"
67
- * import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
68
- *
69
- * const router = HttpRouter.empty.pipe(
70
- * HttpRouter.get("/", Effect.succeed(HttpServerResponse.text("Hello!"))),
71
- * )
72
- *
73
- * const HttpLive = router.pipe(
74
- * HttpServer.serve(),
75
- * Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })),
76
- * Layer.provide(EffectTracingLive), // <- Just add this!
77
- * )
78
- *
79
- * NodeRuntime.runMain(Layer.launch(HttpLive))
80
- * // All HTTP requests now automatically traced!
81
- * ```
82
- */
83
- declare const EffectTracingLive: Layer.Layer<never>;
84
- /**
85
- * Create a combined layer that provides both:
86
- * 1. Effect-native HTTP tracing (via Effect's Tracer + global OTel provider)
87
- * 2. Fiber-level auto-tracing (via Supervisor)
88
- *
89
- * This gives you automatic spans for:
90
- * - Every HTTP request (from Effect's platform middleware)
91
- * - Every forked fiber (from our Supervisor)
92
- *
93
- * No manual Effect.withSpan() calls needed.
94
- *
95
- * ARCHITECTURE NOTE:
96
- * Unlike EffectTracingLive which uses NodeSdk.layer (scoped provider),
97
- * CombinedTracingLive uses a single GLOBAL TracerProvider so that both
98
- * Effect's Tracer and our Supervisor use the same provider and exporter.
99
- *
100
- * This solves the dual-provider problem where HTTP spans and fiber spans
101
- * would otherwise go to different exporters.
102
- */
103
- declare const createCombinedTracingLayer: () => Layer.Layer<never>;
104
- /**
105
- * Combined tracing layer providing both HTTP and fiber-level auto-tracing
106
- *
107
- * This is the **most comprehensive** tracing option. You get automatic spans for:
108
- * - Every HTTP request (from Effect's @effect/platform middleware)
109
- * - Every forked fiber (from our Supervisor)
110
- *
111
- * No manual Effect.withSpan() calls needed - everything is traced automatically.
112
- *
113
- * @example
114
- * ```yaml
115
- * # instrumentation.yaml
116
- * effect:
117
- * auto_instrumentation:
118
- * enabled: true
119
- * granularity: fiber
120
- * exporter_config:
121
- * type: otlp
122
- * endpoint: http://localhost:4318
123
- * ```
124
- *
125
- * @example
126
- * ```typescript
127
- * import { CombinedTracingLive } from '@atrim/instrument-node/effect/auto'
128
- *
129
- * const HttpLive = router.pipe(
130
- * HttpServer.serve(),
131
- * Layer.provide(ServerLive),
132
- * Layer.provide(CombinedTracingLive),
133
- * )
134
- *
135
- * // Both HTTP requests AND forked fibers are auto-traced!
136
- * ```
137
- */
138
- declare const CombinedTracingLive: Layer.Layer<never>;
139
-
140
- /**
141
- * Auto-Tracing Supervisor for Effect-TS
142
- *
143
- * Provides automatic tracing of all Effect fibers without manual Effect.withSpan() calls.
144
- * Uses Effect's Supervisor API to intercept fiber creation/termination and create
145
- * OpenTelemetry spans automatically.
146
- *
147
- * @example
148
- * ```typescript
149
- * import { AutoTracingLive } from '@atrim/instrument-node/effect/auto'
150
- *
151
- * const program = Effect.gen(function* () {
152
- * yield* doWork() // Automatically traced!
153
- * }).pipe(Effect.provide(AutoTracingLive))
154
- * ```
155
- */
156
-
157
- /**
158
- * FiberRef to enable/disable auto-tracing for specific fibers
159
- * Use withoutAutoTracing() to disable
160
- */
161
- declare const AutoTracingEnabled: FiberRef.FiberRef<boolean>;
162
- /**
163
- * FiberRef to override auto-generated span name
164
- * Use setSpanName() to override
165
- */
166
- declare const AutoTracingSpanName: FiberRef.FiberRef<Option.Option<string>>;
167
- /**
168
- * Supervisor that automatically creates OpenTelemetry spans for all Effect fibers
169
- *
170
- * This supervisor intercepts fiber creation and termination, creating spans
171
- * based on configuration from instrumentation.yaml.
172
- */
173
- declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void> {
174
- private readonly config;
175
- private readonly fiberSpans;
176
- private readonly fiberStartTimes;
177
- private _tracer;
178
- private readonly tracerProvider;
179
- private readonly includePatterns;
180
- private readonly excludePatterns;
181
- private activeFiberCount;
182
- private _rootSpan;
183
- constructor(config: AutoInstrumentationConfig, tracerProvider?: OtelApi.TracerProvider);
184
- /**
185
- * Set the root span for parent context propagation
186
- */
187
- setRootSpan(span: OtelApi.Span): void;
188
- /**
189
- * Get the tracer lazily - uses provided TracerProvider if available, otherwise uses global
190
- */
191
- private get tracer();
192
- /**
193
- * Returns the current value (void for this supervisor)
194
- */
195
- get value(): Effect.Effect<void>;
196
- /**
197
- * Called when a fiber starts executing
198
- */
199
- onStart<A, E, R>(_context: Context.Context<R>, _effect: Effect.Effect<A, E, R>, parent: Option.Option<Fiber.RuntimeFiber<unknown, unknown>>, fiber: Fiber.RuntimeFiber<A, E>): void;
200
- /**
201
- * Called when a fiber completes (success or failure)
202
- */
203
- onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
204
- /**
205
- * Get attributes for span links from config
206
- */
207
- private getLinkAttributes;
208
- /**
209
- * Check if a span name should be traced based on filter patterns
210
- */
211
- private shouldTrace;
212
- /**
213
- * Get initial span attributes for a fiber
214
- */
215
- private getInitialAttributes;
216
- /**
217
- * Parse stack trace to get source info
218
- */
219
- private parseStackTrace;
220
- /**
221
- * Parse min_duration string to nanoseconds
222
- */
223
- private parseMinDuration;
224
- }
225
- /**
226
- * Create a custom AutoTracingSupervisor with the given config
227
- */
228
- declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig, tracerProvider?: OtelApi.TracerProvider) => AutoTracingSupervisor;
229
- /**
230
- * Layer that provides auto-tracing with custom configuration
231
- *
232
- * @example
233
- * ```typescript
234
- * const CustomAutoTracing = createAutoTracingLayer({
235
- * enabled: true,
236
- * span_naming: {
237
- * default: 'app.{function}',
238
- * rules: [{ match: { file: 'src/services/.*' }, name: 'service.{function}' }]
239
- * }
240
- * })
241
- * ```
242
- */
243
- declare const createAutoTracingLayer: (options?: {
244
- config?: AutoInstrumentationConfig;
245
- }) => Layer.Layer<never>;
246
- /**
247
- * Wrap an Effect with auto-tracing supervision
248
- *
249
- * This creates a span for the main effect AND supervises all child fibers.
250
- * Use this when you need to ensure all fibers in an effect are traced.
251
- *
252
- * @example
253
- * ```typescript
254
- * const program = Effect.gen(function* () {
255
- * yield* doWork() // Automatically traced!
256
- * })
257
- *
258
- * const tracedProgram = withAutoTracing(program, { enabled: true, ... })
259
- * Effect.runPromise(tracedProgram)
260
- * ```
261
- */
262
- declare const withAutoTracing: <A, E, R>(effect: Effect.Effect<A, E, R>, config: AutoInstrumentationConfig, mainSpanName?: string) => Effect.Effect<A, E, R>;
263
- /**
264
- * Zero-config auto-tracing layer
265
- *
266
- * Loads configuration from instrumentation.yaml and automatically traces
267
- * all Effect fibers based on the configuration.
268
- *
269
- * @example
270
- * ```typescript
271
- * import { AutoTracingLive } from '@atrim/instrument-node/effect/auto'
272
- *
273
- * const program = Effect.gen(function* () {
274
- * yield* doWork() // Automatically traced!
275
- * }).pipe(Effect.provide(AutoTracingLive))
276
- * ```
277
- */
278
- declare const AutoTracingLive: Layer.Layer<never>;
279
- /**
280
- * Disable auto-tracing for a specific Effect
281
- *
282
- * @example
283
- * ```typescript
284
- * const program = Effect.gen(function* () {
285
- * yield* publicWork() // Traced
286
- * yield* withoutAutoTracing(internalWork()) // NOT traced
287
- * })
288
- * ```
289
- */
290
- declare const withoutAutoTracing: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
291
- /**
292
- * Override the auto-generated span name for a specific Effect
293
- *
294
- * @example
295
- * ```typescript
296
- * const program = Effect.gen(function* () {
297
- * yield* setSpanName('custom.operation.name')(myEffect)
298
- * })
299
- * ```
300
- */
301
- declare const setSpanName: (name: string) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
302
- /**
303
- * Create a fully YAML-driven auto-instrumentation layer
304
- *
305
- * This layer reads all configuration from instrumentation.yaml including:
306
- * - Exporter configuration (type, endpoint, processor)
307
- * - Auto-tracing configuration (naming rules, filters, performance)
308
- * - Service metadata (name, version)
309
- *
310
- * @example
311
- * ```typescript
312
- * import { createFullAutoTracingLayer } from '@atrim/instrument-node/effect/auto'
313
- *
314
- * // Everything configured via instrumentation.yaml - no code config needed!
315
- * const AppLive = createFullAutoTracingLayer()
316
- *
317
- * Effect.runPromise(program.pipe(Effect.provide(AppLive)))
318
- * ```
319
- */
320
- declare const createFullAutoTracingLayer: () => Layer.Layer<never>;
321
- /**
322
- * Fully YAML-driven auto-instrumentation layer
323
- *
324
- * This is the recommended way to use auto-instrumentation. All configuration
325
- * comes from instrumentation.yaml - no code configuration needed.
326
- *
327
- * @example
328
- * ```yaml
329
- * # instrumentation.yaml
330
- * effect:
331
- * auto_instrumentation:
332
- * enabled: true
333
- * span_naming:
334
- * default: "effect.{function}"
335
- * rules:
336
- * - match: { function: "internal.*" }
337
- * name: "internal.{function}"
338
- * filter:
339
- * exclude:
340
- * - "^internal\\."
341
- * exporter_config:
342
- * type: otlp # or 'console' for dev
343
- * endpoint: http://localhost:4318
344
- * processor: batch # or 'simple' for dev
345
- * ```
346
- *
347
- * @example
348
- * ```typescript
349
- * import { FullAutoTracingLive } from '@atrim/instrument-node/effect/auto'
350
- *
351
- * // Just provide the layer - everything else from YAML!
352
- * Effect.runPromise(program.pipe(Effect.provide(FullAutoTracingLive)))
353
- * ```
354
- */
355
- declare const FullAutoTracingLive: Layer.Layer<never>;
356
-
357
6
  /**
358
7
  * Node.js configuration loader
359
8
  *
@@ -383,11 +32,11 @@ interface ConfigLoaderOptions {
383
32
  */
384
33
  declare const defaultAutoTracingConfig: AutoInstrumentationConfig;
385
34
  declare const AutoTracingConfig_base: Context.TagClass<AutoTracingConfig, "AutoTracingConfig", {
35
+ enabled: boolean;
386
36
  filter: {
387
37
  include: string[];
388
38
  exclude: string[];
389
39
  };
390
- enabled: boolean;
391
40
  granularity: "fiber" | "operator";
392
41
  span_naming: {
393
42
  default: string;
@@ -402,7 +51,7 @@ declare const AutoTracingConfig_base: Context.TagClass<AutoTracingConfig, "AutoT
402
51
  }[];
403
52
  };
404
53
  span_relationships: {
405
- type: "both" | "parent-child" | "span-links";
54
+ type: "parent-child" | "span-links" | "both";
406
55
  link_attributes?: {
407
56
  "link.type": string;
408
57
  custom?: Record<string, string> | undefined;
@@ -446,6 +95,188 @@ declare const AutoTracingConfigLive: Layer.Layer<AutoTracingConfig, never, never
446
95
  * Layer that provides custom auto-tracing configuration
447
96
  */
448
97
  declare const AutoTracingConfigLayer: (config: AutoInstrumentationConfig) => Layer.Layer<AutoTracingConfig>;
98
+ /**
99
+ * Load the full instrumentation config synchronously
100
+ *
101
+ * This is needed for layers that cannot use Layer.unwrapEffect (which breaks
102
+ * tracer propagation). Falls back to default config if file doesn't exist.
103
+ */
104
+ declare const loadFullConfigSync: () => InstrumentationConfig;
105
+
106
+ /**
107
+ * Span Control FiberRefs for Effect-TS Tracing
108
+ *
109
+ * Provides FiberRefs that control span creation behavior. These can be used to:
110
+ * - Disable auto-tracing for specific fibers/effects
111
+ * - Override auto-generated span names
112
+ *
113
+ * These FiberRefs are checked by the UnifiedTracingSupervisor during span creation.
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * import { withoutAutoTracing, setSpanName } from '@atrim/instrument-node/effect/auto'
118
+ *
119
+ * const program = Effect.gen(function* () {
120
+ * // Automatically traced
121
+ * yield* publicWork()
122
+ *
123
+ * // Opt-out of tracing
124
+ * yield* withoutAutoTracing(internalWork())
125
+ *
126
+ * // Custom span name
127
+ * yield* setSpanName('custom.operation')(criticalWork())
128
+ * }).pipe(withUnifiedTracing)
129
+ * ```
130
+ */
131
+
132
+ /**
133
+ * FiberRef to enable/disable auto-tracing for specific fibers.
134
+ *
135
+ * When set to `false`, the UnifiedTracingSupervisor will skip span creation
136
+ * for the fiber and its children (unless they override it back to `true`).
137
+ *
138
+ * Default: `true` (auto-tracing enabled)
139
+ */
140
+ declare const AutoTracingEnabled: FiberRef.FiberRef<boolean>;
141
+ /**
142
+ * FiberRef to override the auto-generated span name.
143
+ *
144
+ * When set to `Some(name)`, the UnifiedTracingSupervisor will use this name
145
+ * instead of inferring it from source location.
146
+ *
147
+ * Default: `None` (use inferred name)
148
+ */
149
+ declare const AutoTracingSpanName: FiberRef.FiberRef<Option.Option<string>>;
150
+ /**
151
+ * Disable auto-tracing for a specific Effect.
152
+ *
153
+ * Use this to opt-out of automatic span creation for internal operations
154
+ * that don't need to be traced.
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const program = Effect.gen(function* () {
159
+ * yield* publicWork() // Traced
160
+ * yield* withoutAutoTracing(internalWork()) // NOT traced
161
+ * })
162
+ * ```
163
+ */
164
+ declare const withoutAutoTracing: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
165
+ /**
166
+ * Override the auto-generated span name for a specific Effect.
167
+ *
168
+ * Use this when you want a custom span name instead of the inferred one.
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const program = Effect.gen(function* () {
173
+ * yield* setSpanName('custom.operation.name')(myEffect)
174
+ * })
175
+ * ```
176
+ */
177
+ declare const setSpanName: (name: string) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
178
+
179
+ /**
180
+ * Unified Tracing Supervisor for Effect-TS
181
+ *
182
+ * Combines operation tracing (Effect.all, Effect.forEach, Effect.fork) with
183
+ * fiber-level tracing, ensuring correct parent-child span relationships.
184
+ *
185
+ * Key feature: Fork spans are correctly set as parents of their resulting fiber spans.
186
+ *
187
+ * Requires the @clayroach/effect fork with OperationMeta and source capture support.
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * import { withUnifiedTracing } from '@atrim/instrument-node/effect/auto'
192
+ *
193
+ * const program = Effect.gen(function* () {
194
+ * // Creates spans: effect.all -> child fiber spans
195
+ * yield* Effect.all([doA(), doB()])
196
+ *
197
+ * // Creates spans: effect.fork -> forked fiber span (correct hierarchy!)
198
+ * yield* Effect.fork(backgroundTask())
199
+ * }).pipe(withUnifiedTracing)
200
+ * ```
201
+ */
202
+
203
+ /**
204
+ * Operation metadata stored in the trace field by Effect.all, Effect.forEach, etc.
205
+ */
206
+ interface OperationMeta {
207
+ readonly _tag: 'OperationMeta';
208
+ readonly op: string;
209
+ readonly count?: number;
210
+ readonly capturedAt: string;
211
+ }
212
+ /**
213
+ * Unified supervisor that handles both operation tracing and fiber tracing,
214
+ * ensuring correct parent-child relationships for fork spans.
215
+ */
216
+ declare class UnifiedTracingSupervisor extends Supervisor.AbstractSupervisor<void> {
217
+ private readonly config;
218
+ private readonly pendingForkSpans;
219
+ private readonly fiberSpans;
220
+ private readonly fiberContexts;
221
+ private readonly fiberStartTimes;
222
+ private readonly processedEffects;
223
+ private readonly configuredOps;
224
+ private _tracer;
225
+ private activeFiberCount;
226
+ constructor(config: AutoInstrumentationConfig);
227
+ private get tracer();
228
+ get value(): Effect.Effect<void>;
229
+ onEffect<A, E>(fiber: Fiber.RuntimeFiber<A, E>, effect: Effect.Effect<unknown, unknown, unknown>): void;
230
+ onStart<A, E, R>(_context: Context.Context<R>, _effect: Effect.Effect<A, E, R>, parent: Option.Option<Fiber.RuntimeFiber<unknown, unknown>>, fiber: Fiber.RuntimeFiber<A, E>): void;
231
+ onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
232
+ private cleanup;
233
+ private resolveParentContext;
234
+ private resolveParentContextFromFiberRefs;
235
+ private parseMinDuration;
236
+ }
237
+ /**
238
+ * Create the UnifiedTracingLive layer
239
+ */
240
+ declare const createUnifiedTracingLayer: () => Layer.Layer<never>;
241
+ /**
242
+ * Unified Tracing Layer - combines operation and fiber tracing with correct hierarchy
243
+ *
244
+ * NOTE: Uses Layer.suspend to defer provider setup until the layer is actually used.
245
+ * This prevents the global TracerProvider from being set at module import time,
246
+ * allowing tests to set up their own provider first.
247
+ */
248
+ declare const UnifiedTracingLive: Layer.Layer<never>;
249
+ /**
250
+ * Helper to enable OpSupervision runtime flag
251
+ */
252
+ declare const enableOpSupervision: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
253
+ /**
254
+ * Wrap an effect with unified tracing (OpSupervision + layer)
255
+ *
256
+ * @example
257
+ * ```typescript
258
+ * const program = Effect.gen(function* () {
259
+ * yield* Effect.fork(myTask()) // Fork span is parent of fiber span!
260
+ * }).pipe(withUnifiedTracing)
261
+ * ```
262
+ */
263
+ declare const withUnifiedTracing: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, never>>;
264
+ /**
265
+ * Wrap an effect with auto-tracing using a custom config
266
+ *
267
+ * This is the legacy API for backward compatibility. It allows passing a custom
268
+ * config and optional root span name.
269
+ *
270
+ * @deprecated Use `withUnifiedTracing` with `UnifiedTracingLive` layer instead.
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * const result = await Effect.runPromise(withAutoTracing(program, config, 'my-root-span'))
275
+ * ```
276
+ */
277
+ declare const withAutoTracing: <A, E, R>(effect: Effect.Effect<A, E, R>, config?: AutoInstrumentationConfig, rootSpanName?: string) => Effect.Effect<A, E, R>;
278
+ declare const flushAndShutdown: () => Promise<void>;
279
+ declare const forceFlush: () => Promise<void>;
449
280
 
450
281
  /**
451
282
  * Span Name Inference for Auto-Tracing
@@ -590,306 +421,8 @@ declare function patchEffectFork(): void;
590
421
  declare function unpatchEffectFork(): void;
591
422
 
592
423
  /**
593
- * Source Capture Supervisor for Effect-TS (POC)
594
- *
595
- * Uses Effect's native source capture feature (from @clayroach/effect@3.19.14-source-capture.0)
596
- * to automatically capture call-site locations when fibers are forked.
597
- *
598
- * This is the POC implementation for issue #145:
599
- * https://github.com/atrim-ai/instrumentation/issues/145
600
- *
601
- * @example
602
- * ```typescript
603
- * import { SourceCaptureTracingLive } from '@atrim/instrument-node/effect/auto'
604
- *
605
- * const program = Effect.gen(function* () {
606
- * yield* Effect.fork(doWork()) // Automatically traced with source location!
607
- * }).pipe(Effect.provide(SourceCaptureTracingLive))
608
- *
609
- * // Span name will be "effect.sendEmail (user-handlers.ts:42)" instead of "effect.anonymous"
610
- * ```
611
- */
612
-
613
- /**
614
- * Supervisor that uses Effect's native source capture to create spans with
615
- * meaningful names based on the actual call site of Effect.fork().
616
- *
617
- * This supervisor reads from `currentSourceLocation` FiberRef which is
618
- * populated automatically by Effect when source capture is enabled via
619
- * `Layer.enableSourceCapture` or `Effect.withCaptureStackTraces(true)`.
620
- */
621
- declare class SourceCaptureSupervisor extends Supervisor.AbstractSupervisor<void> {
622
- private readonly config;
623
- private readonly fiberSpans;
624
- private readonly fiberContexts;
625
- private readonly fiberStartTimes;
626
- private _tracer;
627
- private activeFiberCount;
628
- private _rootSpan;
629
- constructor(config: AutoInstrumentationConfig);
630
- /**
631
- * Set the default root span for auto-instrumentation.
632
- * Fibers without a ParentSpan will use this as their parent.
633
- */
634
- setRootSpan(span: OtelApi.Span): void;
635
- /**
636
- * Get the root span (if set)
637
- */
638
- get rootSpan(): OtelApi.Span | null;
639
- /**
640
- * Get the tracer lazily from global OTel API
641
- */
642
- private get tracer();
643
- /**
644
- * Returns the current value (void for this supervisor)
645
- */
646
- get value(): Effect.Effect<void>;
647
- /**
648
- * Called when a fiber starts executing
649
- */
650
- onStart<A, E, R>(_context: Context.Context<R>, _effect: Effect.Effect<A, E, R>, parent: Option.Option<Fiber.RuntimeFiber<unknown, unknown>>, fiber: Fiber.RuntimeFiber<A, E>): void;
651
- /**
652
- * Called when a fiber completes (success or failure)
653
- */
654
- onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
655
- /**
656
- * Parse min_duration string to nanoseconds
657
- */
658
- private parseMinDuration;
659
- }
660
- /**
661
- * Create the SourceCaptureTracingLive layer
662
- *
663
- * This layer:
664
- * 1. Enables Effect's native source capture via Layer.enableSourceCapture
665
- * 2. Uses the global TracerProvider (set at module load time)
666
- * 3. Adds the SourceCaptureSupervisor that reads native source locations
667
- *
668
- * The key difference from CombinedTracingLive is that this uses Effect's
669
- * NATIVE source capture instead of our manual tracedFork() workaround.
670
- */
671
- declare const createSourceCaptureTracingLayer: () => Layer.Layer<never>;
672
- /**
673
- * Native Source Capture Tracing Layer (POC for issue #145)
674
- *
675
- * This layer uses Effect's NATIVE source capture feature to automatically
676
- * capture call-site locations when fibers are forked. No more need for
677
- * manual `tracedFork()` calls!
678
- *
679
- * **Key difference from CombinedTracingLive:**
680
- * - CombinedTracingLive: Requires `tracedFork()` wrapper for source capture
681
- * - SourceCaptureTracingLive: Uses Effect's native source capture (no wrappers!)
682
- *
683
- * @example
684
- * ```yaml
685
- * # instrumentation.yaml
686
- * effect:
687
- * auto_instrumentation:
688
- * enabled: true
689
- * exporter_config:
690
- * type: console # or 'otlp'
691
- * ```
692
- *
693
- * @example
694
- * ```typescript
695
- * import { SourceCaptureTracingLive } from '@atrim/instrument-node/effect/auto'
696
- *
697
- * const program = Effect.gen(function* () {
698
- * // Just use regular Effect.fork() - no wrapper needed!
699
- * yield* Effect.fork(sendEmail()) // Span: "effect.sendEmail (user-handlers.ts:42)"
700
- * yield* Effect.fork(processOrder()) // Span: "effect.processOrder (order-service.ts:18)"
701
- * }).pipe(Effect.provide(SourceCaptureTracingLive))
702
- *
703
- * Effect.runPromise(program)
704
- * ```
705
- */
706
- declare const SourceCaptureTracingLive: Layer.Layer<never>;
707
- /**
708
- * Disable source capture for a hot path (opt-out)
709
- *
710
- * Use this to disable source capture for performance-critical code paths
711
- * where the ~0.001ms overhead is unacceptable.
712
- */
713
- declare const withoutSourceCapture: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
714
- /**
715
- * Flush all pending spans and shutdown the TracerProvider.
716
- * Call this before your application exits to ensure all spans are exported.
717
- *
718
- * @example
719
- * ```typescript
720
- * import { flushAndShutdown } from '@atrim/instrument-node/effect/auto'
721
- *
722
- * // At the end of your application
723
- * await flushAndShutdown()
724
- * process.exit(0)
725
- * ```
726
- */
727
- declare const flushAndShutdown: () => Promise<void>;
728
- /**
729
- * Force flush all pending spans without shutting down.
730
- * Use this if you need to ensure spans are exported but want to continue tracing.
731
- */
732
- declare const forceFlush: () => Promise<void>;
733
-
734
- /**
735
- * Operation Tracing Supervisor for Effect-TS
736
- *
737
- * Uses OpSupervision to trace high-level Effect operations like Effect.all,
738
- * Effect.forEach, etc. This supervisor reads operation metadata from the
739
- * `trace` field that Effect populates when operations are created.
740
- *
741
- * Requires the @clayroach/effect fork which adds OperationMeta to the trace field.
742
- *
743
- * The `OperationTracingLive` layer automatically enables the OpSupervision runtime
744
- * flag, so no additional configuration is needed.
745
- *
746
- * @example
747
- * ```typescript
748
- * import { OperationTracingLive } from '@atrim/instrument-node/effect/auto'
749
- *
750
- * const program = Effect.gen(function* () {
751
- * // Automatically traced with span "effect.all" including item count
752
- * yield* Effect.all([doA(), doB(), doC()])
753
- *
754
- * // Automatically traced with span "effect.forEach"
755
- * yield* Effect.forEach(items, processItem)
756
- * }).pipe(Effect.provide(OperationTracingLive))
757
- * ```
758
- */
759
-
760
- /**
761
- * Operation metadata stored in the trace field by Effect.all, Effect.forEach, etc.
762
- * This matches the OperationMeta interface in the Effect fork's core.ts
763
- */
764
- interface OperationMeta {
765
- readonly _tag: 'OperationMeta';
766
- readonly op: string;
767
- readonly count?: number;
768
- readonly capturedAt: string;
769
- }
770
- /**
771
- * Global span naming configuration for operation tracing
772
- */
773
- interface SpanNamingConfig {
774
- /** Include source location in span name (default: true) */
775
- readonly includeLocation: boolean;
776
- /** Span name template with variables: {op}, {file}, {filename}, {line}, {column} */
777
- readonly template: string;
778
- }
779
- /**
780
- * Configuration for which operations to trace
781
- */
782
- interface OperationConfig {
783
- readonly name: string;
784
- readonly spanNameTemplate?: string;
785
- readonly includeCount?: boolean;
786
- readonly includeStack?: boolean;
787
- }
788
- /**
789
- * Supervisor that traces Effect operations using OpSupervision.
790
- *
791
- * When OpSupervision is enabled, the Effect runtime calls `onEffect(fiber, effect)`
792
- * for every Effect operation in the runLoop. This supervisor checks if the effect
793
- * has OperationMeta in its trace field and creates spans accordingly.
794
- */
795
- declare class OperationTracingSupervisor extends Supervisor.AbstractSupervisor<void> {
796
- private readonly configuredOps;
797
- private readonly spanNaming;
798
- private readonly processedEffects;
799
- private readonly fiberSpans;
800
- private _tracer;
801
- constructor(operations: OperationConfig[], spanNaming?: SpanNamingConfig);
802
- /**
803
- * Get the tracer lazily from global OTel API
804
- */
805
- private get tracer();
806
- /**
807
- * Returns the current value (void for this supervisor)
808
- */
809
- get value(): Effect.Effect<void>;
810
- /**
811
- * Called for EVERY Effect operation when OpSupervision is enabled.
812
- *
813
- * This is the key hook for operation-level tracing. We check if the effect
814
- * has OperationMeta and create a span if configured.
815
- */
816
- onEffect<A, E>(fiber: Fiber.RuntimeFiber<A, E>, effect: Effect.Effect<unknown, unknown, unknown>): void;
817
- /**
818
- * Called when a fiber starts - we don't need this for operation tracing
819
- */
820
- onStart(): void;
821
- /**
822
- * Called when a fiber ends - end all spans for this fiber
823
- */
824
- onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
825
- }
826
- /**
827
- * Create a Layer that adds the OperationTracingSupervisor.
828
- *
829
- * NOTE: This layer adds the supervisor, but OpSupervision must also be enabled
830
- * for the runtime to call onEffect(). Use Effect.withRuntimeFlags to enable
831
- * OpSupervision, or use the enableOpSupervision helper.
832
- *
833
- * @param operations - Configuration for which operations to trace
834
- * @param spanNaming - Global span naming configuration
835
- */
836
- declare const makeOperationTracingLayer: (operations?: OperationConfig[], spanNaming?: SpanNamingConfig) => Layer.Layer<never>;
837
- /**
838
- * Helper to enable OpSupervision runtime flag for an effect.
839
- *
840
- * OpSupervision causes the runtime to call supervisor.onEffect() for every
841
- * Effect operation. This has a performance cost but enables operation-level tracing.
842
- *
843
- * @example
844
- * ```typescript
845
- * const program = myEffect.pipe(
846
- * enableOpSupervision,
847
- * Effect.provide(OperationTracingLive)
848
- * )
849
- * ```
850
- */
851
- declare const enableOpSupervision: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
852
- /**
853
- * Pre-configured layer for automatic operation tracing.
854
- *
855
- * **Zero-config by default** - Works out of the box with sensible defaults:
856
- * - Traces `Effect.all` and `Effect.forEach` operations
857
- * - Includes item count and source location in span attributes
858
- *
859
- * **Important:** You must enable OpSupervision for operation tracing to work.
860
- * Use `withOperationTracing(effect)` for the simplest setup, or manually:
861
- * `enableOpSupervision` + `Effect.provide(OperationTracingLive)`.
862
- *
863
- * @example
864
- * ```typescript
865
- * // Simplest: use withOperationTracing wrapper
866
- * const program = Effect.gen(function* () {
867
- * yield* Effect.all([doA(), doB()]) // Automatically traced
868
- * }).pipe(withOperationTracing)
869
- *
870
- * // Or manually enable OpSupervision + provide layer
871
- * const program = myEffect.pipe(
872
- * enableOpSupervision,
873
- * Effect.provide(OperationTracingLive)
874
- * )
875
- * ```
876
- */
877
- declare const OperationTracingLive: Layer.Layer<never, never, never>;
878
- /**
879
- * Convenience wrapper that enables operation tracing for an effect.
880
- *
881
- * This is the simplest way to use operation tracing - just wrap your effect:
882
- *
883
- * @example
884
- * ```typescript
885
- * const program = Effect.gen(function* () {
886
- * yield* Effect.all([doA(), doB()]) // Automatically creates "effect.all" span
887
- * yield* Effect.forEach(items, process) // Automatically creates "effect.forEach" span
888
- * }).pipe(withOperationTracing)
889
- *
890
- * Effect.runPromise(program)
891
- * ```
424
+ * @deprecated Use new UnifiedTracingSupervisor(config) instead
892
425
  */
893
- declare const withOperationTracing: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
426
+ declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig) => any;
894
427
 
895
- export { AutoTracingConfig, AutoTracingConfigLayer, AutoTracingConfigLive, AutoTracingEnabled, AutoTracingLive, AutoTracingSpanName, AutoTracingSupervisor, CapturedSourceLocation, CombinedTracingLive, EffectTracingLive, FullAutoTracingLive, type OperationConfig, type OperationMeta, OperationTracingLive, OperationTracingSupervisor, SourceCaptureSupervisor, SourceCaptureTracingLive, type SourceInfo, type TemplateVariables, captureCallSite, createAutoTracingLayer, createAutoTracingSupervisor, createCombinedTracingLayer, createEffectTracingLayer, createFullAutoTracingLayer, createSourceCaptureTracingLayer, defaultAutoTracingConfig, enableOpSupervision, flushAndShutdown, forceFlush, inferSpanName, isEffectForkPatched, loadAutoTracingConfig, loadAutoTracingConfigSync, makeOperationTracingLayer, patchEffectFork, sanitizeSpanName, setSpanName, tracedFork, tracedForkDaemon, unpatchEffectFork, withAutoTracing, withOperationTracing, withoutAutoTracing, withoutSourceCapture };
428
+ export { AutoTracingConfig, AutoTracingConfigLayer, AutoTracingConfigLive, AutoTracingEnabled, UnifiedTracingLive as AutoTracingLive, AutoTracingSpanName, UnifiedTracingSupervisor as AutoTracingSupervisor, CapturedSourceLocation, UnifiedTracingLive as CombinedTracingLive, UnifiedTracingLive as FullAutoTracingLive, type OperationMeta, UnifiedTracingLive as OperationTracingLive, UnifiedTracingSupervisor as SourceCaptureSupervisor, UnifiedTracingLive as SourceCaptureTracingLive, type SourceInfo, type TemplateVariables, UnifiedTracingLive, UnifiedTracingSupervisor, captureCallSite, createUnifiedTracingLayer as createAutoTracingLayer, createAutoTracingSupervisor, createUnifiedTracingLayer as createFullAutoTracingLayer, createUnifiedTracingLayer, defaultAutoTracingConfig, enableOpSupervision, flushAndShutdown, forceFlush, inferSpanName, isEffectForkPatched, loadAutoTracingConfig, loadAutoTracingConfigSync, loadFullConfigSync, patchEffectFork, sanitizeSpanName, setSpanName, tracedFork, tracedForkDaemon, unpatchEffectFork, withAutoTracing, withUnifiedTracing as withOperationTracing, withUnifiedTracing, withoutAutoTracing };