@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.
- package/README.md +92 -330
- package/package.json +25 -19
- package/target/dist/index.cjs +227 -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 +226 -60
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/auto/index.cjs +1181 -0
- package/target/dist/integrations/effect/auto/index.cjs.map +1 -0
- package/target/dist/integrations/effect/auto/index.d.cts +437 -0
- package/target/dist/integrations/effect/auto/index.d.ts +437 -0
- package/target/dist/integrations/effect/auto/index.js +1136 -0
- package/target/dist/integrations/effect/auto/index.js.map +1 -0
- package/target/dist/integrations/effect/index.cjs +231 -129
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.d.cts +19 -24
- package/target/dist/integrations/effect/index.d.ts +19 -24
- package/target/dist/integrations/effect/index.js +232 -132
- package/target/dist/integrations/effect/index.js.map +1 -1
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var effect = require('effect');
|
|
4
|
+
var Tracer = require('@effect/opentelemetry/Tracer');
|
|
5
|
+
var Resource = require('@effect/opentelemetry/Resource');
|
|
4
6
|
var Otlp = require('@effect/opentelemetry/Otlp');
|
|
5
7
|
var platform = require('@effect/platform');
|
|
6
8
|
var api = require('@opentelemetry/api');
|
|
9
|
+
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
7
10
|
var FileSystem = require('@effect/platform/FileSystem');
|
|
8
11
|
var HttpClient = require('@effect/platform/HttpClient');
|
|
9
12
|
var HttpClientRequest = require('@effect/platform/HttpClientRequest');
|
|
10
13
|
var yaml = require('yaml');
|
|
11
14
|
var zod = require('zod');
|
|
12
|
-
var platformNode = require('@effect/platform-node');
|
|
13
15
|
|
|
14
16
|
function _interopNamespace(e) {
|
|
15
17
|
if (e && e.__esModule) return e;
|
|
@@ -29,16 +31,13 @@ function _interopNamespace(e) {
|
|
|
29
31
|
return Object.freeze(n);
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
var Tracer__namespace = /*#__PURE__*/_interopNamespace(Tracer);
|
|
35
|
+
var Resource__namespace = /*#__PURE__*/_interopNamespace(Resource);
|
|
32
36
|
var Otlp__namespace = /*#__PURE__*/_interopNamespace(Otlp);
|
|
33
37
|
var HttpClient__namespace = /*#__PURE__*/_interopNamespace(HttpClient);
|
|
34
38
|
var HttpClientRequest__namespace = /*#__PURE__*/_interopNamespace(HttpClientRequest);
|
|
35
39
|
|
|
36
40
|
// src/integrations/effect/effect-tracer.ts
|
|
37
|
-
|
|
38
|
-
// ../../node_modules/.pnpm/@opentelemetry+semantic-conventions@1.38.0/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js
|
|
39
|
-
var ATTR_TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language";
|
|
40
|
-
var TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS = "nodejs";
|
|
41
|
-
var ATTR_TELEMETRY_SDK_NAME = "telemetry.sdk.name";
|
|
42
41
|
var __defProp = Object.defineProperty;
|
|
43
42
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
44
43
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -69,6 +68,69 @@ var AutoIsolationConfigSchema = zod.z.object({
|
|
|
69
68
|
add_metadata: zod.z.boolean().default(true)
|
|
70
69
|
}).default({})
|
|
71
70
|
});
|
|
71
|
+
var SpanNamingRuleSchema = zod.z.object({
|
|
72
|
+
// Match criteria (all specified criteria must match)
|
|
73
|
+
match: zod.z.object({
|
|
74
|
+
// Regex pattern to match file path
|
|
75
|
+
file: zod.z.string().optional(),
|
|
76
|
+
// Regex pattern to match function name
|
|
77
|
+
function: zod.z.string().optional(),
|
|
78
|
+
// Regex pattern to match module name
|
|
79
|
+
module: zod.z.string().optional()
|
|
80
|
+
}),
|
|
81
|
+
// Span name template with variables:
|
|
82
|
+
// {fiber_id} - Fiber ID
|
|
83
|
+
// {function} - Function name
|
|
84
|
+
// {module} - Module name
|
|
85
|
+
// {file} - File path
|
|
86
|
+
// {line} - Line number
|
|
87
|
+
// {operator} - Effect operator (gen, all, forEach, etc.)
|
|
88
|
+
// {match:field:N} - Captured regex group from match
|
|
89
|
+
name: zod.z.string()
|
|
90
|
+
});
|
|
91
|
+
var AutoInstrumentationConfigSchema = zod.z.object({
|
|
92
|
+
// Enable/disable auto-instrumentation
|
|
93
|
+
enabled: zod.z.boolean().default(false),
|
|
94
|
+
// Tracing granularity
|
|
95
|
+
// - 'fiber': Trace at fiber creation (recommended, lower overhead)
|
|
96
|
+
// - 'operator': Trace each Effect operator (higher granularity, more overhead)
|
|
97
|
+
granularity: zod.z.enum(["fiber", "operator"]).default("fiber"),
|
|
98
|
+
// Smart span naming configuration
|
|
99
|
+
span_naming: zod.z.object({
|
|
100
|
+
// Default span name template when no rules match
|
|
101
|
+
default: zod.z.string().default("effect.fiber.{fiber_id}"),
|
|
102
|
+
// Infer span names from source code (requires stack trace parsing)
|
|
103
|
+
// Adds ~50-100μs overhead per fiber
|
|
104
|
+
infer_from_source: zod.z.boolean().default(true),
|
|
105
|
+
// Naming rules (first match wins)
|
|
106
|
+
rules: zod.z.array(SpanNamingRuleSchema).default([])
|
|
107
|
+
}).default({}),
|
|
108
|
+
// Pattern-based filtering
|
|
109
|
+
filter: zod.z.object({
|
|
110
|
+
// Only trace spans matching these patterns (empty = trace all)
|
|
111
|
+
include: zod.z.array(zod.z.string()).default([]),
|
|
112
|
+
// Never trace spans matching these patterns
|
|
113
|
+
exclude: zod.z.array(zod.z.string()).default([])
|
|
114
|
+
}).default({}),
|
|
115
|
+
// Performance controls
|
|
116
|
+
performance: zod.z.object({
|
|
117
|
+
// Sample rate (0.0 - 1.0)
|
|
118
|
+
sampling_rate: zod.z.number().min(0).max(1).default(1),
|
|
119
|
+
// Skip fibers shorter than this duration (e.g., "10ms", "100 millis")
|
|
120
|
+
min_duration: zod.z.string().default("0ms"),
|
|
121
|
+
// Maximum concurrent traced fibers (0 = unlimited)
|
|
122
|
+
max_concurrent: zod.z.number().default(0)
|
|
123
|
+
}).default({}),
|
|
124
|
+
// Automatic metadata extraction
|
|
125
|
+
metadata: zod.z.object({
|
|
126
|
+
// Extract Effect fiber information
|
|
127
|
+
fiber_info: zod.z.boolean().default(true),
|
|
128
|
+
// Extract source location (file:line)
|
|
129
|
+
source_location: zod.z.boolean().default(true),
|
|
130
|
+
// Extract parent fiber information
|
|
131
|
+
parent_fiber: zod.z.boolean().default(true)
|
|
132
|
+
}).default({})
|
|
133
|
+
});
|
|
72
134
|
var HttpFilteringConfigSchema = zod.z.object({
|
|
73
135
|
// Patterns to ignore for outgoing HTTP requests (string patterns only in YAML)
|
|
74
136
|
ignore_outgoing_urls: zod.z.array(zod.z.string()).optional(),
|
|
@@ -90,6 +152,30 @@ var HttpFilteringConfigSchema = zod.z.object({
|
|
|
90
152
|
include_urls: zod.z.array(zod.z.string()).optional()
|
|
91
153
|
}).optional()
|
|
92
154
|
});
|
|
155
|
+
var ExporterConfigSchema = zod.z.object({
|
|
156
|
+
// Exporter type: 'otlp' | 'console' | 'none'
|
|
157
|
+
// - 'otlp': Export to OTLP endpoint (production)
|
|
158
|
+
// - 'console': Log spans to console (development)
|
|
159
|
+
// - 'none': No export (disable tracing)
|
|
160
|
+
type: zod.z.enum(["otlp", "console", "none"]).default("otlp"),
|
|
161
|
+
// OTLP endpoint URL (for type: otlp)
|
|
162
|
+
// Defaults to OTEL_EXPORTER_OTLP_ENDPOINT env var or http://localhost:4318
|
|
163
|
+
endpoint: zod.z.string().optional(),
|
|
164
|
+
// Custom headers to send with OTLP requests (for type: otlp)
|
|
165
|
+
// Useful for authentication (x-api-key, Authorization, etc.)
|
|
166
|
+
headers: zod.z.record(zod.z.string()).optional(),
|
|
167
|
+
// Span processor type
|
|
168
|
+
// - 'batch': Batch spans for export (production, lower overhead)
|
|
169
|
+
// - 'simple': Export immediately (development, no batching delay)
|
|
170
|
+
processor: zod.z.enum(["batch", "simple"]).default("batch"),
|
|
171
|
+
// Batch processor settings (for processor: batch)
|
|
172
|
+
batch: zod.z.object({
|
|
173
|
+
// Max time to wait before exporting (milliseconds)
|
|
174
|
+
scheduled_delay_millis: zod.z.number().default(1e3),
|
|
175
|
+
// Max batch size
|
|
176
|
+
max_export_batch_size: zod.z.number().default(100)
|
|
177
|
+
}).optional()
|
|
178
|
+
});
|
|
93
179
|
var InstrumentationConfigSchema = zod.z.object({
|
|
94
180
|
version: zod.z.string(),
|
|
95
181
|
instrumentation: zod.z.object({
|
|
@@ -100,11 +186,54 @@ var InstrumentationConfigSchema = zod.z.object({
|
|
|
100
186
|
ignore_patterns: zod.z.array(PatternConfigSchema)
|
|
101
187
|
}),
|
|
102
188
|
effect: zod.z.object({
|
|
189
|
+
// Enable/disable Effect tracing entirely
|
|
190
|
+
// When false, EffectInstrumentationLive returns Layer.empty
|
|
191
|
+
enabled: zod.z.boolean().default(true),
|
|
192
|
+
// Exporter mode (legacy - use exporter.type instead):
|
|
193
|
+
// - "unified": Use global TracerProvider from Node SDK (recommended, enables filtering)
|
|
194
|
+
// - "standalone": Use Effect's own OTLP exporter (bypasses Node SDK filtering)
|
|
195
|
+
exporter: zod.z.enum(["unified", "standalone"]).default("unified"),
|
|
196
|
+
// Exporter configuration (for auto-instrumentation)
|
|
197
|
+
exporter_config: ExporterConfigSchema.optional(),
|
|
103
198
|
auto_extract_metadata: zod.z.boolean(),
|
|
104
|
-
auto_isolation: AutoIsolationConfigSchema.optional()
|
|
199
|
+
auto_isolation: AutoIsolationConfigSchema.optional(),
|
|
200
|
+
// Auto-instrumentation: automatic tracing of all Effect fibers
|
|
201
|
+
auto_instrumentation: AutoInstrumentationConfigSchema.optional()
|
|
105
202
|
}).optional(),
|
|
106
203
|
http: HttpFilteringConfigSchema.optional()
|
|
107
204
|
});
|
|
205
|
+
var defaultConfig = {
|
|
206
|
+
version: "1.0",
|
|
207
|
+
instrumentation: {
|
|
208
|
+
enabled: true,
|
|
209
|
+
logging: "on",
|
|
210
|
+
description: "Default instrumentation configuration",
|
|
211
|
+
instrument_patterns: [
|
|
212
|
+
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
213
|
+
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
214
|
+
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
215
|
+
],
|
|
216
|
+
ignore_patterns: [
|
|
217
|
+
{ pattern: "^test\\.", description: "Test utilities" },
|
|
218
|
+
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
219
|
+
{ pattern: "^health\\.", description: "Health checks" }
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
effect: {
|
|
223
|
+
enabled: true,
|
|
224
|
+
exporter: "unified",
|
|
225
|
+
auto_extract_metadata: true
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
function parseAndValidateConfig(content) {
|
|
229
|
+
let parsed;
|
|
230
|
+
if (typeof content === "string") {
|
|
231
|
+
parsed = yaml.parse(content);
|
|
232
|
+
} else {
|
|
233
|
+
parsed = content;
|
|
234
|
+
}
|
|
235
|
+
return InstrumentationConfigSchema.parse(parsed);
|
|
236
|
+
}
|
|
108
237
|
(class extends effect.Data.TaggedError("ConfigError") {
|
|
109
238
|
get message() {
|
|
110
239
|
return this.reason;
|
|
@@ -282,7 +411,7 @@ var makeConfigLoader = effect.Effect.gen(function* () {
|
|
|
282
411
|
})
|
|
283
412
|
});
|
|
284
413
|
});
|
|
285
|
-
|
|
414
|
+
effect.Layer.effect(ConfigLoader, makeConfigLoader);
|
|
286
415
|
var PatternMatcher = class {
|
|
287
416
|
constructor(config) {
|
|
288
417
|
__publicField(this, "ignorePatterns", []);
|
|
@@ -430,84 +559,58 @@ var Logger = class {
|
|
|
430
559
|
}
|
|
431
560
|
};
|
|
432
561
|
var logger = new Logger();
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
);
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}).pipe(effect.Effect.provide(NodeConfigLoaderLive))
|
|
443
|
-
);
|
|
562
|
+
async function loadFromFile(filePath) {
|
|
563
|
+
const { readFile } = await import('fs/promises');
|
|
564
|
+
const content = await readFile(filePath, "utf-8");
|
|
565
|
+
return parseAndValidateConfig(content);
|
|
566
|
+
}
|
|
567
|
+
async function loadFromUrl(url) {
|
|
568
|
+
const response = await fetch(url);
|
|
569
|
+
if (!response.ok) {
|
|
570
|
+
throw new Error(`Failed to fetch config from ${url}: ${response.statusText}`);
|
|
444
571
|
}
|
|
445
|
-
|
|
572
|
+
const content = await response.text();
|
|
573
|
+
return parseAndValidateConfig(content);
|
|
446
574
|
}
|
|
447
|
-
async function loadConfig(uri,
|
|
448
|
-
if (
|
|
449
|
-
|
|
450
|
-
const loader2 = yield* ConfigLoader;
|
|
451
|
-
return yield* loader2.loadFromUri(uri);
|
|
452
|
-
});
|
|
453
|
-
return effect.Effect.runPromise(program.pipe(effect.Effect.provide(NodeConfigLoaderLive)));
|
|
575
|
+
async function loadConfig(uri, _options) {
|
|
576
|
+
if (uri.startsWith("http://") || uri.startsWith("https://")) {
|
|
577
|
+
return loadFromUrl(uri);
|
|
454
578
|
}
|
|
455
|
-
|
|
456
|
-
|
|
579
|
+
if (uri.startsWith("file://")) {
|
|
580
|
+
const filePath = uri.slice(7);
|
|
581
|
+
return loadFromFile(filePath);
|
|
582
|
+
}
|
|
583
|
+
return loadFromFile(uri);
|
|
457
584
|
}
|
|
458
585
|
async function loadConfigFromInline(content) {
|
|
459
|
-
|
|
460
|
-
return effect.Effect.runPromise(loader.loadFromInline(content));
|
|
461
|
-
}
|
|
462
|
-
function getDefaultConfig() {
|
|
463
|
-
return {
|
|
464
|
-
version: "1.0",
|
|
465
|
-
instrumentation: {
|
|
466
|
-
enabled: true,
|
|
467
|
-
logging: "on",
|
|
468
|
-
description: "Default instrumentation configuration",
|
|
469
|
-
instrument_patterns: [
|
|
470
|
-
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
471
|
-
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
472
|
-
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
473
|
-
],
|
|
474
|
-
ignore_patterns: [
|
|
475
|
-
{ pattern: "^test\\.", description: "Test utilities" },
|
|
476
|
-
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
477
|
-
{ pattern: "^health\\.", description: "Health checks" }
|
|
478
|
-
]
|
|
479
|
-
},
|
|
480
|
-
effect: {
|
|
481
|
-
auto_extract_metadata: true
|
|
482
|
-
}
|
|
483
|
-
};
|
|
586
|
+
return parseAndValidateConfig(content);
|
|
484
587
|
}
|
|
485
588
|
async function loadConfigWithOptions(options = {}) {
|
|
486
|
-
const loadOptions = options.cacheTimeout !== void 0 ? { cacheTimeout: options.cacheTimeout } : void 0;
|
|
487
589
|
if (options.config) {
|
|
488
590
|
return loadConfigFromInline(options.config);
|
|
489
591
|
}
|
|
490
592
|
const envConfigPath = process.env.ATRIM_INSTRUMENTATION_CONFIG;
|
|
491
593
|
if (envConfigPath) {
|
|
492
|
-
return loadConfig(envConfigPath
|
|
594
|
+
return loadConfig(envConfigPath);
|
|
493
595
|
}
|
|
494
596
|
if (options.configUrl) {
|
|
495
|
-
return loadConfig(options.configUrl
|
|
597
|
+
return loadConfig(options.configUrl);
|
|
496
598
|
}
|
|
497
599
|
if (options.configPath) {
|
|
498
|
-
return loadConfig(options.configPath
|
|
600
|
+
return loadConfig(options.configPath);
|
|
499
601
|
}
|
|
500
602
|
const { existsSync } = await import('fs');
|
|
501
603
|
const { join } = await import('path');
|
|
502
604
|
const defaultPath = join(process.cwd(), "instrumentation.yaml");
|
|
503
605
|
if (existsSync(defaultPath)) {
|
|
504
|
-
return loadConfig(defaultPath
|
|
606
|
+
return loadConfig(defaultPath);
|
|
505
607
|
}
|
|
506
|
-
return
|
|
608
|
+
return defaultConfig;
|
|
507
609
|
}
|
|
508
610
|
|
|
509
611
|
// src/integrations/effect/effect-tracer.ts
|
|
510
|
-
var SDK_NAME = "@effect/opentelemetry
|
|
612
|
+
var SDK_NAME = "@effect/opentelemetry";
|
|
613
|
+
var ATTR_TELEMETRY_EXPORTER_MODE = "telemetry.exporter.mode";
|
|
511
614
|
function createEffectInstrumentation(options = {}) {
|
|
512
615
|
return effect.Layer.unwrapEffect(
|
|
513
616
|
effect.Effect.gen(function* () {
|
|
@@ -518,90 +621,89 @@ function createEffectInstrumentation(options = {}) {
|
|
|
518
621
|
message: error instanceof Error ? error.message : String(error)
|
|
519
622
|
})
|
|
520
623
|
});
|
|
624
|
+
const effectEnabled = process.env.OTEL_EFFECT_ENABLED !== "false" && (config.effect?.enabled ?? true);
|
|
625
|
+
if (!effectEnabled) {
|
|
626
|
+
logger.log("@atrim/instrumentation/effect: Effect tracing disabled via config");
|
|
627
|
+
return effect.Layer.empty;
|
|
628
|
+
}
|
|
521
629
|
yield* effect.Effect.sync(() => {
|
|
522
630
|
const loggingLevel = config.instrumentation.logging || "on";
|
|
523
631
|
logger.setLevel(loggingLevel);
|
|
524
632
|
});
|
|
525
633
|
yield* effect.Effect.sync(() => initializePatternMatcher(config));
|
|
526
|
-
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
527
634
|
const serviceName = options.serviceName || process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
528
635
|
const serviceVersion = options.serviceVersion || process.env.npm_package_version || "1.0.0";
|
|
529
|
-
const
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
636
|
+
const exporterMode = options.exporterMode ?? config.effect?.exporter ?? "unified";
|
|
637
|
+
const resourceAttributes = {
|
|
638
|
+
"platform.component": "effect",
|
|
639
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
640
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
641
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: exporterMode
|
|
642
|
+
};
|
|
643
|
+
if (exporterMode === "standalone") {
|
|
644
|
+
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
645
|
+
logger.log("Effect OpenTelemetry instrumentation (standalone)");
|
|
646
|
+
logger.log(` Service: ${serviceName}`);
|
|
647
|
+
logger.log(` Endpoint: ${otlpEndpoint}`);
|
|
648
|
+
logger.log(" WARNING: Standalone mode bypasses Node SDK filtering");
|
|
649
|
+
return Otlp__namespace.layer({
|
|
650
|
+
baseUrl: otlpEndpoint,
|
|
651
|
+
resource: {
|
|
652
|
+
serviceName,
|
|
653
|
+
serviceVersion,
|
|
654
|
+
attributes: resourceAttributes
|
|
655
|
+
},
|
|
656
|
+
// Bridge Effect context to OpenTelemetry global context
|
|
657
|
+
tracerContext: (f, span) => {
|
|
658
|
+
if (span._tag !== "Span") {
|
|
659
|
+
return f();
|
|
660
|
+
}
|
|
661
|
+
const spanContext = {
|
|
662
|
+
traceId: span.traceId,
|
|
663
|
+
spanId: span.spanId,
|
|
664
|
+
traceFlags: span.sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
|
|
665
|
+
};
|
|
666
|
+
const otelSpan = api.trace.wrapSpanContext(spanContext);
|
|
667
|
+
return api.context.with(api.trace.setSpan(api.context.active(), otelSpan), f);
|
|
554
668
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
669
|
+
}).pipe(effect.Layer.provide(platform.FetchHttpClient.layer));
|
|
670
|
+
} else {
|
|
671
|
+
logger.log("Effect OpenTelemetry instrumentation (unified)");
|
|
672
|
+
logger.log(` Service: ${serviceName}`);
|
|
673
|
+
logger.log(" Using global TracerProvider for span export");
|
|
674
|
+
return Tracer__namespace.layerGlobal.pipe(
|
|
675
|
+
effect.Layer.provide(
|
|
676
|
+
Resource__namespace.layer({
|
|
677
|
+
serviceName,
|
|
678
|
+
serviceVersion,
|
|
679
|
+
attributes: resourceAttributes
|
|
680
|
+
})
|
|
681
|
+
)
|
|
682
|
+
);
|
|
566
683
|
}
|
|
567
|
-
return otlpLayer;
|
|
568
684
|
})
|
|
569
685
|
).pipe(effect.Layer.orDie);
|
|
570
686
|
}
|
|
571
687
|
var EffectInstrumentationLive = effect.Effect.sync(() => {
|
|
572
|
-
const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
573
688
|
const serviceName = process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
574
689
|
const serviceVersion = process.env.npm_package_version || "1.0.0";
|
|
575
690
|
logger.minimal(`@atrim/instrumentation/effect: Effect tracing enabled (${serviceName})`);
|
|
576
|
-
logger.log("
|
|
577
|
-
logger.log(`
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
tracerContext: (f, span) => {
|
|
593
|
-
if (span._tag !== "Span") {
|
|
594
|
-
return f();
|
|
595
|
-
}
|
|
596
|
-
const spanContext = {
|
|
597
|
-
traceId: span.traceId,
|
|
598
|
-
spanId: span.spanId,
|
|
599
|
-
traceFlags: span.sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
|
|
600
|
-
};
|
|
601
|
-
const otelSpan = api.trace.wrapSpanContext(spanContext);
|
|
602
|
-
return api.context.with(api.trace.setSpan(api.context.active(), otelSpan), f);
|
|
603
|
-
}
|
|
604
|
-
}).pipe(effect.Layer.provide(platform.FetchHttpClient.layer));
|
|
691
|
+
logger.log("Effect OpenTelemetry tracer (unified)");
|
|
692
|
+
logger.log(` Service: ${serviceName}`);
|
|
693
|
+
return Tracer__namespace.layerGlobal.pipe(
|
|
694
|
+
effect.Layer.provide(
|
|
695
|
+
Resource__namespace.layer({
|
|
696
|
+
serviceName,
|
|
697
|
+
serviceVersion,
|
|
698
|
+
attributes: {
|
|
699
|
+
"platform.component": "effect",
|
|
700
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
701
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
702
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: "unified"
|
|
703
|
+
}
|
|
704
|
+
})
|
|
705
|
+
)
|
|
706
|
+
);
|
|
605
707
|
}).pipe(effect.Layer.unwrapEffect);
|
|
606
708
|
function annotateUser(userId, email, username) {
|
|
607
709
|
const attributes = {
|