@atrim/instrument-web 0.5.0-c05e3a1-20251119131241 → 0.5.0-cda80ad-20251119134818
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 +37 -22
- package/target/dist/index.js +103 -93
- 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';
|
|
2
1
|
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
|
|
3
|
-
import { InstrumentationConfig,
|
|
2
|
+
import { InstrumentationConfig, ConfigLoader } from '@atrim/instrument-core';
|
|
4
3
|
export { ConfigError, ConfigFileError, ConfigUrlError, ConfigValidationError, ExportError, InitializationError, InstrumentationConfig, PatternConfig, PatternMatcher, ShutdownError, clearPatternMatcher, getPatternMatcher, initializePatternMatcher, shouldInstrumentSpan } from '@atrim/instrument-core';
|
|
5
4
|
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,6 +70,31 @@ 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[];
|
|
73
98
|
}
|
|
74
99
|
/**
|
|
75
100
|
* Get the current SDK instance
|
|
@@ -103,47 +128,37 @@ declare function resetSdk(): void;
|
|
|
103
128
|
* Call this function once at application startup, before any other code runs.
|
|
104
129
|
*
|
|
105
130
|
* @param options - Initialization options
|
|
106
|
-
* @returns
|
|
131
|
+
* @returns WebTracerProvider instance
|
|
132
|
+
* @throws {Error} If initialization fails
|
|
107
133
|
*
|
|
108
134
|
* @example
|
|
109
135
|
* ```typescript
|
|
110
|
-
* import { Effect } from 'effect'
|
|
111
136
|
* import { initializeInstrumentation } from '@atrim/instrument-web'
|
|
112
137
|
*
|
|
113
|
-
*
|
|
138
|
+
* await initializeInstrumentation({
|
|
114
139
|
* serviceName: 'my-app',
|
|
115
140
|
* otlpEndpoint: 'http://localhost:4318/v1/traces'
|
|
116
141
|
* })
|
|
117
|
-
*
|
|
118
|
-
* await Effect.runPromise(program)
|
|
119
142
|
* ```
|
|
120
143
|
*
|
|
121
144
|
* @example With pattern-based filtering
|
|
122
145
|
* ```typescript
|
|
123
|
-
*
|
|
146
|
+
* await initializeInstrumentation({
|
|
124
147
|
* serviceName: 'my-app',
|
|
125
148
|
* configUrl: 'https://config.company.com/instrumentation.yaml'
|
|
126
149
|
* })
|
|
127
|
-
*
|
|
128
|
-
* await Effect.runPromise(program)
|
|
129
150
|
* ```
|
|
130
151
|
*
|
|
131
|
-
* @example
|
|
152
|
+
* @example Disable specific instrumentations
|
|
132
153
|
* ```typescript
|
|
133
|
-
*
|
|
154
|
+
* await initializeInstrumentation({
|
|
134
155
|
* serviceName: 'my-app',
|
|
135
|
-
* enableUserInteraction: false
|
|
136
|
-
*
|
|
137
|
-
*
|
|
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)
|
|
156
|
+
* enableUserInteraction: false, // Disable click tracking
|
|
157
|
+
* enableXhr: false // Disable XMLHttpRequest tracking
|
|
158
|
+
* })
|
|
144
159
|
* ```
|
|
145
160
|
*/
|
|
146
|
-
declare
|
|
161
|
+
declare function initializeInstrumentation(options: SdkInitializationOptions): Promise<WebTracerProvider>;
|
|
147
162
|
|
|
148
163
|
/**
|
|
149
164
|
* OTLP Exporter Factory for Browser
|
package/target/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Data, Context, Effect, Layer, Deferred } from 'effect';
|
|
2
1
|
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
|
|
3
2
|
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
4
3
|
import { registerInstrumentations } from '@opentelemetry/instrumentation';
|
|
5
4
|
import { getWebAutoInstrumentations } from '@opentelemetry/auto-instrumentations-web';
|
|
6
5
|
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,34 +4539,92 @@ var PatternSpanProcessor = class {
|
|
|
4539
4539
|
|
|
4540
4540
|
// src/core/sdk-initializer.ts
|
|
4541
4541
|
var sdkInstance = null;
|
|
4542
|
-
|
|
4543
|
-
|
|
4542
|
+
function buildPropagateTraceUrls(options, config) {
|
|
4543
|
+
const apiOption = options.propagateTraceContext;
|
|
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) {
|
|
4544
4591
|
if (sdkInstance) {
|
|
4545
4592
|
return sdkInstance;
|
|
4546
4593
|
}
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4594
|
+
try {
|
|
4595
|
+
let config = null;
|
|
4596
|
+
if (options.config) {
|
|
4597
|
+
config = await loadConfigFromInline(options.config);
|
|
4598
|
+
} else if (options.configPath || options.configUrl) {
|
|
4599
|
+
const url = options.configUrl || options.configPath;
|
|
4600
|
+
config = await loadConfig(url);
|
|
4601
|
+
}
|
|
4602
|
+
if (config) {
|
|
4603
|
+
initializePatternMatcher(config);
|
|
4604
|
+
}
|
|
4605
|
+
const ignoreUrls = [
|
|
4606
|
+
// Always ignore standard OTLP endpoints (prevents infinite loops)
|
|
4607
|
+
/\/v1\/traces$/,
|
|
4608
|
+
/\/v1\/metrics$/,
|
|
4609
|
+
/\/v1\/logs$/
|
|
4610
|
+
];
|
|
4611
|
+
if (config?.http?.ignore_outgoing_urls) {
|
|
4612
|
+
for (const pattern of config.http.ignore_outgoing_urls) {
|
|
4613
|
+
try {
|
|
4614
|
+
ignoreUrls.push(new RegExp(pattern));
|
|
4615
|
+
} catch (error) {
|
|
4616
|
+
console.warn(
|
|
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);
|
|
4570
4628
|
const exporterOptions = {};
|
|
4571
4629
|
if (options.otlpEndpoint) {
|
|
4572
4630
|
exporterOptions.endpoint = options.otlpEndpoint;
|
|
@@ -4574,23 +4632,18 @@ var performInitializationEffect = (options) => Effect.gen(function* () {
|
|
|
4574
4632
|
if (options.otlpHeaders) {
|
|
4575
4633
|
exporterOptions.headers = options.otlpHeaders;
|
|
4576
4634
|
}
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
const provider = yield* Effect.sync(() => {
|
|
4585
|
-
const p = new WebTracerProvider({
|
|
4635
|
+
const exporter = createOtlpExporter(exporterOptions);
|
|
4636
|
+
const spanProcessors = [];
|
|
4637
|
+
if (config) {
|
|
4638
|
+
spanProcessors.push(new PatternSpanProcessor());
|
|
4639
|
+
}
|
|
4640
|
+
spanProcessors.push(new SimpleSpanProcessor(exporter));
|
|
4641
|
+
const provider = new WebTracerProvider({
|
|
4586
4642
|
spanProcessors
|
|
4587
4643
|
});
|
|
4588
|
-
|
|
4644
|
+
provider.register({
|
|
4589
4645
|
contextManager: new ZoneContextManager()
|
|
4590
4646
|
});
|
|
4591
|
-
return p;
|
|
4592
|
-
});
|
|
4593
|
-
yield* Effect.sync(() => {
|
|
4594
4647
|
registerInstrumentations({
|
|
4595
4648
|
instrumentations: [
|
|
4596
4649
|
getWebAutoInstrumentations({
|
|
@@ -4603,69 +4656,25 @@ var performInitializationEffect = (options) => Effect.gen(function* () {
|
|
|
4603
4656
|
},
|
|
4604
4657
|
"@opentelemetry/instrumentation-fetch": {
|
|
4605
4658
|
enabled: options.enableFetch ?? true,
|
|
4606
|
-
propagateTraceHeaderCorsUrls:
|
|
4607
|
-
//
|
|
4659
|
+
propagateTraceHeaderCorsUrls: propagateTraceUrls,
|
|
4660
|
+
// Controlled by config/API
|
|
4608
4661
|
clearTimingResources: true,
|
|
4609
4662
|
ignoreUrls
|
|
4610
4663
|
// Prevent self-instrumentation of OTLP exports
|
|
4611
4664
|
},
|
|
4612
4665
|
"@opentelemetry/instrumentation-xml-http-request": {
|
|
4613
4666
|
enabled: options.enableXhr ?? true,
|
|
4614
|
-
propagateTraceHeaderCorsUrls:
|
|
4667
|
+
propagateTraceHeaderCorsUrls: propagateTraceUrls
|
|
4668
|
+
// Controlled by config/API
|
|
4615
4669
|
}
|
|
4616
4670
|
})
|
|
4617
4671
|
]
|
|
4618
4672
|
});
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
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
|
-
});
|
|
4673
|
+
sdkInstance = provider;
|
|
4674
|
+
return provider;
|
|
4675
|
+
} catch (error) {
|
|
4676
|
+
throw new Error(`Failed to initialize OpenTelemetry SDK: ${error}`);
|
|
4632
4677
|
}
|
|
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;
|
|
4669
4678
|
}
|
|
4670
4679
|
function getSdkInstance() {
|
|
4671
4680
|
return sdkInstance;
|
|
@@ -4678,11 +4687,12 @@ async function shutdownSdk() {
|
|
|
4678
4687
|
}
|
|
4679
4688
|
function resetSdk() {
|
|
4680
4689
|
sdkInstance = null;
|
|
4681
|
-
initializationDeferred = null;
|
|
4682
4690
|
}
|
|
4683
4691
|
|
|
4684
4692
|
// src/api.ts
|
|
4685
|
-
|
|
4693
|
+
async function initializeInstrumentation(options) {
|
|
4694
|
+
return await initializeSdk(options);
|
|
4695
|
+
}
|
|
4686
4696
|
function setSpanAttributes(span, attributes) {
|
|
4687
4697
|
for (const [key, value] of Object.entries(attributes)) {
|
|
4688
4698
|
span.setAttribute(key, value);
|