@atrim/instrument-node 0.5.0 → 0.5.1-21bb978-20260105202350
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/README.md +73 -274
- package/package.json +20 -19
- package/target/dist/index.cjs +155 -60
- package/target/dist/index.cjs.map +1 -1
- package/target/dist/index.d.cts +28 -13
- package/target/dist/index.d.ts +28 -13
- package/target/dist/index.js +154 -60
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/index.cjs +346 -130
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.d.cts +335 -36
- package/target/dist/integrations/effect/index.d.ts +335 -36
- package/target/dist/integrations/effect/index.js +340 -134
- package/target/dist/integrations/effect/index.js.map +1 -1
package/target/dist/index.d.cts
CHANGED
|
@@ -46,35 +46,33 @@ declare function createOtlpExporter(options?: OtlpExporterOptions): OTLPTraceExp
|
|
|
46
46
|
declare function getOtlpEndpoint(options?: OtlpExporterOptions): string;
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* Node.js configuration loader
|
|
49
|
+
* Node.js configuration loader
|
|
50
50
|
*
|
|
51
|
-
* Provides
|
|
51
|
+
* Provides configuration loading using native Node.js APIs (fs, fetch)
|
|
52
|
+
* This module doesn't require Effect Platform, making it work without Effect installed.
|
|
52
53
|
*/
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
|
-
*
|
|
56
|
-
* @internal
|
|
57
|
-
*/
|
|
58
|
-
declare function _resetConfigLoaderCache(): void;
|
|
59
|
-
/**
|
|
60
|
-
* Load configuration from URI (Promise-based convenience API)
|
|
61
|
-
*
|
|
62
|
-
* Automatically provides Node.js platform layers (FileSystem + HttpClient)
|
|
56
|
+
* Load configuration from URI (file path or URL)
|
|
63
57
|
*
|
|
64
58
|
* @param uri - Configuration URI (file://, http://, https://, or relative path)
|
|
65
|
-
* @param options - Optional loading options (e.g., to disable caching)
|
|
66
59
|
* @returns Promise that resolves to validated configuration
|
|
67
60
|
*/
|
|
68
|
-
declare function loadConfig(uri: string,
|
|
61
|
+
declare function loadConfig(uri: string, _options?: {
|
|
69
62
|
cacheTimeout?: number;
|
|
70
63
|
}): Promise<InstrumentationConfig>;
|
|
71
64
|
/**
|
|
72
|
-
* Load configuration from inline content
|
|
65
|
+
* Load configuration from inline content
|
|
73
66
|
*
|
|
74
67
|
* @param content - YAML string, JSON string, or plain object
|
|
75
68
|
* @returns Promise that resolves to validated configuration
|
|
76
69
|
*/
|
|
77
70
|
declare function loadConfigFromInline(content: string | unknown): Promise<InstrumentationConfig>;
|
|
71
|
+
/**
|
|
72
|
+
* Reset the config loader cache (no-op for native implementation)
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
declare function _resetConfigLoaderCache(): void;
|
|
78
76
|
/**
|
|
79
77
|
* Legacy options interface for backward compatibility
|
|
80
78
|
*/
|
|
@@ -548,6 +546,10 @@ declare function getServiceVersionAsync(): Promise<string | undefined>;
|
|
|
548
546
|
* This processor filters spans based on configured patterns before they are exported.
|
|
549
547
|
* It wraps another processor (typically BatchSpanProcessor) and only forwards spans
|
|
550
548
|
* that match the instrumentation patterns.
|
|
549
|
+
*
|
|
550
|
+
* Filtering is applied at two levels:
|
|
551
|
+
* 1. Span name patterns (instrument_patterns / ignore_patterns)
|
|
552
|
+
* 2. HTTP path patterns (http.ignore_incoming_paths) - for HTTP spans
|
|
551
553
|
*/
|
|
552
554
|
|
|
553
555
|
/**
|
|
@@ -570,6 +572,7 @@ declare function getServiceVersionAsync(): Promise<string | undefined>;
|
|
|
570
572
|
declare class PatternSpanProcessor implements SpanProcessor {
|
|
571
573
|
private matcher;
|
|
572
574
|
private wrappedProcessor;
|
|
575
|
+
private httpIgnorePatterns;
|
|
573
576
|
constructor(config: InstrumentationConfig, wrappedProcessor: SpanProcessor);
|
|
574
577
|
/**
|
|
575
578
|
* Called when a span is started
|
|
@@ -582,8 +585,20 @@ declare class PatternSpanProcessor implements SpanProcessor {
|
|
|
582
585
|
* Called when a span is ended
|
|
583
586
|
*
|
|
584
587
|
* This is where we make the final decision on whether to export the span.
|
|
588
|
+
* We check both span name patterns and HTTP path patterns.
|
|
585
589
|
*/
|
|
586
590
|
onEnd(span: ReadableSpan): void;
|
|
591
|
+
/**
|
|
592
|
+
* Check if span should be ignored based on HTTP path attributes
|
|
593
|
+
*
|
|
594
|
+
* This checks the span's url.path, http.route, or http.target attributes
|
|
595
|
+
* against the configured http.ignore_incoming_paths patterns.
|
|
596
|
+
*
|
|
597
|
+
* This enables filtering of Effect HTTP spans (and any other HTTP spans)
|
|
598
|
+
* based on path patterns, which is essential for filtering out OTLP
|
|
599
|
+
* endpoint requests like /v1/traces, /v1/logs, /v1/metrics.
|
|
600
|
+
*/
|
|
601
|
+
private shouldIgnoreHttpSpan;
|
|
587
602
|
/**
|
|
588
603
|
* Shutdown the processor
|
|
589
604
|
*/
|
package/target/dist/index.d.ts
CHANGED
|
@@ -46,35 +46,33 @@ declare function createOtlpExporter(options?: OtlpExporterOptions): OTLPTraceExp
|
|
|
46
46
|
declare function getOtlpEndpoint(options?: OtlpExporterOptions): string;
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* Node.js configuration loader
|
|
49
|
+
* Node.js configuration loader
|
|
50
50
|
*
|
|
51
|
-
* Provides
|
|
51
|
+
* Provides configuration loading using native Node.js APIs (fs, fetch)
|
|
52
|
+
* This module doesn't require Effect Platform, making it work without Effect installed.
|
|
52
53
|
*/
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
|
-
*
|
|
56
|
-
* @internal
|
|
57
|
-
*/
|
|
58
|
-
declare function _resetConfigLoaderCache(): void;
|
|
59
|
-
/**
|
|
60
|
-
* Load configuration from URI (Promise-based convenience API)
|
|
61
|
-
*
|
|
62
|
-
* Automatically provides Node.js platform layers (FileSystem + HttpClient)
|
|
56
|
+
* Load configuration from URI (file path or URL)
|
|
63
57
|
*
|
|
64
58
|
* @param uri - Configuration URI (file://, http://, https://, or relative path)
|
|
65
|
-
* @param options - Optional loading options (e.g., to disable caching)
|
|
66
59
|
* @returns Promise that resolves to validated configuration
|
|
67
60
|
*/
|
|
68
|
-
declare function loadConfig(uri: string,
|
|
61
|
+
declare function loadConfig(uri: string, _options?: {
|
|
69
62
|
cacheTimeout?: number;
|
|
70
63
|
}): Promise<InstrumentationConfig>;
|
|
71
64
|
/**
|
|
72
|
-
* Load configuration from inline content
|
|
65
|
+
* Load configuration from inline content
|
|
73
66
|
*
|
|
74
67
|
* @param content - YAML string, JSON string, or plain object
|
|
75
68
|
* @returns Promise that resolves to validated configuration
|
|
76
69
|
*/
|
|
77
70
|
declare function loadConfigFromInline(content: string | unknown): Promise<InstrumentationConfig>;
|
|
71
|
+
/**
|
|
72
|
+
* Reset the config loader cache (no-op for native implementation)
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
declare function _resetConfigLoaderCache(): void;
|
|
78
76
|
/**
|
|
79
77
|
* Legacy options interface for backward compatibility
|
|
80
78
|
*/
|
|
@@ -548,6 +546,10 @@ declare function getServiceVersionAsync(): Promise<string | undefined>;
|
|
|
548
546
|
* This processor filters spans based on configured patterns before they are exported.
|
|
549
547
|
* It wraps another processor (typically BatchSpanProcessor) and only forwards spans
|
|
550
548
|
* that match the instrumentation patterns.
|
|
549
|
+
*
|
|
550
|
+
* Filtering is applied at two levels:
|
|
551
|
+
* 1. Span name patterns (instrument_patterns / ignore_patterns)
|
|
552
|
+
* 2. HTTP path patterns (http.ignore_incoming_paths) - for HTTP spans
|
|
551
553
|
*/
|
|
552
554
|
|
|
553
555
|
/**
|
|
@@ -570,6 +572,7 @@ declare function getServiceVersionAsync(): Promise<string | undefined>;
|
|
|
570
572
|
declare class PatternSpanProcessor implements SpanProcessor {
|
|
571
573
|
private matcher;
|
|
572
574
|
private wrappedProcessor;
|
|
575
|
+
private httpIgnorePatterns;
|
|
573
576
|
constructor(config: InstrumentationConfig, wrappedProcessor: SpanProcessor);
|
|
574
577
|
/**
|
|
575
578
|
* Called when a span is started
|
|
@@ -582,8 +585,20 @@ declare class PatternSpanProcessor implements SpanProcessor {
|
|
|
582
585
|
* Called when a span is ended
|
|
583
586
|
*
|
|
584
587
|
* This is where we make the final decision on whether to export the span.
|
|
588
|
+
* We check both span name patterns and HTTP path patterns.
|
|
585
589
|
*/
|
|
586
590
|
onEnd(span: ReadableSpan): void;
|
|
591
|
+
/**
|
|
592
|
+
* Check if span should be ignored based on HTTP path attributes
|
|
593
|
+
*
|
|
594
|
+
* This checks the span's url.path, http.route, or http.target attributes
|
|
595
|
+
* against the configured http.ignore_incoming_paths patterns.
|
|
596
|
+
*
|
|
597
|
+
* This enables filtering of Effect HTTP spans (and any other HTTP spans)
|
|
598
|
+
* based on path patterns, which is essential for filtering out OTLP
|
|
599
|
+
* endpoint requests like /v1/traces, /v1/logs, /v1/metrics.
|
|
600
|
+
*/
|
|
601
|
+
private shouldIgnoreHttpSpan;
|
|
587
602
|
/**
|
|
588
603
|
* Shutdown the processor
|
|
589
604
|
*/
|
package/target/dist/index.js
CHANGED
|
@@ -11,8 +11,7 @@ import { z } from 'zod';
|
|
|
11
11
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
12
12
|
import { readFile } from 'fs/promises';
|
|
13
13
|
import { join } from 'path';
|
|
14
|
-
import {
|
|
15
|
-
import { FetchHttpClient } from '@effect/platform';
|
|
14
|
+
import { createRequire } from 'module';
|
|
16
15
|
|
|
17
16
|
var __defProp = Object.defineProperty;
|
|
18
17
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -59,7 +58,20 @@ var HttpFilteringConfigSchema = z.object({
|
|
|
59
58
|
// Patterns to ignore for incoming HTTP requests (string patterns only in YAML)
|
|
60
59
|
ignore_incoming_paths: z.array(z.string()).optional(),
|
|
61
60
|
// Require parent span for outgoing requests (prevents root spans for HTTP calls)
|
|
62
|
-
require_parent_for_outgoing_spans: z.boolean().optional()
|
|
61
|
+
require_parent_for_outgoing_spans: z.boolean().optional(),
|
|
62
|
+
// Trace context propagation configuration
|
|
63
|
+
// Controls which cross-origin requests receive W3C Trace Context headers (traceparent, tracestate)
|
|
64
|
+
propagate_trace_context: z.object({
|
|
65
|
+
// Strategy for trace propagation
|
|
66
|
+
// - "all": Propagate to all cross-origin requests (may cause CORS errors)
|
|
67
|
+
// - "none": Never propagate trace headers
|
|
68
|
+
// - "same-origin": Only propagate to same-origin requests (default, safe)
|
|
69
|
+
// - "patterns": Propagate based on include_urls patterns
|
|
70
|
+
strategy: z.enum(["all", "none", "same-origin", "patterns"]).default("same-origin"),
|
|
71
|
+
// URL patterns to include when strategy is "patterns"
|
|
72
|
+
// Supports regex patterns (e.g., "^https://api\\.myapp\\.com")
|
|
73
|
+
include_urls: z.array(z.string()).optional()
|
|
74
|
+
}).optional()
|
|
63
75
|
});
|
|
64
76
|
var InstrumentationConfigSchema = z.object({
|
|
65
77
|
version: z.string(),
|
|
@@ -71,11 +83,56 @@ var InstrumentationConfigSchema = z.object({
|
|
|
71
83
|
ignore_patterns: z.array(PatternConfigSchema)
|
|
72
84
|
}),
|
|
73
85
|
effect: z.object({
|
|
86
|
+
// Enable/disable Effect tracing entirely
|
|
87
|
+
// When false, EffectInstrumentationLive returns Layer.empty
|
|
88
|
+
enabled: z.boolean().default(true),
|
|
89
|
+
// Exporter mode:
|
|
90
|
+
// - "unified": Use global TracerProvider from Node SDK (recommended, enables filtering)
|
|
91
|
+
// - "standalone": Use Effect's own OTLP exporter (bypasses Node SDK filtering)
|
|
92
|
+
exporter: z.enum(["unified", "standalone"]).default("unified"),
|
|
74
93
|
auto_extract_metadata: z.boolean(),
|
|
94
|
+
// Auto-bridge OpenTelemetry context to Effect spans
|
|
95
|
+
// When true, Effect spans automatically become children of the active OTel span
|
|
96
|
+
// (e.g., HTTP request span from auto-instrumentation)
|
|
97
|
+
// This is essential for proper trace hierarchy when using Effect with HTTP frameworks
|
|
98
|
+
auto_bridge_context: z.boolean().default(true),
|
|
75
99
|
auto_isolation: AutoIsolationConfigSchema.optional()
|
|
76
100
|
}).optional(),
|
|
77
101
|
http: HttpFilteringConfigSchema.optional()
|
|
78
102
|
});
|
|
103
|
+
var defaultConfig = {
|
|
104
|
+
version: "1.0",
|
|
105
|
+
instrumentation: {
|
|
106
|
+
enabled: true,
|
|
107
|
+
logging: "on",
|
|
108
|
+
description: "Default instrumentation configuration",
|
|
109
|
+
instrument_patterns: [
|
|
110
|
+
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
111
|
+
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
112
|
+
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
113
|
+
],
|
|
114
|
+
ignore_patterns: [
|
|
115
|
+
{ pattern: "^test\\.", description: "Test utilities" },
|
|
116
|
+
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
117
|
+
{ pattern: "^health\\.", description: "Health checks" }
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
effect: {
|
|
121
|
+
enabled: true,
|
|
122
|
+
exporter: "unified",
|
|
123
|
+
auto_extract_metadata: true,
|
|
124
|
+
auto_bridge_context: true
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
function parseAndValidateConfig(content) {
|
|
128
|
+
let parsed;
|
|
129
|
+
if (typeof content === "string") {
|
|
130
|
+
parsed = parse(content);
|
|
131
|
+
} else {
|
|
132
|
+
parsed = content;
|
|
133
|
+
}
|
|
134
|
+
return InstrumentationConfigSchema.parse(parsed);
|
|
135
|
+
}
|
|
79
136
|
(class extends Data.TaggedError("ConfigError") {
|
|
80
137
|
get message() {
|
|
81
138
|
return this.reason;
|
|
@@ -253,7 +310,7 @@ var makeConfigLoader = Effect.gen(function* () {
|
|
|
253
310
|
})
|
|
254
311
|
});
|
|
255
312
|
});
|
|
256
|
-
|
|
313
|
+
Layer.effect(ConfigLoader, makeConfigLoader);
|
|
257
314
|
var PatternMatcher = class {
|
|
258
315
|
constructor(config) {
|
|
259
316
|
__publicField2(this, "ignorePatterns", []);
|
|
@@ -417,8 +474,14 @@ var PatternSpanProcessor = class {
|
|
|
417
474
|
constructor(config, wrappedProcessor) {
|
|
418
475
|
__publicField(this, "matcher");
|
|
419
476
|
__publicField(this, "wrappedProcessor");
|
|
477
|
+
__publicField(this, "httpIgnorePatterns", []);
|
|
420
478
|
this.matcher = new PatternMatcher(config);
|
|
421
479
|
this.wrappedProcessor = wrappedProcessor;
|
|
480
|
+
if (config.http?.ignore_incoming_paths) {
|
|
481
|
+
this.httpIgnorePatterns = config.http.ignore_incoming_paths.map(
|
|
482
|
+
(pattern) => new RegExp(pattern)
|
|
483
|
+
);
|
|
484
|
+
}
|
|
422
485
|
}
|
|
423
486
|
/**
|
|
424
487
|
* Called when a span is started
|
|
@@ -436,12 +499,40 @@ var PatternSpanProcessor = class {
|
|
|
436
499
|
* Called when a span is ended
|
|
437
500
|
*
|
|
438
501
|
* This is where we make the final decision on whether to export the span.
|
|
502
|
+
* We check both span name patterns and HTTP path patterns.
|
|
439
503
|
*/
|
|
440
504
|
onEnd(span) {
|
|
441
505
|
const spanName = span.name;
|
|
442
|
-
if (this.matcher.shouldInstrument(spanName)) {
|
|
443
|
-
|
|
506
|
+
if (!this.matcher.shouldInstrument(spanName)) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
if (this.shouldIgnoreHttpSpan(span)) {
|
|
510
|
+
return;
|
|
444
511
|
}
|
|
512
|
+
this.wrappedProcessor.onEnd(span);
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Check if span should be ignored based on HTTP path attributes
|
|
516
|
+
*
|
|
517
|
+
* This checks the span's url.path, http.route, or http.target attributes
|
|
518
|
+
* against the configured http.ignore_incoming_paths patterns.
|
|
519
|
+
*
|
|
520
|
+
* This enables filtering of Effect HTTP spans (and any other HTTP spans)
|
|
521
|
+
* based on path patterns, which is essential for filtering out OTLP
|
|
522
|
+
* endpoint requests like /v1/traces, /v1/logs, /v1/metrics.
|
|
523
|
+
*/
|
|
524
|
+
shouldIgnoreHttpSpan(span) {
|
|
525
|
+
if (this.httpIgnorePatterns.length === 0) {
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
const urlPath = span.attributes["url.path"];
|
|
529
|
+
const httpRoute = span.attributes["http.route"];
|
|
530
|
+
const httpTarget = span.attributes["http.target"];
|
|
531
|
+
const pathToCheck = urlPath || httpRoute || httpTarget;
|
|
532
|
+
if (!pathToCheck) {
|
|
533
|
+
return false;
|
|
534
|
+
}
|
|
535
|
+
return this.httpIgnorePatterns.some((pattern) => pattern.test(pathToCheck));
|
|
445
536
|
}
|
|
446
537
|
/**
|
|
447
538
|
* Shutdown the processor
|
|
@@ -679,83 +770,55 @@ async function getServiceNameAsync() {
|
|
|
679
770
|
async function getServiceVersionAsync() {
|
|
680
771
|
return Effect.runPromise(getServiceVersion);
|
|
681
772
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
);
|
|
685
|
-
|
|
686
|
-
function getCachedLoader() {
|
|
687
|
-
if (!cachedLoaderPromise) {
|
|
688
|
-
cachedLoaderPromise = Effect.runPromise(
|
|
689
|
-
Effect.gen(function* () {
|
|
690
|
-
return yield* ConfigLoader;
|
|
691
|
-
}).pipe(Effect.provide(NodeConfigLoaderLive))
|
|
692
|
-
);
|
|
693
|
-
}
|
|
694
|
-
return cachedLoaderPromise;
|
|
773
|
+
async function loadFromFile(filePath) {
|
|
774
|
+
const { readFile: readFile2 } = await import('fs/promises');
|
|
775
|
+
const content = await readFile2(filePath, "utf-8");
|
|
776
|
+
return parseAndValidateConfig(content);
|
|
695
777
|
}
|
|
696
|
-
function
|
|
697
|
-
|
|
778
|
+
async function loadFromUrl(url) {
|
|
779
|
+
const response = await fetch(url);
|
|
780
|
+
if (!response.ok) {
|
|
781
|
+
throw new Error(`Failed to fetch config from ${url}: ${response.statusText}`);
|
|
782
|
+
}
|
|
783
|
+
const content = await response.text();
|
|
784
|
+
return parseAndValidateConfig(content);
|
|
698
785
|
}
|
|
699
|
-
async function loadConfig(uri,
|
|
700
|
-
if (
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
return
|
|
786
|
+
async function loadConfig(uri, _options) {
|
|
787
|
+
if (uri.startsWith("http://") || uri.startsWith("https://")) {
|
|
788
|
+
return loadFromUrl(uri);
|
|
789
|
+
}
|
|
790
|
+
if (uri.startsWith("file://")) {
|
|
791
|
+
const filePath = uri.slice(7);
|
|
792
|
+
return loadFromFile(filePath);
|
|
706
793
|
}
|
|
707
|
-
|
|
708
|
-
return Effect.runPromise(loader.loadFromUri(uri));
|
|
794
|
+
return loadFromFile(uri);
|
|
709
795
|
}
|
|
710
796
|
async function loadConfigFromInline(content) {
|
|
711
|
-
|
|
712
|
-
return Effect.runPromise(loader.loadFromInline(content));
|
|
797
|
+
return parseAndValidateConfig(content);
|
|
713
798
|
}
|
|
714
|
-
function
|
|
715
|
-
return {
|
|
716
|
-
version: "1.0",
|
|
717
|
-
instrumentation: {
|
|
718
|
-
enabled: true,
|
|
719
|
-
logging: "on",
|
|
720
|
-
description: "Default instrumentation configuration",
|
|
721
|
-
instrument_patterns: [
|
|
722
|
-
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
723
|
-
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
724
|
-
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
725
|
-
],
|
|
726
|
-
ignore_patterns: [
|
|
727
|
-
{ pattern: "^test\\.", description: "Test utilities" },
|
|
728
|
-
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
729
|
-
{ pattern: "^health\\.", description: "Health checks" }
|
|
730
|
-
]
|
|
731
|
-
},
|
|
732
|
-
effect: {
|
|
733
|
-
auto_extract_metadata: true
|
|
734
|
-
}
|
|
735
|
-
};
|
|
799
|
+
function _resetConfigLoaderCache() {
|
|
736
800
|
}
|
|
737
801
|
async function loadConfigWithOptions(options = {}) {
|
|
738
|
-
const loadOptions = options.cacheTimeout !== void 0 ? { cacheTimeout: options.cacheTimeout } : void 0;
|
|
739
802
|
if (options.config) {
|
|
740
803
|
return loadConfigFromInline(options.config);
|
|
741
804
|
}
|
|
742
805
|
const envConfigPath = process.env.ATRIM_INSTRUMENTATION_CONFIG;
|
|
743
806
|
if (envConfigPath) {
|
|
744
|
-
return loadConfig(envConfigPath
|
|
807
|
+
return loadConfig(envConfigPath);
|
|
745
808
|
}
|
|
746
809
|
if (options.configUrl) {
|
|
747
|
-
return loadConfig(options.configUrl
|
|
810
|
+
return loadConfig(options.configUrl);
|
|
748
811
|
}
|
|
749
812
|
if (options.configPath) {
|
|
750
|
-
return loadConfig(options.configPath
|
|
813
|
+
return loadConfig(options.configPath);
|
|
751
814
|
}
|
|
752
815
|
const { existsSync } = await import('fs');
|
|
753
816
|
const { join: join2 } = await import('path');
|
|
754
817
|
const defaultPath = join2(process.cwd(), "instrumentation.yaml");
|
|
755
818
|
if (existsSync(defaultPath)) {
|
|
756
|
-
return loadConfig(defaultPath
|
|
819
|
+
return loadConfig(defaultPath);
|
|
757
820
|
}
|
|
758
|
-
return
|
|
821
|
+
return defaultConfig;
|
|
759
822
|
}
|
|
760
823
|
|
|
761
824
|
// src/core/sdk-initializer.ts
|
|
@@ -1047,9 +1110,39 @@ function logInitialization(config, serviceName, serviceVersion, options, autoIns
|
|
|
1047
1110
|
logger.log(` - OTLP endpoint: ${endpoint}`);
|
|
1048
1111
|
logger.log("");
|
|
1049
1112
|
}
|
|
1113
|
+
var require2 = createRequire(import.meta.url);
|
|
1114
|
+
function validateOpenTelemetryApi() {
|
|
1115
|
+
try {
|
|
1116
|
+
require2.resolve("@opentelemetry/api");
|
|
1117
|
+
} catch {
|
|
1118
|
+
throw new Error(
|
|
1119
|
+
"@atrim/instrument-node requires @opentelemetry/api as a peer dependency.\n\nInstall it with:\n npm install @opentelemetry/api\n\nOr with your preferred package manager:\n pnpm add @opentelemetry/api\n yarn add @opentelemetry/api\n bun add @opentelemetry/api"
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
function validateEffectDependencies() {
|
|
1124
|
+
const packages = ["effect", "@effect/opentelemetry", "@effect/platform"];
|
|
1125
|
+
for (const pkg of packages) {
|
|
1126
|
+
try {
|
|
1127
|
+
require2.resolve(pkg);
|
|
1128
|
+
} catch {
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
var validateDependencies = Effect.try({
|
|
1135
|
+
try: () => validateOpenTelemetryApi(),
|
|
1136
|
+
catch: (error) => new InitializationError2({
|
|
1137
|
+
reason: error instanceof Error ? error.message : "Dependency validation failed",
|
|
1138
|
+
cause: error
|
|
1139
|
+
})
|
|
1140
|
+
});
|
|
1141
|
+
Effect.sync(() => validateEffectDependencies());
|
|
1050
1142
|
|
|
1051
1143
|
// src/api.ts
|
|
1052
1144
|
async function initializeInstrumentation(options = {}) {
|
|
1145
|
+
validateOpenTelemetryApi();
|
|
1053
1146
|
const sdk = await initializeSdk(options);
|
|
1054
1147
|
if (sdk) {
|
|
1055
1148
|
const config = await loadConfigWithOptions(options);
|
|
@@ -1066,6 +1159,7 @@ async function initializePatternMatchingOnly(options = {}) {
|
|
|
1066
1159
|
);
|
|
1067
1160
|
}
|
|
1068
1161
|
var initializeInstrumentationEffect = (options = {}) => Effect.gen(function* () {
|
|
1162
|
+
yield* validateDependencies;
|
|
1069
1163
|
const sdk = yield* Effect.tryPromise({
|
|
1070
1164
|
try: () => initializeSdk(options),
|
|
1071
1165
|
catch: (error) => new InitializationError2({
|