@atrim/instrument-node 0.7.1-dev.14fdea7.20260108232436 → 0.7.1-dev.764c183.20260110203528
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.
- package/package.json +2 -1
- package/target/dist/index.cjs +19 -0
- package/target/dist/index.cjs.map +1 -1
- package/target/dist/index.js +19 -0
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/auto/index.cjs +176 -47
- package/target/dist/integrations/effect/auto/index.cjs.map +1 -1
- package/target/dist/integrations/effect/auto/index.d.cts +24 -4
- package/target/dist/integrations/effect/auto/index.d.ts +24 -4
- package/target/dist/integrations/effect/auto/index.js +177 -48
- package/target/dist/integrations/effect/auto/index.js.map +1 -1
- package/target/dist/integrations/effect/index.cjs +19 -0
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.js +19 -0
- package/target/dist/integrations/effect/index.js.map +1 -1
|
@@ -82,7 +82,7 @@ declare const createEffectTracingLayer: () => Layer.Layer<never>;
|
|
|
82
82
|
declare const EffectTracingLive: Layer.Layer<never>;
|
|
83
83
|
/**
|
|
84
84
|
* Create a combined layer that provides both:
|
|
85
|
-
* 1. Effect-native HTTP tracing (via
|
|
85
|
+
* 1. Effect-native HTTP tracing (via Effect's Tracer + global OTel provider)
|
|
86
86
|
* 2. Fiber-level auto-tracing (via Supervisor)
|
|
87
87
|
*
|
|
88
88
|
* This gives you automatic spans for:
|
|
@@ -90,6 +90,14 @@ declare const EffectTracingLive: Layer.Layer<never>;
|
|
|
90
90
|
* - Every forked fiber (from our Supervisor)
|
|
91
91
|
*
|
|
92
92
|
* No manual Effect.withSpan() calls needed.
|
|
93
|
+
*
|
|
94
|
+
* ARCHITECTURE NOTE:
|
|
95
|
+
* Unlike EffectTracingLive which uses NodeSdk.layer (scoped provider),
|
|
96
|
+
* CombinedTracingLive uses a single GLOBAL TracerProvider so that both
|
|
97
|
+
* Effect's Tracer and our Supervisor use the same provider and exporter.
|
|
98
|
+
*
|
|
99
|
+
* This solves the dual-provider problem where HTTP spans and fiber spans
|
|
100
|
+
* would otherwise go to different exporters.
|
|
93
101
|
*/
|
|
94
102
|
declare const createCombinedTracingLayer: () => Layer.Layer<never>;
|
|
95
103
|
/**
|
|
@@ -166,17 +174,18 @@ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void>
|
|
|
166
174
|
private readonly fiberSpans;
|
|
167
175
|
private readonly fiberStartTimes;
|
|
168
176
|
private _tracer;
|
|
177
|
+
private readonly tracerProvider;
|
|
169
178
|
private readonly includePatterns;
|
|
170
179
|
private readonly excludePatterns;
|
|
171
180
|
private activeFiberCount;
|
|
172
181
|
private _rootSpan;
|
|
173
|
-
constructor(config: AutoInstrumentationConfig);
|
|
182
|
+
constructor(config: AutoInstrumentationConfig, tracerProvider?: OtelApi.TracerProvider);
|
|
174
183
|
/**
|
|
175
184
|
* Set the root span for parent context propagation
|
|
176
185
|
*/
|
|
177
186
|
setRootSpan(span: OtelApi.Span): void;
|
|
178
187
|
/**
|
|
179
|
-
* Get the tracer lazily -
|
|
188
|
+
* Get the tracer lazily - uses provided TracerProvider if available, otherwise uses global
|
|
180
189
|
*/
|
|
181
190
|
private get tracer();
|
|
182
191
|
/**
|
|
@@ -191,6 +200,10 @@ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void>
|
|
|
191
200
|
* Called when a fiber completes (success or failure)
|
|
192
201
|
*/
|
|
193
202
|
onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
|
|
203
|
+
/**
|
|
204
|
+
* Get attributes for span links from config
|
|
205
|
+
*/
|
|
206
|
+
private getLinkAttributes;
|
|
194
207
|
/**
|
|
195
208
|
* Check if a span name should be traced based on filter patterns
|
|
196
209
|
*/
|
|
@@ -211,7 +224,7 @@ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void>
|
|
|
211
224
|
/**
|
|
212
225
|
* Create a custom AutoTracingSupervisor with the given config
|
|
213
226
|
*/
|
|
214
|
-
declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig) => AutoTracingSupervisor;
|
|
227
|
+
declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig, tracerProvider?: OtelApi.TracerProvider) => AutoTracingSupervisor;
|
|
215
228
|
/**
|
|
216
229
|
* Layer that provides auto-tracing with custom configuration
|
|
217
230
|
*
|
|
@@ -387,6 +400,13 @@ declare const AutoTracingConfig_base: Context.TagClass<AutoTracingConfig, "AutoT
|
|
|
387
400
|
name: string;
|
|
388
401
|
}[];
|
|
389
402
|
};
|
|
403
|
+
span_relationships: {
|
|
404
|
+
type: "parent-child" | "span-links" | "both";
|
|
405
|
+
link_attributes?: {
|
|
406
|
+
"link.type": string;
|
|
407
|
+
custom?: Record<string, string> | undefined;
|
|
408
|
+
} | undefined;
|
|
409
|
+
};
|
|
390
410
|
performance: {
|
|
391
411
|
sampling_rate: number;
|
|
392
412
|
min_duration: string;
|
|
@@ -82,7 +82,7 @@ declare const createEffectTracingLayer: () => Layer.Layer<never>;
|
|
|
82
82
|
declare const EffectTracingLive: Layer.Layer<never>;
|
|
83
83
|
/**
|
|
84
84
|
* Create a combined layer that provides both:
|
|
85
|
-
* 1. Effect-native HTTP tracing (via
|
|
85
|
+
* 1. Effect-native HTTP tracing (via Effect's Tracer + global OTel provider)
|
|
86
86
|
* 2. Fiber-level auto-tracing (via Supervisor)
|
|
87
87
|
*
|
|
88
88
|
* This gives you automatic spans for:
|
|
@@ -90,6 +90,14 @@ declare const EffectTracingLive: Layer.Layer<never>;
|
|
|
90
90
|
* - Every forked fiber (from our Supervisor)
|
|
91
91
|
*
|
|
92
92
|
* No manual Effect.withSpan() calls needed.
|
|
93
|
+
*
|
|
94
|
+
* ARCHITECTURE NOTE:
|
|
95
|
+
* Unlike EffectTracingLive which uses NodeSdk.layer (scoped provider),
|
|
96
|
+
* CombinedTracingLive uses a single GLOBAL TracerProvider so that both
|
|
97
|
+
* Effect's Tracer and our Supervisor use the same provider and exporter.
|
|
98
|
+
*
|
|
99
|
+
* This solves the dual-provider problem where HTTP spans and fiber spans
|
|
100
|
+
* would otherwise go to different exporters.
|
|
93
101
|
*/
|
|
94
102
|
declare const createCombinedTracingLayer: () => Layer.Layer<never>;
|
|
95
103
|
/**
|
|
@@ -166,17 +174,18 @@ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void>
|
|
|
166
174
|
private readonly fiberSpans;
|
|
167
175
|
private readonly fiberStartTimes;
|
|
168
176
|
private _tracer;
|
|
177
|
+
private readonly tracerProvider;
|
|
169
178
|
private readonly includePatterns;
|
|
170
179
|
private readonly excludePatterns;
|
|
171
180
|
private activeFiberCount;
|
|
172
181
|
private _rootSpan;
|
|
173
|
-
constructor(config: AutoInstrumentationConfig);
|
|
182
|
+
constructor(config: AutoInstrumentationConfig, tracerProvider?: OtelApi.TracerProvider);
|
|
174
183
|
/**
|
|
175
184
|
* Set the root span for parent context propagation
|
|
176
185
|
*/
|
|
177
186
|
setRootSpan(span: OtelApi.Span): void;
|
|
178
187
|
/**
|
|
179
|
-
* Get the tracer lazily -
|
|
188
|
+
* Get the tracer lazily - uses provided TracerProvider if available, otherwise uses global
|
|
180
189
|
*/
|
|
181
190
|
private get tracer();
|
|
182
191
|
/**
|
|
@@ -191,6 +200,10 @@ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void>
|
|
|
191
200
|
* Called when a fiber completes (success or failure)
|
|
192
201
|
*/
|
|
193
202
|
onEnd<A, E>(exit: Exit.Exit<A, E>, fiber: Fiber.RuntimeFiber<A, E>): void;
|
|
203
|
+
/**
|
|
204
|
+
* Get attributes for span links from config
|
|
205
|
+
*/
|
|
206
|
+
private getLinkAttributes;
|
|
194
207
|
/**
|
|
195
208
|
* Check if a span name should be traced based on filter patterns
|
|
196
209
|
*/
|
|
@@ -211,7 +224,7 @@ declare class AutoTracingSupervisor extends Supervisor.AbstractSupervisor<void>
|
|
|
211
224
|
/**
|
|
212
225
|
* Create a custom AutoTracingSupervisor with the given config
|
|
213
226
|
*/
|
|
214
|
-
declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig) => AutoTracingSupervisor;
|
|
227
|
+
declare const createAutoTracingSupervisor: (config: AutoInstrumentationConfig, tracerProvider?: OtelApi.TracerProvider) => AutoTracingSupervisor;
|
|
215
228
|
/**
|
|
216
229
|
* Layer that provides auto-tracing with custom configuration
|
|
217
230
|
*
|
|
@@ -387,6 +400,13 @@ declare const AutoTracingConfig_base: Context.TagClass<AutoTracingConfig, "AutoT
|
|
|
387
400
|
name: string;
|
|
388
401
|
}[];
|
|
389
402
|
};
|
|
403
|
+
span_relationships: {
|
|
404
|
+
type: "parent-child" | "span-links" | "both";
|
|
405
|
+
link_attributes?: {
|
|
406
|
+
"link.type": string;
|
|
407
|
+
custom?: Record<string, string> | undefined;
|
|
408
|
+
} | undefined;
|
|
409
|
+
};
|
|
390
410
|
performance: {
|
|
391
411
|
sampling_rate: number;
|
|
392
412
|
min_duration: string;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { Data, Context, Effect, Layer, FiberRef, Option, Supervisor, FiberRefs, Exit } from 'effect';
|
|
2
|
-
import { NodeSdk } from '@effect/opentelemetry';
|
|
1
|
+
import { Data, Context, Effect, Layer, FiberRef, Option, Supervisor, FiberRefs, Tracer, Exit } from 'effect';
|
|
2
|
+
import { NodeSdk, Resource, Tracer as Tracer$1 } from '@effect/opentelemetry';
|
|
3
3
|
import { BasicTracerProvider, SimpleSpanProcessor, ConsoleSpanExporter, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
4
4
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
5
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
6
|
+
import { ATTR_SERVICE_VERSION, ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
|
|
7
|
+
import * as OtelApi from '@opentelemetry/api';
|
|
5
8
|
import { FileSystem } from '@effect/platform/FileSystem';
|
|
6
9
|
import * as HttpClient from '@effect/platform/HttpClient';
|
|
7
10
|
import * as HttpClientRequest from '@effect/platform/HttpClientRequest';
|
|
8
11
|
import { parse } from 'yaml';
|
|
9
12
|
import { z } from 'zod';
|
|
10
|
-
import * as OtelApi from '@opentelemetry/api';
|
|
11
|
-
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
12
|
-
import { ATTR_SERVICE_VERSION, ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';
|
|
13
13
|
import * as path from 'path';
|
|
14
14
|
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -82,6 +82,25 @@ var AutoInstrumentationConfigSchema = z.object({
|
|
|
82
82
|
// Naming rules (first match wins)
|
|
83
83
|
rules: z.array(SpanNamingRuleSchema).default([])
|
|
84
84
|
}).default({}),
|
|
85
|
+
// Span relationship configuration for forked fibers
|
|
86
|
+
// Controls how child fiber spans relate to their parent/forking context
|
|
87
|
+
span_relationships: z.object({
|
|
88
|
+
// Relationship type between forked fiber spans and their parent context
|
|
89
|
+
// - 'parent-child': Use parent-child relationship (default, traditional tracing)
|
|
90
|
+
// Parent span shows child as nested. Works well with most observability tools.
|
|
91
|
+
// - 'span-links': Use span links (semantically correct for async forks per OTel spec)
|
|
92
|
+
// Fibers get independent traces linked to parent. Better for long-running fibers.
|
|
93
|
+
// - 'both': Create parent-child AND add span links
|
|
94
|
+
// Maximum visibility but may create redundant data.
|
|
95
|
+
type: z.enum(["parent-child", "span-links", "both"]).default("parent-child"),
|
|
96
|
+
// Custom attributes to add to span links (only used when type includes links)
|
|
97
|
+
link_attributes: z.object({
|
|
98
|
+
// Link type identifier
|
|
99
|
+
"link.type": z.string().default("fork"),
|
|
100
|
+
// Custom attributes (key-value pairs)
|
|
101
|
+
custom: z.record(z.string()).optional()
|
|
102
|
+
}).optional()
|
|
103
|
+
}).default({}),
|
|
85
104
|
// Pattern-based filtering
|
|
86
105
|
filter: z.object({
|
|
87
106
|
// Only trace spans matching these patterns (empty = trace all)
|
|
@@ -525,6 +544,9 @@ var defaultAutoTracingConfig = {
|
|
|
525
544
|
infer_from_source: true,
|
|
526
545
|
rules: []
|
|
527
546
|
},
|
|
547
|
+
span_relationships: {
|
|
548
|
+
type: "parent-child"
|
|
549
|
+
},
|
|
528
550
|
filter: {
|
|
529
551
|
include: [],
|
|
530
552
|
exclude: []
|
|
@@ -706,7 +728,7 @@ function sanitizeSpanName(name) {
|
|
|
706
728
|
var AutoTracingEnabled = FiberRef.unsafeMake(true);
|
|
707
729
|
var AutoTracingSpanName = FiberRef.unsafeMake(Option.none());
|
|
708
730
|
var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
709
|
-
constructor(config) {
|
|
731
|
+
constructor(config, tracerProvider) {
|
|
710
732
|
super();
|
|
711
733
|
this.config = config;
|
|
712
734
|
// WeakMap to associate fibers with their OTel spans
|
|
@@ -715,6 +737,8 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
715
737
|
__publicField(this, "fiberStartTimes", /* @__PURE__ */ new WeakMap());
|
|
716
738
|
// OpenTelemetry tracer - lazily initialized
|
|
717
739
|
__publicField(this, "_tracer", null);
|
|
740
|
+
// Optional TracerProvider (if provided, use this instead of global)
|
|
741
|
+
__publicField(this, "tracerProvider", null);
|
|
718
742
|
// Compiled filter patterns
|
|
719
743
|
__publicField(this, "includePatterns");
|
|
720
744
|
__publicField(this, "excludePatterns");
|
|
@@ -722,6 +746,10 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
722
746
|
__publicField(this, "activeFiberCount", 0);
|
|
723
747
|
// Root span for parent context (set by withAutoTracing)
|
|
724
748
|
__publicField(this, "_rootSpan", null);
|
|
749
|
+
if (tracerProvider) {
|
|
750
|
+
this.tracerProvider = tracerProvider;
|
|
751
|
+
logger.log("@atrim/auto-trace: Using provided TracerProvider");
|
|
752
|
+
}
|
|
725
753
|
this.includePatterns = (config.filter?.include || []).map((p) => new RegExp(p));
|
|
726
754
|
this.excludePatterns = (config.filter?.exclude || []).map((p) => new RegExp(p));
|
|
727
755
|
logger.log("@atrim/auto-trace: Supervisor initialized");
|
|
@@ -736,11 +764,17 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
736
764
|
this._rootSpan = span;
|
|
737
765
|
}
|
|
738
766
|
/**
|
|
739
|
-
* Get the tracer lazily -
|
|
767
|
+
* Get the tracer lazily - uses provided TracerProvider if available, otherwise uses global
|
|
740
768
|
*/
|
|
741
769
|
get tracer() {
|
|
742
770
|
if (!this._tracer) {
|
|
743
|
-
|
|
771
|
+
if (this.tracerProvider) {
|
|
772
|
+
logger.log("@atrim/auto-trace: Getting tracer from provided TracerProvider");
|
|
773
|
+
this._tracer = this.tracerProvider.getTracer("@atrim/auto-trace", "1.0.0");
|
|
774
|
+
} else {
|
|
775
|
+
logger.log("@atrim/auto-trace: Getting tracer from global API");
|
|
776
|
+
this._tracer = OtelApi.trace.getTracer("@atrim/auto-trace", "1.0.0");
|
|
777
|
+
}
|
|
744
778
|
}
|
|
745
779
|
return this._tracer;
|
|
746
780
|
}
|
|
@@ -754,9 +788,11 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
754
788
|
* Called when a fiber starts executing
|
|
755
789
|
*/
|
|
756
790
|
onStart(_context, _effect, parent, fiber) {
|
|
791
|
+
logger.log(`@atrim/auto-trace: onStart called for fiber ${fiber.id().id}`);
|
|
757
792
|
const fiberRefsValue = fiber.getFiberRefs();
|
|
758
793
|
const enabled = FiberRefs.getOrDefault(fiberRefsValue, AutoTracingEnabled);
|
|
759
794
|
if (!enabled) {
|
|
795
|
+
logger.log(`@atrim/auto-trace: Auto-tracing disabled for fiber ${fiber.id().id}`);
|
|
760
796
|
return;
|
|
761
797
|
}
|
|
762
798
|
const samplingRate = this.config.performance?.sampling_rate ?? 1;
|
|
@@ -778,37 +814,86 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
778
814
|
if (!this.shouldTrace(spanName)) {
|
|
779
815
|
return;
|
|
780
816
|
}
|
|
817
|
+
const relationshipType = this.config.span_relationships?.type ?? "parent-child";
|
|
818
|
+
const useParentChild = relationshipType === "parent-child" || relationshipType === "both";
|
|
819
|
+
const useSpanLinks = relationshipType === "span-links" || relationshipType === "both";
|
|
781
820
|
let parentContext = OtelApi.ROOT_CONTEXT;
|
|
782
821
|
let parentFiberId;
|
|
783
|
-
|
|
822
|
+
let spanLinks = [];
|
|
823
|
+
const maybeEffectParentSpan = Context.getOption(_context, Tracer.ParentSpan);
|
|
824
|
+
if (Option.isSome(maybeEffectParentSpan)) {
|
|
825
|
+
const effectSpan = maybeEffectParentSpan.value;
|
|
826
|
+
logger.log(
|
|
827
|
+
`@atrim/auto-trace: Found ParentSpan - traceId=${effectSpan.traceId.slice(0, 8)}..., spanId=${effectSpan.spanId.slice(0, 8)}...`
|
|
828
|
+
);
|
|
829
|
+
const otelSpanContext = {
|
|
830
|
+
traceId: effectSpan.traceId,
|
|
831
|
+
spanId: effectSpan.spanId,
|
|
832
|
+
traceFlags: effectSpan.sampled ? OtelApi.TraceFlags.SAMPLED : OtelApi.TraceFlags.NONE,
|
|
833
|
+
isRemote: false
|
|
834
|
+
};
|
|
835
|
+
if (useParentChild) {
|
|
836
|
+
const wrappedSpan = OtelApi.trace.wrapSpanContext(otelSpanContext);
|
|
837
|
+
parentContext = OtelApi.trace.setSpan(OtelApi.ROOT_CONTEXT, wrappedSpan);
|
|
838
|
+
}
|
|
839
|
+
if (useSpanLinks) {
|
|
840
|
+
const linkAttributes = this.getLinkAttributes();
|
|
841
|
+
spanLinks.push({
|
|
842
|
+
context: otelSpanContext,
|
|
843
|
+
attributes: linkAttributes
|
|
844
|
+
});
|
|
845
|
+
logger.log(`@atrim/auto-trace: Added span link to parent (${relationshipType})`);
|
|
846
|
+
}
|
|
847
|
+
} else if (Option.isSome(parent)) {
|
|
784
848
|
parentFiberId = parent.value.id().id;
|
|
785
849
|
const parentSpan = this.fiberSpans.get(parent.value);
|
|
786
850
|
if (parentSpan) {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
if (
|
|
791
|
-
|
|
792
|
-
|
|
851
|
+
if (useParentChild) {
|
|
852
|
+
parentContext = OtelApi.trace.setSpan(OtelApi.ROOT_CONTEXT, parentSpan);
|
|
853
|
+
}
|
|
854
|
+
if (useSpanLinks) {
|
|
855
|
+
const linkAttributes = this.getLinkAttributes();
|
|
856
|
+
spanLinks.push({
|
|
857
|
+
context: parentSpan.spanContext(),
|
|
858
|
+
attributes: linkAttributes
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
} else if (this._rootSpan) {
|
|
862
|
+
if (useParentChild) {
|
|
793
863
|
parentContext = OtelApi.trace.setSpan(OtelApi.ROOT_CONTEXT, this._rootSpan);
|
|
794
864
|
}
|
|
865
|
+
if (useSpanLinks) {
|
|
866
|
+
const linkAttributes = this.getLinkAttributes();
|
|
867
|
+
spanLinks.push({
|
|
868
|
+
context: this._rootSpan.spanContext(),
|
|
869
|
+
attributes: linkAttributes
|
|
870
|
+
});
|
|
871
|
+
}
|
|
795
872
|
}
|
|
796
|
-
} else {
|
|
797
|
-
|
|
798
|
-
if (activeSpan) {
|
|
799
|
-
parentContext = OtelApi.context.active();
|
|
800
|
-
} else if (this._rootSpan) {
|
|
873
|
+
} else if (this._rootSpan) {
|
|
874
|
+
if (useParentChild) {
|
|
801
875
|
parentContext = OtelApi.trace.setSpan(OtelApi.ROOT_CONTEXT, this._rootSpan);
|
|
802
876
|
}
|
|
877
|
+
if (useSpanLinks) {
|
|
878
|
+
const linkAttributes = this.getLinkAttributes();
|
|
879
|
+
spanLinks.push({
|
|
880
|
+
context: this._rootSpan.spanContext(),
|
|
881
|
+
attributes: linkAttributes
|
|
882
|
+
});
|
|
883
|
+
}
|
|
803
884
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
)
|
|
885
|
+
if (Option.isSome(parent)) {
|
|
886
|
+
parentFiberId = parent.value.id().id;
|
|
887
|
+
}
|
|
888
|
+
const spanOptions = {
|
|
889
|
+
kind: OtelApi.SpanKind.INTERNAL,
|
|
890
|
+
attributes: this.getInitialAttributes(fiber, sourceInfo, parentFiberId)
|
|
891
|
+
};
|
|
892
|
+
if (spanLinks.length > 0) {
|
|
893
|
+
spanOptions.links = spanLinks;
|
|
894
|
+
}
|
|
895
|
+
const span = this.tracer.startSpan(spanName, spanOptions, parentContext);
|
|
896
|
+
logger.log(`@atrim/auto-trace: Created span "${spanName}" for fiber ${fiber.id().id}`);
|
|
812
897
|
this.fiberSpans.set(fiber, span);
|
|
813
898
|
this.fiberStartTimes.set(fiber, process.hrtime.bigint());
|
|
814
899
|
this.activeFiberCount++;
|
|
@@ -817,8 +902,12 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
817
902
|
* Called when a fiber completes (success or failure)
|
|
818
903
|
*/
|
|
819
904
|
onEnd(exit, fiber) {
|
|
905
|
+
logger.log(`@atrim/auto-trace: onEnd called for fiber ${fiber.id().id}`);
|
|
820
906
|
const span = this.fiberSpans.get(fiber);
|
|
821
907
|
if (!span) {
|
|
908
|
+
logger.log(
|
|
909
|
+
`@atrim/auto-trace: No span found for fiber ${fiber.id().id} (skipped or filtered)`
|
|
910
|
+
);
|
|
822
911
|
return;
|
|
823
912
|
}
|
|
824
913
|
const startTime = this.fiberStartTimes.get(fiber);
|
|
@@ -842,10 +931,26 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
842
931
|
span.setAttribute("effect.fiber.failed", true);
|
|
843
932
|
}
|
|
844
933
|
span.end();
|
|
934
|
+
logger.log(`@atrim/auto-trace: Ended span for fiber ${fiber.id().id}`);
|
|
845
935
|
this.fiberSpans.delete(fiber);
|
|
846
936
|
this.fiberStartTimes.delete(fiber);
|
|
847
937
|
this.activeFiberCount--;
|
|
848
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* Get attributes for span links from config
|
|
941
|
+
*/
|
|
942
|
+
getLinkAttributes() {
|
|
943
|
+
const linkConfig = this.config.span_relationships?.link_attributes;
|
|
944
|
+
const attrs = {
|
|
945
|
+
"link.type": linkConfig?.["link.type"] ?? "fork"
|
|
946
|
+
};
|
|
947
|
+
if (linkConfig?.custom) {
|
|
948
|
+
for (const [key, value] of Object.entries(linkConfig.custom)) {
|
|
949
|
+
attrs[key] = value;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
return attrs;
|
|
953
|
+
}
|
|
849
954
|
/**
|
|
850
955
|
* Check if a span name should be traced based on filter patterns
|
|
851
956
|
*/
|
|
@@ -936,8 +1041,8 @@ var AutoTracingSupervisor = class extends Supervisor.AbstractSupervisor {
|
|
|
936
1041
|
}
|
|
937
1042
|
}
|
|
938
1043
|
};
|
|
939
|
-
var createAutoTracingSupervisor = (config) => {
|
|
940
|
-
return new AutoTracingSupervisor(config);
|
|
1044
|
+
var createAutoTracingSupervisor = (config, tracerProvider) => {
|
|
1045
|
+
return new AutoTracingSupervisor(config, tracerProvider);
|
|
941
1046
|
};
|
|
942
1047
|
var createAutoTracingLayer = (options) => {
|
|
943
1048
|
return Layer.unwrapEffect(
|
|
@@ -1017,7 +1122,9 @@ var createExporterLayer = (exporterConfig, serviceName, serviceVersion) => {
|
|
|
1017
1122
|
};
|
|
1018
1123
|
if (config.headers) {
|
|
1019
1124
|
exporterConfig2.headers = config.headers;
|
|
1020
|
-
logger.log(
|
|
1125
|
+
logger.log(
|
|
1126
|
+
`@atrim/auto-trace: Using custom headers: ${Object.keys(config.headers).join(", ")}`
|
|
1127
|
+
);
|
|
1021
1128
|
}
|
|
1022
1129
|
return new OTLPTraceExporter(exporterConfig2);
|
|
1023
1130
|
};
|
|
@@ -1110,7 +1217,9 @@ var createEffectTracingLayer = () => {
|
|
|
1110
1217
|
};
|
|
1111
1218
|
if (exporterConfig.headers) {
|
|
1112
1219
|
otlpConfig.headers = exporterConfig.headers;
|
|
1113
|
-
logger.log(
|
|
1220
|
+
logger.log(
|
|
1221
|
+
`@atrim/auto-trace: Using custom headers: ${Object.keys(exporterConfig.headers).join(", ")}`
|
|
1222
|
+
);
|
|
1114
1223
|
}
|
|
1115
1224
|
const exporter = new OTLPTraceExporter(otlpConfig);
|
|
1116
1225
|
if (exporterConfig.processor === "simple") {
|
|
@@ -1158,6 +1267,9 @@ var createCombinedTracingLayer = () => {
|
|
|
1158
1267
|
infer_from_source: true,
|
|
1159
1268
|
rules: []
|
|
1160
1269
|
},
|
|
1270
|
+
span_relationships: {
|
|
1271
|
+
type: "parent-child"
|
|
1272
|
+
},
|
|
1161
1273
|
filter: { include: [], exclude: [] },
|
|
1162
1274
|
performance: { sampling_rate: 1, min_duration: "0ms", max_concurrent: 0 },
|
|
1163
1275
|
metadata: { fiber_info: true, source_location: true, parent_fiber: true }
|
|
@@ -1169,10 +1281,10 @@ var createCombinedTracingLayer = () => {
|
|
|
1169
1281
|
logger.log('@atrim/auto-trace: Exporter type is "none", using empty layer');
|
|
1170
1282
|
return Layer.empty;
|
|
1171
1283
|
}
|
|
1172
|
-
const
|
|
1284
|
+
const createSpanExporter = () => {
|
|
1173
1285
|
if (exporterConfig.type === "console") {
|
|
1174
|
-
logger.log("@atrim/auto-trace: Using ConsoleSpanExporter
|
|
1175
|
-
return new
|
|
1286
|
+
logger.log("@atrim/auto-trace: Using ConsoleSpanExporter");
|
|
1287
|
+
return new ConsoleSpanExporter();
|
|
1176
1288
|
}
|
|
1177
1289
|
const endpoint = exporterConfig.endpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
1178
1290
|
logger.log(`@atrim/auto-trace: Using OTLPTraceExporter (${endpoint})`);
|
|
@@ -1181,10 +1293,15 @@ var createCombinedTracingLayer = () => {
|
|
|
1181
1293
|
};
|
|
1182
1294
|
if (exporterConfig.headers) {
|
|
1183
1295
|
otlpConfig.headers = exporterConfig.headers;
|
|
1184
|
-
logger.log(
|
|
1296
|
+
logger.log(
|
|
1297
|
+
`@atrim/auto-trace: Using custom headers: ${Object.keys(exporterConfig.headers).join(", ")}`
|
|
1298
|
+
);
|
|
1185
1299
|
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1300
|
+
return new OTLPTraceExporter(otlpConfig);
|
|
1301
|
+
};
|
|
1302
|
+
const createSpanProcessor = () => {
|
|
1303
|
+
const exporter = createSpanExporter();
|
|
1304
|
+
if (exporterConfig.processor === "simple" || exporterConfig.type === "console") {
|
|
1188
1305
|
logger.log("@atrim/auto-trace: Using SimpleSpanProcessor");
|
|
1189
1306
|
return new SimpleSpanProcessor(exporter);
|
|
1190
1307
|
}
|
|
@@ -1198,19 +1315,31 @@ var createCombinedTracingLayer = () => {
|
|
|
1198
1315
|
maxExportBatchSize: batchConfig.max_export_batch_size
|
|
1199
1316
|
});
|
|
1200
1317
|
};
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1318
|
+
const globalProviderLayer = Layer.effectDiscard(
|
|
1319
|
+
Effect.sync(() => {
|
|
1320
|
+
const provider = new BasicTracerProvider({
|
|
1321
|
+
resource: resourceFromAttributes({
|
|
1322
|
+
[ATTR_SERVICE_NAME]: serviceName,
|
|
1323
|
+
[ATTR_SERVICE_VERSION]: serviceVersion
|
|
1324
|
+
}),
|
|
1325
|
+
spanProcessors: [createSpanProcessor()]
|
|
1326
|
+
});
|
|
1327
|
+
OtelApi.trace.setGlobalTracerProvider(provider);
|
|
1328
|
+
logger.log("@atrim/auto-trace: Global TracerProvider registered");
|
|
1329
|
+
})
|
|
1330
|
+
);
|
|
1331
|
+
const resourceLayer = Resource.layer({
|
|
1332
|
+
serviceName,
|
|
1333
|
+
serviceVersion
|
|
1334
|
+
});
|
|
1335
|
+
const effectTracerLayer = Tracer$1.layerGlobal;
|
|
1208
1336
|
const supervisor = createAutoTracingSupervisor(autoConfig);
|
|
1209
1337
|
const supervisorLayer = Supervisor.addSupervisor(supervisor);
|
|
1210
1338
|
logger.log("@atrim/auto-trace: Combined layer created");
|
|
1211
|
-
logger.log(" - HTTP requests: auto-traced via Effect platform");
|
|
1212
|
-
logger.log(" - Forked fibers: auto-traced via Supervisor");
|
|
1213
|
-
|
|
1339
|
+
logger.log(" - HTTP requests: auto-traced via Effect platform (global provider)");
|
|
1340
|
+
logger.log(" - Forked fibers: auto-traced via Supervisor (global provider)");
|
|
1341
|
+
const tracerWithResource = effectTracerLayer.pipe(Layer.provide(resourceLayer));
|
|
1342
|
+
return Layer.mergeAll(globalProviderLayer, Layer.discard(tracerWithResource), supervisorLayer);
|
|
1214
1343
|
})
|
|
1215
1344
|
);
|
|
1216
1345
|
};
|