@atrim/instrument-node 0.5.2-dev.ac2fbfe.20251221205322 → 0.7.0-14fdea7-20260108225522

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,437 @@
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';
4
+ export { AutoInstrumentationConfig } from '@atrim/instrument-core';
5
+
6
+ /**
7
+ * Effect-Native Tracing Layer
8
+ *
9
+ * Uses @effect/opentelemetry's NodeSdk.layer for proper Effect integration.
10
+ * This provides automatic HTTP request tracing and Effect.withSpan() support.
11
+ *
12
+ * Requires @effect/opentelemetry peer dependency to be installed.
13
+ */
14
+
15
+ /**
16
+ * Create a layer that provides Effect-native tracing via NodeSdk.layer
17
+ *
18
+ * This integrates with Effect's built-in tracing system, which means:
19
+ * - HTTP requests are automatically traced by @effect/platform
20
+ * - Effect.withSpan() creates proper OTel spans
21
+ * - Parent-child span relationships work correctly
22
+ * - No need to fork fibers for tracing to work
23
+ *
24
+ * Configuration is loaded from instrumentation.yaml (exporter_config section).
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import { EffectTracingLive } from '@atrim/instrument-node/effect/auto'
29
+ *
30
+ * // HTTP requests automatically traced!
31
+ * const HttpLive = router.pipe(
32
+ * HttpServer.serve(),
33
+ * Layer.provide(ServerLive),
34
+ * Layer.provide(EffectTracingLive),
35
+ * )
36
+ * ```
37
+ */
38
+ declare const createEffectTracingLayer: () => Layer.Layer<never>;
39
+ /**
40
+ * Effect-native tracing layer using @effect/opentelemetry
41
+ *
42
+ * This is the **recommended** layer for Effect HTTP applications. It provides:
43
+ * - Automatic HTTP request tracing (built into @effect/platform)
44
+ * - Full Effect.withSpan() support for manual spans
45
+ * - Proper parent-child span relationships
46
+ * - No need to fork fibers manually
47
+ *
48
+ * Configuration is loaded from your instrumentation.yaml file.
49
+ *
50
+ * @example
51
+ * ```yaml
52
+ * # instrumentation.yaml
53
+ * effect:
54
+ * exporter_config:
55
+ * type: otlp # or 'console' for dev
56
+ * endpoint: http://localhost:4318
57
+ * headers:
58
+ * x-api-key: your-key
59
+ * processor: batch # or 'simple' for immediate export
60
+ * ```
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * import { EffectTracingLive } from '@atrim/instrument-node/effect/auto'
65
+ * import { HttpRouter, HttpServer } from "@effect/platform"
66
+ * import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
67
+ *
68
+ * const router = HttpRouter.empty.pipe(
69
+ * HttpRouter.get("/", Effect.succeed(HttpServerResponse.text("Hello!"))),
70
+ * )
71
+ *
72
+ * const HttpLive = router.pipe(
73
+ * HttpServer.serve(),
74
+ * Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 })),
75
+ * Layer.provide(EffectTracingLive), // <- Just add this!
76
+ * )
77
+ *
78
+ * NodeRuntime.runMain(Layer.launch(HttpLive))
79
+ * // All HTTP requests now automatically traced!
80
+ * ```
81
+ */
82
+ declare const EffectTracingLive: Layer.Layer<never>;
83
+
84
+ /**
85
+ * Auto-Tracing Supervisor for Effect-TS
86
+ *
87
+ * Provides automatic tracing of all Effect fibers without manual Effect.withSpan() calls.
88
+ * Uses Effect's Supervisor API to intercept fiber creation/termination and create
89
+ * OpenTelemetry spans automatically.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { AutoTracingLive } from '@atrim/instrument-node/effect/auto'
94
+ *
95
+ * const program = Effect.gen(function* () {
96
+ * yield* doWork() // Automatically traced!
97
+ * }).pipe(Effect.provide(AutoTracingLive))
98
+ * ```
99
+ */
100
+
101
+ /**
102
+ * FiberRef to enable/disable auto-tracing for specific fibers
103
+ * Use withoutAutoTracing() to disable
104
+ */
105
+ declare const AutoTracingEnabled: FiberRef.FiberRef<boolean>;
106
+ /**
107
+ * FiberRef to override auto-generated span name
108
+ * Use setSpanName() to override
109
+ */
110
+ declare const AutoTracingSpanName: FiberRef.FiberRef<Option.Option<string>>;
111
+ /**
112
+ * Supervisor that automatically creates OpenTelemetry spans for all Effect fibers
113
+ *
114
+ * This supervisor intercepts fiber creation and termination, creating spans
115
+ * based on configuration from instrumentation.yaml.
116
+ */
117
+ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void> {
118
+ private readonly config;
119
+ private readonly fiberSpans;
120
+ private readonly fiberStartTimes;
121
+ private _tracer;
122
+ private readonly includePatterns;
123
+ private readonly excludePatterns;
124
+ private activeFiberCount;
125
+ private _rootSpan;
126
+ constructor(config: AutoInstrumentationConfig);
127
+ /**
128
+ * Set the root span for parent context propagation
129
+ */
130
+ setRootSpan(span: OtelApi.Span): void;
131
+ /**
132
+ * Get the tracer lazily - this allows time for the NodeSdk layer to register the global provider
133
+ */
134
+ private get tracer();
135
+ /**
136
+ * Returns the current value (void for this supervisor)
137
+ */
138
+ get value(): Effect.Effect<void>;
139
+ /**
140
+ * Called when a fiber starts executing
141
+ */
142
+ 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;
143
+ /**
144
+ * Called when a fiber completes (success or failure)
145
+ */
146
+ onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
147
+ /**
148
+ * Check if a span name should be traced based on filter patterns
149
+ */
150
+ private shouldTrace;
151
+ /**
152
+ * Get initial span attributes for a fiber
153
+ */
154
+ private getInitialAttributes;
155
+ /**
156
+ * Parse stack trace to get source info
157
+ */
158
+ private parseStackTrace;
159
+ /**
160
+ * Parse min_duration string to nanoseconds
161
+ */
162
+ private parseMinDuration;
163
+ }
164
+ /**
165
+ * Create a custom AutoTracingSupervisor with the given config
166
+ */
167
+ declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig) => AutoTracingSupervisor;
168
+ /**
169
+ * Layer that provides auto-tracing with custom configuration
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * const CustomAutoTracing = createAutoTracingLayer({
174
+ * enabled: true,
175
+ * span_naming: {
176
+ * default: 'app.{function}',
177
+ * rules: [{ match: { file: 'src/services/.*' }, name: 'service.{function}' }]
178
+ * }
179
+ * })
180
+ * ```
181
+ */
182
+ declare const createAutoTracingLayer: (options?: {
183
+ config?: AutoInstrumentationConfig;
184
+ }) => Layer.Layer<never>;
185
+ /**
186
+ * Wrap an Effect with auto-tracing supervision
187
+ *
188
+ * This creates a span for the main effect AND supervises all child fibers.
189
+ * Use this when you need to ensure all fibers in an effect are traced.
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const program = Effect.gen(function* () {
194
+ * yield* doWork() // Automatically traced!
195
+ * })
196
+ *
197
+ * const tracedProgram = withAutoTracing(program, { enabled: true, ... })
198
+ * Effect.runPromise(tracedProgram)
199
+ * ```
200
+ */
201
+ declare const withAutoTracing: <A, E, R>(effect: Effect.Effect<A, E, R>, config: AutoInstrumentationConfig, mainSpanName?: string) => Effect.Effect<A, E, R>;
202
+ /**
203
+ * Zero-config auto-tracing layer
204
+ *
205
+ * Loads configuration from instrumentation.yaml and automatically traces
206
+ * all Effect fibers based on the configuration.
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * import { AutoTracingLive } from '@atrim/instrument-node/effect/auto'
211
+ *
212
+ * const program = Effect.gen(function* () {
213
+ * yield* doWork() // Automatically traced!
214
+ * }).pipe(Effect.provide(AutoTracingLive))
215
+ * ```
216
+ */
217
+ declare const AutoTracingLive: Layer.Layer<never>;
218
+ /**
219
+ * Disable auto-tracing for a specific Effect
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * const program = Effect.gen(function* () {
224
+ * yield* publicWork() // Traced
225
+ * yield* withoutAutoTracing(internalWork()) // NOT traced
226
+ * })
227
+ * ```
228
+ */
229
+ declare const withoutAutoTracing: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
230
+ /**
231
+ * Override the auto-generated span name for a specific Effect
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * const program = Effect.gen(function* () {
236
+ * yield* setSpanName('custom.operation.name')(myEffect)
237
+ * })
238
+ * ```
239
+ */
240
+ declare const setSpanName: (name: string) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
241
+ /**
242
+ * Create a fully YAML-driven auto-instrumentation layer
243
+ *
244
+ * This layer reads all configuration from instrumentation.yaml including:
245
+ * - Exporter configuration (type, endpoint, processor)
246
+ * - Auto-tracing configuration (naming rules, filters, performance)
247
+ * - Service metadata (name, version)
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * import { createFullAutoTracingLayer } from '@atrim/instrument-node/effect/auto'
252
+ *
253
+ * // Everything configured via instrumentation.yaml - no code config needed!
254
+ * const AppLive = createFullAutoTracingLayer()
255
+ *
256
+ * Effect.runPromise(program.pipe(Effect.provide(AppLive)))
257
+ * ```
258
+ */
259
+ declare const createFullAutoTracingLayer: () => Layer.Layer<never>;
260
+ /**
261
+ * Fully YAML-driven auto-instrumentation layer
262
+ *
263
+ * This is the recommended way to use auto-instrumentation. All configuration
264
+ * comes from instrumentation.yaml - no code configuration needed.
265
+ *
266
+ * @example
267
+ * ```yaml
268
+ * # instrumentation.yaml
269
+ * effect:
270
+ * auto_instrumentation:
271
+ * enabled: true
272
+ * span_naming:
273
+ * default: "effect.{function}"
274
+ * rules:
275
+ * - match: { function: "internal.*" }
276
+ * name: "internal.{function}"
277
+ * filter:
278
+ * exclude:
279
+ * - "^internal\\."
280
+ * exporter_config:
281
+ * type: otlp # or 'console' for dev
282
+ * endpoint: http://localhost:4318
283
+ * processor: batch # or 'simple' for dev
284
+ * ```
285
+ *
286
+ * @example
287
+ * ```typescript
288
+ * import { FullAutoTracingLive } from '@atrim/instrument-node/effect/auto'
289
+ *
290
+ * // Just provide the layer - everything else from YAML!
291
+ * Effect.runPromise(program.pipe(Effect.provide(FullAutoTracingLive)))
292
+ * ```
293
+ */
294
+ declare const FullAutoTracingLive: Layer.Layer<never>;
295
+
296
+ /**
297
+ * Node.js configuration loader
298
+ *
299
+ * Provides configuration loading using native Node.js APIs (fs, fetch)
300
+ * This module doesn't require Effect Platform, making it work without Effect installed.
301
+ */
302
+
303
+ /**
304
+ * Legacy options interface for backward compatibility
305
+ */
306
+ interface ConfigLoaderOptions {
307
+ configPath?: string;
308
+ configUrl?: string;
309
+ config?: InstrumentationConfig;
310
+ cacheTimeout?: number;
311
+ }
312
+
313
+ /**
314
+ * Auto-Tracing Configuration Loader
315
+ *
316
+ * Loads auto-tracing configuration from instrumentation.yaml
317
+ * and provides a typed Effect service for accessing it.
318
+ */
319
+
320
+ /**
321
+ * Default auto-tracing configuration when not specified in instrumentation.yaml
322
+ */
323
+ declare const defaultAutoTracingConfig: AutoInstrumentationConfig;
324
+ declare const AutoTracingConfig_base: Context.TagClass<AutoTracingConfig, "AutoTracingConfig", {
325
+ enabled: boolean;
326
+ filter: {
327
+ include: string[];
328
+ exclude: string[];
329
+ };
330
+ granularity: "fiber" | "operator";
331
+ span_naming: {
332
+ default: string;
333
+ infer_from_source: boolean;
334
+ rules: {
335
+ match: {
336
+ function?: string | undefined;
337
+ file?: string | undefined;
338
+ module?: string | undefined;
339
+ };
340
+ name: string;
341
+ }[];
342
+ };
343
+ performance: {
344
+ sampling_rate: number;
345
+ min_duration: string;
346
+ max_concurrent: number;
347
+ };
348
+ metadata: {
349
+ fiber_info: boolean;
350
+ source_location: boolean;
351
+ parent_fiber: boolean;
352
+ };
353
+ }>;
354
+ /**
355
+ * Service tag for auto-tracing configuration
356
+ */
357
+ declare class AutoTracingConfig extends AutoTracingConfig_base {
358
+ }
359
+ /**
360
+ * Load auto-tracing configuration from instrumentation.yaml
361
+ *
362
+ * Returns the config from effect.auto_instrumentation section,
363
+ * or defaults if not specified.
364
+ */
365
+ declare const loadAutoTracingConfig: (options?: ConfigLoaderOptions) => Effect.Effect<AutoInstrumentationConfig, never, never>;
366
+ /**
367
+ * Load auto-tracing configuration synchronously from cache or default
368
+ *
369
+ * Note: This is a synchronous fallback when Effect runtime isn't available.
370
+ * Prefer loadAutoTracingConfig() when possible.
371
+ */
372
+ declare const loadAutoTracingConfigSync: () => AutoInstrumentationConfig;
373
+ /**
374
+ * Layer that provides auto-tracing configuration
375
+ */
376
+ declare const AutoTracingConfigLive: Layer.Layer<AutoTracingConfig, never, never>;
377
+ /**
378
+ * Layer that provides custom auto-tracing configuration
379
+ */
380
+ declare const AutoTracingConfigLayer: (config: AutoInstrumentationConfig) => Layer.Layer<AutoTracingConfig>;
381
+
382
+ /**
383
+ * Span Name Inference for Auto-Tracing
384
+ *
385
+ * Provides intelligent span naming based on source code information
386
+ * and configuration rules from instrumentation.yaml.
387
+ */
388
+
389
+ /**
390
+ * Source code information extracted from stack traces
391
+ */
392
+ interface SourceInfo {
393
+ /** Function name (or 'anonymous') */
394
+ function: string;
395
+ /** Full file path */
396
+ file: string;
397
+ /** Line number */
398
+ line: number;
399
+ /** Column number */
400
+ column: number;
401
+ }
402
+ /**
403
+ * Template variables available for span naming
404
+ */
405
+ interface TemplateVariables {
406
+ fiber_id: string;
407
+ function: string;
408
+ module: string;
409
+ file: string;
410
+ line: string;
411
+ operator: string;
412
+ [key: string]: string;
413
+ }
414
+ /**
415
+ * Infer a span name based on fiber ID, source info, and configuration
416
+ *
417
+ * Priority:
418
+ * 1. Match against naming rules (first match wins)
419
+ * 2. Use default template with source info if available
420
+ * 3. Fallback to default template with fiber ID only
421
+ *
422
+ * @param fiberId - The fiber's numeric ID
423
+ * @param sourceInfo - Optional source code information from stack trace
424
+ * @param config - Auto-instrumentation configuration
425
+ * @returns The inferred span name
426
+ */
427
+ declare function inferSpanName(fiberId: number, sourceInfo: SourceInfo | undefined, config: AutoInstrumentationConfig): string;
428
+ /**
429
+ * Sanitize a span name to be OpenTelemetry compliant
430
+ *
431
+ * - Replaces invalid characters with underscores
432
+ * - Ensures name is not empty
433
+ * - Truncates to reasonable length
434
+ */
435
+ declare function sanitizeSpanName(name: string): string;
436
+
437
+ export { AutoTracingConfig, AutoTracingConfigLayer, AutoTracingConfigLive, AutoTracingEnabled, AutoTracingLive, AutoTracingSpanName, AutoTracingSupervisor, EffectTracingLive, FullAutoTracingLive, type SourceInfo, type TemplateVariables, createAutoTracingLayer, createAutoTracingSupervisor, createEffectTracingLayer, createFullAutoTracingLayer, defaultAutoTracingConfig, inferSpanName, loadAutoTracingConfig, loadAutoTracingConfigSync, sanitizeSpanName, setSpanName, withAutoTracing, withoutAutoTracing };