@atrim/instrument-web 0.5.0-11e06b7-20251119014031 → 0.5.0-c05e3a1-20251119131241
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 +1 -1
- package/target/dist/index.d.ts +22 -37
- package/target/dist/index.js +93 -103
- package/target/dist/index.js.map +1 -1
package/package.json
CHANGED
package/target/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { Effect, Layer } from 'effect';
|
|
1
2
|
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
|
|
2
|
-
import { InstrumentationConfig, ConfigLoader } from '@atrim/instrument-core';
|
|
3
|
+
import { InstrumentationConfig, InitializationError, ConfigLoader } from '@atrim/instrument-core';
|
|
3
4
|
export { ConfigError, ConfigFileError, ConfigUrlError, ConfigValidationError, ExportError, InitializationError, InstrumentationConfig, PatternConfig, PatternMatcher, ShutdownError, clearPatternMatcher, getPatternMatcher, initializePatternMatcher, shouldInstrumentSpan } from '@atrim/instrument-core';
|
|
4
5
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
5
|
-
import { Layer } from 'effect';
|
|
6
6
|
import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
|
|
7
7
|
import { Context, Span } from '@opentelemetry/api';
|
|
8
8
|
|
|
@@ -70,31 +70,6 @@ interface SdkInitializationOptions {
|
|
|
70
70
|
* @default true
|
|
71
71
|
*/
|
|
72
72
|
enableXhr?: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Control trace context propagation for cross-origin requests
|
|
75
|
-
*
|
|
76
|
-
* Determines which cross-origin requests receive W3C Trace Context headers
|
|
77
|
-
* (traceparent, tracestate). Note: Backends must allow these headers in CORS
|
|
78
|
-
* configuration or requests will fail with CORS errors.
|
|
79
|
-
*
|
|
80
|
-
* - 'all': Propagate to all cross-origin requests (may cause CORS errors)
|
|
81
|
-
* - 'none': Never propagate trace headers
|
|
82
|
-
* - 'same-origin': Only propagate to same-origin requests (default)
|
|
83
|
-
* - Array of URL patterns: Custom propagation patterns (regex strings)
|
|
84
|
-
*
|
|
85
|
-
* @default 'same-origin'
|
|
86
|
-
*
|
|
87
|
-
* @example Propagate to specific API domains
|
|
88
|
-
* ```typescript
|
|
89
|
-
* propagateTraceContext: ['^https://api\\.myapp\\.com', '^http://localhost:300[0-9]']
|
|
90
|
-
* ```
|
|
91
|
-
*
|
|
92
|
-
* @example Disable propagation (for debugging CORS issues)
|
|
93
|
-
* ```typescript
|
|
94
|
-
* propagateTraceContext: 'none'
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
propagateTraceContext?: 'all' | 'none' | 'same-origin' | string[];
|
|
98
73
|
}
|
|
99
74
|
/**
|
|
100
75
|
* Get the current SDK instance
|
|
@@ -128,37 +103,47 @@ declare function resetSdk(): void;
|
|
|
128
103
|
* Call this function once at application startup, before any other code runs.
|
|
129
104
|
*
|
|
130
105
|
* @param options - Initialization options
|
|
131
|
-
* @returns WebTracerProvider instance
|
|
132
|
-
* @throws {Error} If initialization fails
|
|
106
|
+
* @returns Effect that yields WebTracerProvider instance
|
|
133
107
|
*
|
|
134
108
|
* @example
|
|
135
109
|
* ```typescript
|
|
110
|
+
* import { Effect } from 'effect'
|
|
136
111
|
* import { initializeInstrumentation } from '@atrim/instrument-web'
|
|
137
112
|
*
|
|
138
|
-
*
|
|
113
|
+
* const program = initializeInstrumentation({
|
|
139
114
|
* serviceName: 'my-app',
|
|
140
115
|
* otlpEndpoint: 'http://localhost:4318/v1/traces'
|
|
141
116
|
* })
|
|
117
|
+
*
|
|
118
|
+
* await Effect.runPromise(program)
|
|
142
119
|
* ```
|
|
143
120
|
*
|
|
144
121
|
* @example With pattern-based filtering
|
|
145
122
|
* ```typescript
|
|
146
|
-
*
|
|
123
|
+
* const program = initializeInstrumentation({
|
|
147
124
|
* serviceName: 'my-app',
|
|
148
125
|
* configUrl: 'https://config.company.com/instrumentation.yaml'
|
|
149
126
|
* })
|
|
127
|
+
*
|
|
128
|
+
* await Effect.runPromise(program)
|
|
150
129
|
* ```
|
|
151
130
|
*
|
|
152
|
-
* @example
|
|
131
|
+
* @example With error handling
|
|
153
132
|
* ```typescript
|
|
154
|
-
*
|
|
133
|
+
* const program = initializeInstrumentation({
|
|
155
134
|
* serviceName: 'my-app',
|
|
156
|
-
* enableUserInteraction: false
|
|
157
|
-
*
|
|
158
|
-
*
|
|
135
|
+
* enableUserInteraction: false
|
|
136
|
+
* }).pipe(
|
|
137
|
+
* Effect.catchTag('InitializationError', (error) => {
|
|
138
|
+
* console.error('Failed to initialize:', error.reason)
|
|
139
|
+
* return Effect.die(error) // Re-throw or handle
|
|
140
|
+
* })
|
|
141
|
+
* )
|
|
142
|
+
*
|
|
143
|
+
* await Effect.runPromise(program)
|
|
159
144
|
* ```
|
|
160
145
|
*/
|
|
161
|
-
declare
|
|
146
|
+
declare const initializeInstrumentation: (options: SdkInitializationOptions) => Effect.Effect<WebTracerProvider, InitializationError>;
|
|
162
147
|
|
|
163
148
|
/**
|
|
164
149
|
* OTLP Exporter Factory for Browser
|
package/target/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { Data, Context, Effect, Layer, Deferred } from 'effect';
|
|
1
2
|
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
|
|
2
3
|
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
3
4
|
import { registerInstrumentations } from '@opentelemetry/instrumentation';
|
|
4
5
|
import { getWebAutoInstrumentations } from '@opentelemetry/auto-instrumentations-web';
|
|
5
6
|
import { ZoneContextManager } from '@opentelemetry/context-zone';
|
|
6
|
-
import { Data, Context, Effect, Layer } from 'effect';
|
|
7
7
|
import { FileSystem } from '@effect/platform/FileSystem';
|
|
8
8
|
import * as HttpClient from '@effect/platform/HttpClient';
|
|
9
9
|
import * as HttpClientRequest from '@effect/platform/HttpClientRequest';
|
|
@@ -4539,92 +4539,34 @@ var PatternSpanProcessor = class {
|
|
|
4539
4539
|
|
|
4540
4540
|
// src/core/sdk-initializer.ts
|
|
4541
4541
|
var sdkInstance = null;
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
const yamlStrategy = config?.http?.propagate_trace_context?.strategy;
|
|
4545
|
-
const yamlIncludeUrls = config?.http?.propagate_trace_context?.include_urls;
|
|
4546
|
-
let effectiveStrategy;
|
|
4547
|
-
let patterns = [];
|
|
4548
|
-
if (apiOption !== void 0) {
|
|
4549
|
-
if (typeof apiOption === "string") {
|
|
4550
|
-
effectiveStrategy = apiOption;
|
|
4551
|
-
} else {
|
|
4552
|
-
effectiveStrategy = "patterns";
|
|
4553
|
-
patterns = apiOption;
|
|
4554
|
-
}
|
|
4555
|
-
} else if (yamlStrategy) {
|
|
4556
|
-
effectiveStrategy = yamlStrategy;
|
|
4557
|
-
if (effectiveStrategy === "patterns" && yamlIncludeUrls) {
|
|
4558
|
-
patterns = yamlIncludeUrls;
|
|
4559
|
-
}
|
|
4560
|
-
} else {
|
|
4561
|
-
effectiveStrategy = "same-origin";
|
|
4562
|
-
}
|
|
4563
|
-
switch (effectiveStrategy) {
|
|
4564
|
-
case "all":
|
|
4565
|
-
return [/.*/];
|
|
4566
|
-
case "none":
|
|
4567
|
-
case "same-origin":
|
|
4568
|
-
return [];
|
|
4569
|
-
case "patterns": {
|
|
4570
|
-
const regexes = [];
|
|
4571
|
-
for (const pattern of patterns) {
|
|
4572
|
-
try {
|
|
4573
|
-
regexes.push(new RegExp(pattern));
|
|
4574
|
-
} catch (error) {
|
|
4575
|
-
console.warn(
|
|
4576
|
-
`[@atrim/instrument-web] Invalid trace propagation pattern: "${pattern}"`,
|
|
4577
|
-
error
|
|
4578
|
-
);
|
|
4579
|
-
}
|
|
4580
|
-
}
|
|
4581
|
-
return regexes;
|
|
4582
|
-
}
|
|
4583
|
-
default:
|
|
4584
|
-
console.warn(
|
|
4585
|
-
`[@atrim/instrument-web] Unknown trace propagation strategy: "${effectiveStrategy}". Defaulting to same-origin only.`
|
|
4586
|
-
);
|
|
4587
|
-
return [];
|
|
4588
|
-
}
|
|
4589
|
-
}
|
|
4590
|
-
async function initializeSdk(options) {
|
|
4542
|
+
var initializationDeferred = null;
|
|
4543
|
+
var initializeSdkEffect = (options) => Effect.gen(function* () {
|
|
4591
4544
|
if (sdkInstance) {
|
|
4592
4545
|
return sdkInstance;
|
|
4593
4546
|
}
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
`[@atrim/instrument-web] Invalid ignore_outgoing_urls pattern: "${pattern}"`,
|
|
4618
|
-
error
|
|
4619
|
-
);
|
|
4620
|
-
}
|
|
4621
|
-
}
|
|
4622
|
-
} else {
|
|
4623
|
-
console.warn(
|
|
4624
|
-
"[@atrim/instrument-web] Missing http.ignore_outgoing_urls in instrumentation.yaml. Using default OTLP endpoint patterns only. Consider adding http filtering to your config for better control."
|
|
4625
|
-
);
|
|
4626
|
-
}
|
|
4627
|
-
const propagateTraceUrls = buildPropagateTraceUrls(options, config);
|
|
4547
|
+
if (initializationDeferred) {
|
|
4548
|
+
return yield* Deferred.await(initializationDeferred);
|
|
4549
|
+
}
|
|
4550
|
+
const deferred = yield* Deferred.make();
|
|
4551
|
+
initializationDeferred = deferred;
|
|
4552
|
+
const result = yield* performInitializationEffect(options).pipe(
|
|
4553
|
+
Effect.tap((provider) => Deferred.succeed(deferred, provider)),
|
|
4554
|
+
Effect.tapError((error) => Deferred.fail(deferred, error)),
|
|
4555
|
+
Effect.ensuring(
|
|
4556
|
+
Effect.sync(() => {
|
|
4557
|
+
initializationDeferred = null;
|
|
4558
|
+
})
|
|
4559
|
+
)
|
|
4560
|
+
);
|
|
4561
|
+
return result;
|
|
4562
|
+
});
|
|
4563
|
+
var performInitializationEffect = (options) => Effect.gen(function* () {
|
|
4564
|
+
const config = yield* loadConfigEffect(options);
|
|
4565
|
+
if (config) {
|
|
4566
|
+
initializePatternMatcher(config);
|
|
4567
|
+
}
|
|
4568
|
+
const ignoreUrls = buildIgnoreUrls(config);
|
|
4569
|
+
const exporter = yield* Effect.sync(() => {
|
|
4628
4570
|
const exporterOptions = {};
|
|
4629
4571
|
if (options.otlpEndpoint) {
|
|
4630
4572
|
exporterOptions.endpoint = options.otlpEndpoint;
|
|
@@ -4632,18 +4574,23 @@ async function initializeSdk(options) {
|
|
|
4632
4574
|
if (options.otlpHeaders) {
|
|
4633
4575
|
exporterOptions.headers = options.otlpHeaders;
|
|
4634
4576
|
}
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4577
|
+
return createOtlpExporter(exporterOptions);
|
|
4578
|
+
});
|
|
4579
|
+
const spanProcessors = [];
|
|
4580
|
+
if (config) {
|
|
4581
|
+
spanProcessors.push(new PatternSpanProcessor());
|
|
4582
|
+
}
|
|
4583
|
+
spanProcessors.push(new SimpleSpanProcessor(exporter));
|
|
4584
|
+
const provider = yield* Effect.sync(() => {
|
|
4585
|
+
const p = new WebTracerProvider({
|
|
4642
4586
|
spanProcessors
|
|
4643
4587
|
});
|
|
4644
|
-
|
|
4588
|
+
p.register({
|
|
4645
4589
|
contextManager: new ZoneContextManager()
|
|
4646
4590
|
});
|
|
4591
|
+
return p;
|
|
4592
|
+
});
|
|
4593
|
+
yield* Effect.sync(() => {
|
|
4647
4594
|
registerInstrumentations({
|
|
4648
4595
|
instrumentations: [
|
|
4649
4596
|
getWebAutoInstrumentations({
|
|
@@ -4656,25 +4603,69 @@ async function initializeSdk(options) {
|
|
|
4656
4603
|
},
|
|
4657
4604
|
"@opentelemetry/instrumentation-fetch": {
|
|
4658
4605
|
enabled: options.enableFetch ?? true,
|
|
4659
|
-
propagateTraceHeaderCorsUrls:
|
|
4660
|
-
//
|
|
4606
|
+
propagateTraceHeaderCorsUrls: [/.*/],
|
|
4607
|
+
// Propagate to all origins
|
|
4661
4608
|
clearTimingResources: true,
|
|
4662
4609
|
ignoreUrls
|
|
4663
4610
|
// Prevent self-instrumentation of OTLP exports
|
|
4664
4611
|
},
|
|
4665
4612
|
"@opentelemetry/instrumentation-xml-http-request": {
|
|
4666
4613
|
enabled: options.enableXhr ?? true,
|
|
4667
|
-
propagateTraceHeaderCorsUrls:
|
|
4668
|
-
// Controlled by config/API
|
|
4614
|
+
propagateTraceHeaderCorsUrls: [/.*/]
|
|
4669
4615
|
}
|
|
4670
4616
|
})
|
|
4671
4617
|
]
|
|
4672
4618
|
});
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4619
|
+
});
|
|
4620
|
+
sdkInstance = provider;
|
|
4621
|
+
return provider;
|
|
4622
|
+
});
|
|
4623
|
+
var loadConfigEffect = (options) => Effect.gen(function* () {
|
|
4624
|
+
if (options.config) {
|
|
4625
|
+
return yield* Effect.tryPromise({
|
|
4626
|
+
try: () => loadConfigFromInline(options.config),
|
|
4627
|
+
catch: (error) => new InitializationError({
|
|
4628
|
+
reason: "Failed to load inline config",
|
|
4629
|
+
cause: error
|
|
4630
|
+
})
|
|
4631
|
+
});
|
|
4677
4632
|
}
|
|
4633
|
+
if (options.configPath || options.configUrl) {
|
|
4634
|
+
const url = options.configUrl || options.configPath;
|
|
4635
|
+
return yield* Effect.tryPromise({
|
|
4636
|
+
try: () => loadConfig(url),
|
|
4637
|
+
catch: (error) => new InitializationError({
|
|
4638
|
+
reason: `Failed to load config from ${url}`,
|
|
4639
|
+
cause: error
|
|
4640
|
+
})
|
|
4641
|
+
});
|
|
4642
|
+
}
|
|
4643
|
+
return null;
|
|
4644
|
+
});
|
|
4645
|
+
function buildIgnoreUrls(config) {
|
|
4646
|
+
const ignoreUrls = [
|
|
4647
|
+
// Always ignore standard OTLP endpoints (prevents infinite loops)
|
|
4648
|
+
/\/v1\/traces$/,
|
|
4649
|
+
/\/v1\/metrics$/,
|
|
4650
|
+
/\/v1\/logs$/
|
|
4651
|
+
];
|
|
4652
|
+
if (config?.http?.ignore_outgoing_urls) {
|
|
4653
|
+
for (const pattern of config.http.ignore_outgoing_urls) {
|
|
4654
|
+
try {
|
|
4655
|
+
ignoreUrls.push(new RegExp(pattern));
|
|
4656
|
+
} catch (error) {
|
|
4657
|
+
console.warn(
|
|
4658
|
+
`[@atrim/instrument-web] Invalid ignore_outgoing_urls pattern: "${pattern}"`,
|
|
4659
|
+
error
|
|
4660
|
+
);
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
} else {
|
|
4664
|
+
console.warn(
|
|
4665
|
+
"[@atrim/instrument-web] Missing http.ignore_outgoing_urls in instrumentation.yaml. Using default OTLP endpoint patterns only. Consider adding http filtering to your config for better control."
|
|
4666
|
+
);
|
|
4667
|
+
}
|
|
4668
|
+
return ignoreUrls;
|
|
4678
4669
|
}
|
|
4679
4670
|
function getSdkInstance() {
|
|
4680
4671
|
return sdkInstance;
|
|
@@ -4687,12 +4678,11 @@ async function shutdownSdk() {
|
|
|
4687
4678
|
}
|
|
4688
4679
|
function resetSdk() {
|
|
4689
4680
|
sdkInstance = null;
|
|
4681
|
+
initializationDeferred = null;
|
|
4690
4682
|
}
|
|
4691
4683
|
|
|
4692
4684
|
// src/api.ts
|
|
4693
|
-
|
|
4694
|
-
return await initializeSdk(options);
|
|
4695
|
-
}
|
|
4685
|
+
var initializeInstrumentation = (options) => initializeSdkEffect(options);
|
|
4696
4686
|
function setSpanAttributes(span, attributes) {
|
|
4697
4687
|
for (const [key, value] of Object.entries(attributes)) {
|
|
4698
4688
|
span.setAttribute(key, value);
|