@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
|
@@ -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,6 +31,8 @@ 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);
|
|
@@ -70,7 +74,20 @@ var HttpFilteringConfigSchema = zod.z.object({
|
|
|
70
74
|
// Patterns to ignore for incoming HTTP requests (string patterns only in YAML)
|
|
71
75
|
ignore_incoming_paths: zod.z.array(zod.z.string()).optional(),
|
|
72
76
|
// Require parent span for outgoing requests (prevents root spans for HTTP calls)
|
|
73
|
-
require_parent_for_outgoing_spans: zod.z.boolean().optional()
|
|
77
|
+
require_parent_for_outgoing_spans: zod.z.boolean().optional(),
|
|
78
|
+
// Trace context propagation configuration
|
|
79
|
+
// Controls which cross-origin requests receive W3C Trace Context headers (traceparent, tracestate)
|
|
80
|
+
propagate_trace_context: zod.z.object({
|
|
81
|
+
// Strategy for trace propagation
|
|
82
|
+
// - "all": Propagate to all cross-origin requests (may cause CORS errors)
|
|
83
|
+
// - "none": Never propagate trace headers
|
|
84
|
+
// - "same-origin": Only propagate to same-origin requests (default, safe)
|
|
85
|
+
// - "patterns": Propagate based on include_urls patterns
|
|
86
|
+
strategy: zod.z.enum(["all", "none", "same-origin", "patterns"]).default("same-origin"),
|
|
87
|
+
// URL patterns to include when strategy is "patterns"
|
|
88
|
+
// Supports regex patterns (e.g., "^https://api\\.myapp\\.com")
|
|
89
|
+
include_urls: zod.z.array(zod.z.string()).optional()
|
|
90
|
+
}).optional()
|
|
74
91
|
});
|
|
75
92
|
var InstrumentationConfigSchema = zod.z.object({
|
|
76
93
|
version: zod.z.string(),
|
|
@@ -82,11 +99,56 @@ var InstrumentationConfigSchema = zod.z.object({
|
|
|
82
99
|
ignore_patterns: zod.z.array(PatternConfigSchema)
|
|
83
100
|
}),
|
|
84
101
|
effect: zod.z.object({
|
|
102
|
+
// Enable/disable Effect tracing entirely
|
|
103
|
+
// When false, EffectInstrumentationLive returns Layer.empty
|
|
104
|
+
enabled: zod.z.boolean().default(true),
|
|
105
|
+
// Exporter mode:
|
|
106
|
+
// - "unified": Use global TracerProvider from Node SDK (recommended, enables filtering)
|
|
107
|
+
// - "standalone": Use Effect's own OTLP exporter (bypasses Node SDK filtering)
|
|
108
|
+
exporter: zod.z.enum(["unified", "standalone"]).default("unified"),
|
|
85
109
|
auto_extract_metadata: zod.z.boolean(),
|
|
110
|
+
// Auto-bridge OpenTelemetry context to Effect spans
|
|
111
|
+
// When true, Effect spans automatically become children of the active OTel span
|
|
112
|
+
// (e.g., HTTP request span from auto-instrumentation)
|
|
113
|
+
// This is essential for proper trace hierarchy when using Effect with HTTP frameworks
|
|
114
|
+
auto_bridge_context: zod.z.boolean().default(true),
|
|
86
115
|
auto_isolation: AutoIsolationConfigSchema.optional()
|
|
87
116
|
}).optional(),
|
|
88
117
|
http: HttpFilteringConfigSchema.optional()
|
|
89
118
|
});
|
|
119
|
+
var defaultConfig = {
|
|
120
|
+
version: "1.0",
|
|
121
|
+
instrumentation: {
|
|
122
|
+
enabled: true,
|
|
123
|
+
logging: "on",
|
|
124
|
+
description: "Default instrumentation configuration",
|
|
125
|
+
instrument_patterns: [
|
|
126
|
+
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
127
|
+
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
128
|
+
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
129
|
+
],
|
|
130
|
+
ignore_patterns: [
|
|
131
|
+
{ pattern: "^test\\.", description: "Test utilities" },
|
|
132
|
+
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
133
|
+
{ pattern: "^health\\.", description: "Health checks" }
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
effect: {
|
|
137
|
+
enabled: true,
|
|
138
|
+
exporter: "unified",
|
|
139
|
+
auto_extract_metadata: true,
|
|
140
|
+
auto_bridge_context: true
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
function parseAndValidateConfig(content) {
|
|
144
|
+
let parsed;
|
|
145
|
+
if (typeof content === "string") {
|
|
146
|
+
parsed = yaml.parse(content);
|
|
147
|
+
} else {
|
|
148
|
+
parsed = content;
|
|
149
|
+
}
|
|
150
|
+
return InstrumentationConfigSchema.parse(parsed);
|
|
151
|
+
}
|
|
90
152
|
(class extends effect.Data.TaggedError("ConfigError") {
|
|
91
153
|
get message() {
|
|
92
154
|
return this.reason;
|
|
@@ -264,7 +326,7 @@ var makeConfigLoader = effect.Effect.gen(function* () {
|
|
|
264
326
|
})
|
|
265
327
|
});
|
|
266
328
|
});
|
|
267
|
-
|
|
329
|
+
effect.Layer.effect(ConfigLoader, makeConfigLoader);
|
|
268
330
|
var PatternMatcher = class {
|
|
269
331
|
constructor(config) {
|
|
270
332
|
__publicField(this, "ignorePatterns", []);
|
|
@@ -412,83 +474,58 @@ var Logger = class {
|
|
|
412
474
|
}
|
|
413
475
|
};
|
|
414
476
|
var logger = new Logger();
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
);
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}).pipe(effect.Effect.provide(NodeConfigLoaderLive))
|
|
425
|
-
);
|
|
477
|
+
async function loadFromFile(filePath) {
|
|
478
|
+
const { readFile } = await import('fs/promises');
|
|
479
|
+
const content = await readFile(filePath, "utf-8");
|
|
480
|
+
return parseAndValidateConfig(content);
|
|
481
|
+
}
|
|
482
|
+
async function loadFromUrl(url) {
|
|
483
|
+
const response = await fetch(url);
|
|
484
|
+
if (!response.ok) {
|
|
485
|
+
throw new Error(`Failed to fetch config from ${url}: ${response.statusText}`);
|
|
426
486
|
}
|
|
427
|
-
|
|
487
|
+
const content = await response.text();
|
|
488
|
+
return parseAndValidateConfig(content);
|
|
428
489
|
}
|
|
429
|
-
async function loadConfig(uri,
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
const loader2 = yield* ConfigLoader;
|
|
433
|
-
return yield* loader2.loadFromUri(uri);
|
|
434
|
-
});
|
|
435
|
-
return effect.Effect.runPromise(program.pipe(effect.Effect.provide(NodeConfigLoaderLive)));
|
|
490
|
+
async function loadConfig(uri, _options) {
|
|
491
|
+
if (uri.startsWith("http://") || uri.startsWith("https://")) {
|
|
492
|
+
return loadFromUrl(uri);
|
|
436
493
|
}
|
|
437
|
-
|
|
438
|
-
|
|
494
|
+
if (uri.startsWith("file://")) {
|
|
495
|
+
const filePath = uri.slice(7);
|
|
496
|
+
return loadFromFile(filePath);
|
|
497
|
+
}
|
|
498
|
+
return loadFromFile(uri);
|
|
439
499
|
}
|
|
440
500
|
async function loadConfigFromInline(content) {
|
|
441
|
-
|
|
442
|
-
return effect.Effect.runPromise(loader.loadFromInline(content));
|
|
443
|
-
}
|
|
444
|
-
function getDefaultConfig() {
|
|
445
|
-
return {
|
|
446
|
-
version: "1.0",
|
|
447
|
-
instrumentation: {
|
|
448
|
-
enabled: true,
|
|
449
|
-
logging: "on",
|
|
450
|
-
description: "Default instrumentation configuration",
|
|
451
|
-
instrument_patterns: [
|
|
452
|
-
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
453
|
-
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
454
|
-
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
455
|
-
],
|
|
456
|
-
ignore_patterns: [
|
|
457
|
-
{ pattern: "^test\\.", description: "Test utilities" },
|
|
458
|
-
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
459
|
-
{ pattern: "^health\\.", description: "Health checks" }
|
|
460
|
-
]
|
|
461
|
-
},
|
|
462
|
-
effect: {
|
|
463
|
-
auto_extract_metadata: true
|
|
464
|
-
}
|
|
465
|
-
};
|
|
501
|
+
return parseAndValidateConfig(content);
|
|
466
502
|
}
|
|
467
503
|
async function loadConfigWithOptions(options = {}) {
|
|
468
|
-
const loadOptions = options.cacheTimeout !== void 0 ? { cacheTimeout: options.cacheTimeout } : void 0;
|
|
469
504
|
if (options.config) {
|
|
470
505
|
return loadConfigFromInline(options.config);
|
|
471
506
|
}
|
|
472
507
|
const envConfigPath = process.env.ATRIM_INSTRUMENTATION_CONFIG;
|
|
473
508
|
if (envConfigPath) {
|
|
474
|
-
return loadConfig(envConfigPath
|
|
509
|
+
return loadConfig(envConfigPath);
|
|
475
510
|
}
|
|
476
511
|
if (options.configUrl) {
|
|
477
|
-
return loadConfig(options.configUrl
|
|
512
|
+
return loadConfig(options.configUrl);
|
|
478
513
|
}
|
|
479
514
|
if (options.configPath) {
|
|
480
|
-
return loadConfig(options.configPath
|
|
515
|
+
return loadConfig(options.configPath);
|
|
481
516
|
}
|
|
482
517
|
const { existsSync } = await import('fs');
|
|
483
518
|
const { join } = await import('path');
|
|
484
519
|
const defaultPath = join(process.cwd(), "instrumentation.yaml");
|
|
485
520
|
if (existsSync(defaultPath)) {
|
|
486
|
-
return loadConfig(defaultPath
|
|
521
|
+
return loadConfig(defaultPath);
|
|
487
522
|
}
|
|
488
|
-
return
|
|
523
|
+
return defaultConfig;
|
|
489
524
|
}
|
|
490
525
|
|
|
491
526
|
// src/integrations/effect/effect-tracer.ts
|
|
527
|
+
var SDK_NAME = "@effect/opentelemetry";
|
|
528
|
+
var ATTR_TELEMETRY_EXPORTER_MODE = "telemetry.exporter.mode";
|
|
492
529
|
function createEffectInstrumentation(options = {}) {
|
|
493
530
|
return effect.Layer.unwrapEffect(
|
|
494
531
|
effect.Effect.gen(function* () {
|
|
@@ -499,106 +536,277 @@ function createEffectInstrumentation(options = {}) {
|
|
|
499
536
|
message: error instanceof Error ? error.message : String(error)
|
|
500
537
|
})
|
|
501
538
|
});
|
|
539
|
+
const effectEnabled = process.env.OTEL_EFFECT_ENABLED !== "false" && (config.effect?.enabled ?? true);
|
|
540
|
+
if (!effectEnabled) {
|
|
541
|
+
logger.log("@atrim/instrumentation/effect: Effect tracing disabled via config");
|
|
542
|
+
return effect.Layer.empty;
|
|
543
|
+
}
|
|
502
544
|
yield* effect.Effect.sync(() => {
|
|
503
545
|
const loggingLevel = config.instrumentation.logging || "on";
|
|
504
546
|
logger.setLevel(loggingLevel);
|
|
505
547
|
});
|
|
506
548
|
yield* effect.Effect.sync(() => initializePatternMatcher(config));
|
|
507
|
-
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
508
549
|
const serviceName = options.serviceName || process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
509
550
|
const serviceVersion = options.serviceVersion || process.env.npm_package_version || "1.0.0";
|
|
510
|
-
const
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
551
|
+
const exporterMode = options.exporterMode ?? config.effect?.exporter ?? "unified";
|
|
552
|
+
const resourceAttributes = {
|
|
553
|
+
"platform.component": "effect",
|
|
554
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
555
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
556
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: exporterMode
|
|
557
|
+
};
|
|
558
|
+
if (exporterMode === "standalone") {
|
|
559
|
+
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
560
|
+
logger.log("Effect OpenTelemetry instrumentation (standalone)");
|
|
561
|
+
logger.log(` Service: ${serviceName}`);
|
|
562
|
+
logger.log(` Endpoint: ${otlpEndpoint}`);
|
|
563
|
+
logger.log(" WARNING: Standalone mode bypasses Node SDK filtering");
|
|
564
|
+
return Otlp__namespace.layer({
|
|
565
|
+
baseUrl: otlpEndpoint,
|
|
566
|
+
resource: {
|
|
567
|
+
serviceName,
|
|
568
|
+
serviceVersion,
|
|
569
|
+
attributes: resourceAttributes
|
|
570
|
+
},
|
|
571
|
+
// Bridge Effect context to OpenTelemetry global context
|
|
572
|
+
tracerContext: (f, span) => {
|
|
573
|
+
if (span._tag !== "Span") {
|
|
574
|
+
return f();
|
|
575
|
+
}
|
|
576
|
+
const spanContext = {
|
|
577
|
+
traceId: span.traceId,
|
|
578
|
+
spanId: span.spanId,
|
|
579
|
+
traceFlags: span.sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
|
|
580
|
+
};
|
|
581
|
+
const otelSpan = api.trace.wrapSpanContext(spanContext);
|
|
582
|
+
return api.context.with(api.trace.setSpan(api.context.active(), otelSpan), f);
|
|
533
583
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
584
|
+
}).pipe(effect.Layer.provide(platform.FetchHttpClient.layer));
|
|
585
|
+
} else {
|
|
586
|
+
logger.log("Effect OpenTelemetry instrumentation (unified)");
|
|
587
|
+
logger.log(` Service: ${serviceName}`);
|
|
588
|
+
logger.log(" Using global TracerProvider for span export");
|
|
589
|
+
return Tracer__namespace.layerGlobal.pipe(
|
|
590
|
+
effect.Layer.provide(
|
|
591
|
+
Resource__namespace.layer({
|
|
592
|
+
serviceName,
|
|
593
|
+
serviceVersion,
|
|
594
|
+
attributes: resourceAttributes
|
|
595
|
+
})
|
|
596
|
+
)
|
|
597
|
+
);
|
|
545
598
|
}
|
|
546
|
-
return otlpLayer;
|
|
547
599
|
})
|
|
548
600
|
).pipe(effect.Layer.orDie);
|
|
549
601
|
}
|
|
550
602
|
var EffectInstrumentationLive = effect.Effect.sync(() => {
|
|
551
|
-
const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
552
603
|
const serviceName = process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
553
604
|
const serviceVersion = process.env.npm_package_version || "1.0.0";
|
|
554
605
|
logger.minimal(`@atrim/instrumentation/effect: Effect tracing enabled (${serviceName})`);
|
|
555
|
-
logger.log("
|
|
556
|
-
logger.log(`
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
return f();
|
|
572
|
-
}
|
|
573
|
-
const spanContext = {
|
|
574
|
-
traceId: span.traceId,
|
|
575
|
-
spanId: span.spanId,
|
|
576
|
-
traceFlags: span.sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
|
|
577
|
-
};
|
|
578
|
-
const otelSpan = api.trace.wrapSpanContext(spanContext);
|
|
579
|
-
return api.context.with(api.trace.setSpan(api.context.active(), otelSpan), f);
|
|
580
|
-
}
|
|
581
|
-
}).pipe(effect.Layer.provide(platform.FetchHttpClient.layer));
|
|
606
|
+
logger.log("Effect OpenTelemetry tracer (unified)");
|
|
607
|
+
logger.log(` Service: ${serviceName}`);
|
|
608
|
+
return Tracer__namespace.layerGlobal.pipe(
|
|
609
|
+
effect.Layer.provide(
|
|
610
|
+
Resource__namespace.layer({
|
|
611
|
+
serviceName,
|
|
612
|
+
serviceVersion,
|
|
613
|
+
attributes: {
|
|
614
|
+
"platform.component": "effect",
|
|
615
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
616
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
617
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: "unified"
|
|
618
|
+
}
|
|
619
|
+
})
|
|
620
|
+
)
|
|
621
|
+
);
|
|
582
622
|
}).pipe(effect.Layer.unwrapEffect);
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
623
|
+
var withOtelParentSpan = (effect) => {
|
|
624
|
+
const currentSpan = api.trace.getSpan(api.context.active());
|
|
625
|
+
if (currentSpan) {
|
|
626
|
+
const spanContext = currentSpan.spanContext();
|
|
627
|
+
return Tracer__namespace.withSpanContext(spanContext)(effect);
|
|
628
|
+
}
|
|
629
|
+
return effect;
|
|
630
|
+
};
|
|
631
|
+
var getCurrentOtelSpanContext = effect.Effect.sync(() => {
|
|
632
|
+
const currentSpan = api.trace.getSpan(api.context.active());
|
|
633
|
+
return currentSpan?.spanContext();
|
|
634
|
+
});
|
|
635
|
+
var getOtelParentSpan = effect.Effect.sync(
|
|
636
|
+
() => {
|
|
637
|
+
const currentSpan = api.trace.getSpan(api.context.active());
|
|
638
|
+
if (!currentSpan) {
|
|
639
|
+
return void 0;
|
|
640
|
+
}
|
|
641
|
+
const spanContext = currentSpan.spanContext();
|
|
642
|
+
return Tracer__namespace.makeExternalSpan({
|
|
643
|
+
traceId: spanContext.traceId,
|
|
644
|
+
spanId: spanContext.spanId,
|
|
645
|
+
traceFlags: spanContext.traceFlags,
|
|
646
|
+
traceState: spanContext.traceState?.serialize()
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
);
|
|
650
|
+
var runWithOtelContext = (effect$1) => {
|
|
651
|
+
return effect.Effect.flatMap(
|
|
652
|
+
Tracer__namespace.currentOtelSpan,
|
|
653
|
+
(otelSpan) => effect.Effect.async((resume) => {
|
|
654
|
+
api.context.with(api.trace.setSpan(api.context.active(), otelSpan), () => {
|
|
655
|
+
effect.Effect.runPromiseExit(effect$1).then((exit) => {
|
|
656
|
+
if (exit._tag === "Success") {
|
|
657
|
+
resume(effect.Effect.succeed(exit.value));
|
|
658
|
+
} else {
|
|
659
|
+
resume(effect.Effect.failCause(exit.cause));
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
})
|
|
664
|
+
).pipe(
|
|
665
|
+
// If no OTel span is available, just run the effect normally
|
|
666
|
+
effect.Effect.catchAll(() => effect$1)
|
|
667
|
+
);
|
|
668
|
+
};
|
|
669
|
+
var withFullOtelBridging = (effect) => {
|
|
670
|
+
return withOtelParentSpan(effect);
|
|
671
|
+
};
|
|
672
|
+
function annotateUser(userId, email, username) {
|
|
673
|
+
const attributes = {
|
|
674
|
+
"user.id": userId
|
|
675
|
+
};
|
|
676
|
+
if (email) attributes["user.email"] = email;
|
|
677
|
+
if (username) attributes["user.name"] = username;
|
|
678
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
586
679
|
}
|
|
587
|
-
function annotateDataSize(
|
|
680
|
+
function annotateDataSize(bytes, items, compressionRatio) {
|
|
681
|
+
const attributes = {
|
|
682
|
+
"data.size.bytes": bytes,
|
|
683
|
+
"data.size.items": items
|
|
684
|
+
};
|
|
685
|
+
if (compressionRatio !== void 0) {
|
|
686
|
+
attributes["data.compression.ratio"] = compressionRatio;
|
|
687
|
+
}
|
|
688
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
588
689
|
}
|
|
589
|
-
function annotateBatch(
|
|
690
|
+
function annotateBatch(totalItems, batchSize, successCount, failureCount) {
|
|
691
|
+
const attributes = {
|
|
692
|
+
"batch.size": batchSize,
|
|
693
|
+
"batch.total_items": totalItems,
|
|
694
|
+
"batch.count": Math.ceil(totalItems / batchSize)
|
|
695
|
+
};
|
|
696
|
+
if (successCount !== void 0) {
|
|
697
|
+
attributes["batch.success_count"] = successCount;
|
|
698
|
+
}
|
|
699
|
+
if (failureCount !== void 0) {
|
|
700
|
+
attributes["batch.failure_count"] = failureCount;
|
|
701
|
+
}
|
|
702
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
590
703
|
}
|
|
591
|
-
function annotateLLM(
|
|
704
|
+
function annotateLLM(model, provider, tokens) {
|
|
705
|
+
const attributes = {
|
|
706
|
+
"llm.model": model,
|
|
707
|
+
"llm.provider": provider
|
|
708
|
+
};
|
|
709
|
+
if (tokens) {
|
|
710
|
+
if (tokens.prompt !== void 0) attributes["llm.tokens.prompt"] = tokens.prompt;
|
|
711
|
+
if (tokens.completion !== void 0) attributes["llm.tokens.completion"] = tokens.completion;
|
|
712
|
+
if (tokens.total !== void 0) attributes["llm.tokens.total"] = tokens.total;
|
|
713
|
+
}
|
|
714
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
592
715
|
}
|
|
593
|
-
function annotateQuery(
|
|
716
|
+
function annotateQuery(query, duration, rowCount, database) {
|
|
717
|
+
const attributes = {
|
|
718
|
+
"db.statement": query.length > 1e3 ? query.substring(0, 1e3) + "..." : query
|
|
719
|
+
};
|
|
720
|
+
if (duration !== void 0) attributes["db.duration.ms"] = duration;
|
|
721
|
+
if (rowCount !== void 0) attributes["db.row_count"] = rowCount;
|
|
722
|
+
if (database) attributes["db.name"] = database;
|
|
723
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
594
724
|
}
|
|
595
|
-
function annotateHttpRequest(
|
|
725
|
+
function annotateHttpRequest(method, url, statusCode, contentLength) {
|
|
726
|
+
const attributes = {
|
|
727
|
+
"http.method": method,
|
|
728
|
+
"http.url": url
|
|
729
|
+
};
|
|
730
|
+
if (statusCode !== void 0) attributes["http.status_code"] = statusCode;
|
|
731
|
+
if (contentLength !== void 0) attributes["http.response.content_length"] = contentLength;
|
|
732
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
596
733
|
}
|
|
597
|
-
function annotateError(
|
|
734
|
+
function annotateError(error, recoverable, errorType) {
|
|
735
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
736
|
+
const errorStack = typeof error === "string" ? void 0 : error.stack;
|
|
737
|
+
const attributes = {
|
|
738
|
+
"error.message": errorMessage,
|
|
739
|
+
"error.recoverable": recoverable
|
|
740
|
+
};
|
|
741
|
+
if (errorType) attributes["error.type"] = errorType;
|
|
742
|
+
if (errorStack) attributes["error.stack"] = errorStack;
|
|
743
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
598
744
|
}
|
|
599
|
-
function annotatePriority(
|
|
745
|
+
function annotatePriority(priority, reason) {
|
|
746
|
+
const attributes = {
|
|
747
|
+
"operation.priority": priority
|
|
748
|
+
};
|
|
749
|
+
if (reason) attributes["operation.priority.reason"] = reason;
|
|
750
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
600
751
|
}
|
|
601
|
-
function annotateCache(
|
|
752
|
+
function annotateCache(hit, key, ttl) {
|
|
753
|
+
const attributes = {
|
|
754
|
+
"cache.hit": hit,
|
|
755
|
+
"cache.key": key
|
|
756
|
+
};
|
|
757
|
+
if (ttl !== void 0) attributes["cache.ttl.seconds"] = ttl;
|
|
758
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
759
|
+
}
|
|
760
|
+
function extractEffectMetadata() {
|
|
761
|
+
return effect.Effect.gen(function* () {
|
|
762
|
+
const metadata = {};
|
|
763
|
+
const currentFiber = effect.Fiber.getCurrentFiber();
|
|
764
|
+
if (effect.Option.isSome(currentFiber)) {
|
|
765
|
+
const fiber = currentFiber.value;
|
|
766
|
+
const fiberId = fiber.id();
|
|
767
|
+
metadata["effect.fiber.id"] = effect.FiberId.threadName(fiberId);
|
|
768
|
+
const status = yield* effect.Fiber.status(fiber);
|
|
769
|
+
if (status._tag) {
|
|
770
|
+
metadata["effect.fiber.status"] = status._tag;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
const parentSpanResult = yield* effect.Effect.currentSpan.pipe(
|
|
774
|
+
effect.Effect.option
|
|
775
|
+
// Convert NoSuchElementException to Option
|
|
776
|
+
);
|
|
777
|
+
if (effect.Option.isSome(parentSpanResult)) {
|
|
778
|
+
const parentSpan = parentSpanResult.value;
|
|
779
|
+
metadata["effect.operation.nested"] = true;
|
|
780
|
+
metadata["effect.operation.root"] = false;
|
|
781
|
+
if (parentSpan.spanId) {
|
|
782
|
+
metadata["effect.parent.span.id"] = parentSpan.spanId;
|
|
783
|
+
}
|
|
784
|
+
if (parentSpan.name) {
|
|
785
|
+
metadata["effect.parent.span.name"] = parentSpan.name;
|
|
786
|
+
}
|
|
787
|
+
if (parentSpan.traceId) {
|
|
788
|
+
metadata["effect.parent.trace.id"] = parentSpan.traceId;
|
|
789
|
+
}
|
|
790
|
+
} else {
|
|
791
|
+
metadata["effect.operation.nested"] = false;
|
|
792
|
+
metadata["effect.operation.root"] = true;
|
|
793
|
+
}
|
|
794
|
+
return metadata;
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
function autoEnrichSpan() {
|
|
798
|
+
return effect.Effect.gen(function* () {
|
|
799
|
+
const metadata = yield* extractEffectMetadata();
|
|
800
|
+
yield* effect.Effect.annotateCurrentSpan(metadata);
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
function withAutoEnrichedSpan(spanName, options) {
|
|
804
|
+
return (self) => {
|
|
805
|
+
return effect.Effect.gen(function* () {
|
|
806
|
+
yield* autoEnrichSpan();
|
|
807
|
+
return yield* self;
|
|
808
|
+
}).pipe(effect.Effect.withSpan(spanName, options));
|
|
809
|
+
};
|
|
602
810
|
}
|
|
603
811
|
var createLogicalParentLink = (parentSpan, useSpanLinks) => {
|
|
604
812
|
if (!useSpanLinks) {
|
|
@@ -737,8 +945,16 @@ exports.annotatePriority = annotatePriority;
|
|
|
737
945
|
exports.annotateQuery = annotateQuery;
|
|
738
946
|
exports.annotateSpawnedTasks = annotateSpawnedTasks;
|
|
739
947
|
exports.annotateUser = annotateUser;
|
|
948
|
+
exports.autoEnrichSpan = autoEnrichSpan;
|
|
740
949
|
exports.createEffectInstrumentation = createEffectInstrumentation;
|
|
950
|
+
exports.extractEffectMetadata = extractEffectMetadata;
|
|
951
|
+
exports.getCurrentOtelSpanContext = getCurrentOtelSpanContext;
|
|
952
|
+
exports.getOtelParentSpan = getOtelParentSpan;
|
|
741
953
|
exports.runIsolated = runIsolated;
|
|
954
|
+
exports.runWithOtelContext = runWithOtelContext;
|
|
742
955
|
exports.runWithSpan = runWithSpan;
|
|
956
|
+
exports.withAutoEnrichedSpan = withAutoEnrichedSpan;
|
|
957
|
+
exports.withFullOtelBridging = withFullOtelBridging;
|
|
958
|
+
exports.withOtelParentSpan = withOtelParentSpan;
|
|
743
959
|
//# sourceMappingURL=index.cjs.map
|
|
744
960
|
//# sourceMappingURL=index.cjs.map
|