@atrim/instrument-node 0.5.0 → 0.5.1-1451fcf-20260105212505
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 +97 -269
- package/package.json +20 -19
- package/target/dist/index.cjs +149 -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 +148 -60
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/index.cjs +301 -130
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.d.cts +205 -36
- package/target/dist/integrations/effect/index.d.ts +205 -36
- package/target/dist/integrations/effect/index.js +298 -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 OtelTracer = 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 OtelTracer__namespace = /*#__PURE__*/_interopNamespace(OtelTracer);
|
|
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,50 @@ 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(),
|
|
86
110
|
auto_isolation: AutoIsolationConfigSchema.optional()
|
|
87
111
|
}).optional(),
|
|
88
112
|
http: HttpFilteringConfigSchema.optional()
|
|
89
113
|
});
|
|
114
|
+
var defaultConfig = {
|
|
115
|
+
version: "1.0",
|
|
116
|
+
instrumentation: {
|
|
117
|
+
enabled: true,
|
|
118
|
+
logging: "on",
|
|
119
|
+
description: "Default instrumentation configuration",
|
|
120
|
+
instrument_patterns: [
|
|
121
|
+
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
122
|
+
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
123
|
+
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
124
|
+
],
|
|
125
|
+
ignore_patterns: [
|
|
126
|
+
{ pattern: "^test\\.", description: "Test utilities" },
|
|
127
|
+
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
128
|
+
{ pattern: "^health\\.", description: "Health checks" }
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
effect: {
|
|
132
|
+
enabled: true,
|
|
133
|
+
exporter: "unified",
|
|
134
|
+
auto_extract_metadata: true
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
function parseAndValidateConfig(content) {
|
|
138
|
+
let parsed;
|
|
139
|
+
if (typeof content === "string") {
|
|
140
|
+
parsed = yaml.parse(content);
|
|
141
|
+
} else {
|
|
142
|
+
parsed = content;
|
|
143
|
+
}
|
|
144
|
+
return InstrumentationConfigSchema.parse(parsed);
|
|
145
|
+
}
|
|
90
146
|
(class extends effect.Data.TaggedError("ConfigError") {
|
|
91
147
|
get message() {
|
|
92
148
|
return this.reason;
|
|
@@ -264,7 +320,7 @@ var makeConfigLoader = effect.Effect.gen(function* () {
|
|
|
264
320
|
})
|
|
265
321
|
});
|
|
266
322
|
});
|
|
267
|
-
|
|
323
|
+
effect.Layer.effect(ConfigLoader, makeConfigLoader);
|
|
268
324
|
var PatternMatcher = class {
|
|
269
325
|
constructor(config) {
|
|
270
326
|
__publicField(this, "ignorePatterns", []);
|
|
@@ -412,83 +468,73 @@ var Logger = class {
|
|
|
412
468
|
}
|
|
413
469
|
};
|
|
414
470
|
var logger = new Logger();
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
);
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}).pipe(effect.Effect.provide(NodeConfigLoaderLive))
|
|
425
|
-
);
|
|
471
|
+
async function loadFromFile(filePath) {
|
|
472
|
+
const { readFile } = await import('fs/promises');
|
|
473
|
+
const content = await readFile(filePath, "utf-8");
|
|
474
|
+
return parseAndValidateConfig(content);
|
|
475
|
+
}
|
|
476
|
+
async function loadFromUrl(url) {
|
|
477
|
+
const response = await fetch(url);
|
|
478
|
+
if (!response.ok) {
|
|
479
|
+
throw new Error(`Failed to fetch config from ${url}: ${response.statusText}`);
|
|
426
480
|
}
|
|
427
|
-
|
|
481
|
+
const content = await response.text();
|
|
482
|
+
return parseAndValidateConfig(content);
|
|
428
483
|
}
|
|
429
|
-
async function loadConfig(uri,
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
return
|
|
484
|
+
async function loadConfig(uri, _options) {
|
|
485
|
+
if (uri.startsWith("http://") || uri.startsWith("https://")) {
|
|
486
|
+
return loadFromUrl(uri);
|
|
487
|
+
}
|
|
488
|
+
if (uri.startsWith("file://")) {
|
|
489
|
+
const filePath = uri.slice(7);
|
|
490
|
+
return loadFromFile(filePath);
|
|
436
491
|
}
|
|
437
|
-
|
|
438
|
-
return effect.Effect.runPromise(loader.loadFromUri(uri));
|
|
492
|
+
return loadFromFile(uri);
|
|
439
493
|
}
|
|
440
494
|
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
|
-
};
|
|
495
|
+
return parseAndValidateConfig(content);
|
|
466
496
|
}
|
|
467
497
|
async function loadConfigWithOptions(options = {}) {
|
|
468
|
-
const loadOptions = options.cacheTimeout !== void 0 ? { cacheTimeout: options.cacheTimeout } : void 0;
|
|
469
498
|
if (options.config) {
|
|
470
499
|
return loadConfigFromInline(options.config);
|
|
471
500
|
}
|
|
472
501
|
const envConfigPath = process.env.ATRIM_INSTRUMENTATION_CONFIG;
|
|
473
502
|
if (envConfigPath) {
|
|
474
|
-
return loadConfig(envConfigPath
|
|
503
|
+
return loadConfig(envConfigPath);
|
|
475
504
|
}
|
|
476
505
|
if (options.configUrl) {
|
|
477
|
-
return loadConfig(options.configUrl
|
|
506
|
+
return loadConfig(options.configUrl);
|
|
478
507
|
}
|
|
479
508
|
if (options.configPath) {
|
|
480
|
-
return loadConfig(options.configPath
|
|
509
|
+
return loadConfig(options.configPath);
|
|
481
510
|
}
|
|
482
511
|
const { existsSync } = await import('fs');
|
|
483
512
|
const { join } = await import('path');
|
|
484
513
|
const defaultPath = join(process.cwd(), "instrumentation.yaml");
|
|
485
514
|
if (existsSync(defaultPath)) {
|
|
486
|
-
return loadConfig(defaultPath
|
|
515
|
+
return loadConfig(defaultPath);
|
|
487
516
|
}
|
|
488
|
-
return
|
|
517
|
+
return defaultConfig;
|
|
489
518
|
}
|
|
490
519
|
|
|
491
520
|
// src/integrations/effect/effect-tracer.ts
|
|
521
|
+
var SDK_NAME = "@effect/opentelemetry";
|
|
522
|
+
var ATTR_TELEMETRY_EXPORTER_MODE = "telemetry.exporter.mode";
|
|
523
|
+
var ATTR_EFFECT_INSTRUMENTED = "effect.instrumented";
|
|
524
|
+
var EffectAttributeTracerLayer = effect.Layer.effect(
|
|
525
|
+
effect.Tracer.Tracer,
|
|
526
|
+
effect.Effect.gen(function* () {
|
|
527
|
+
const baseTracer = yield* OtelTracer__namespace.make;
|
|
528
|
+
return effect.Tracer.make({
|
|
529
|
+
span: (name, parent, context2, links, startTime, kind, options) => {
|
|
530
|
+
const span = baseTracer.span(name, parent, context2, links, startTime, kind, options);
|
|
531
|
+
span.attribute(ATTR_EFFECT_INSTRUMENTED, true);
|
|
532
|
+
return span;
|
|
533
|
+
},
|
|
534
|
+
context: (f, fiber) => baseTracer.context(f, fiber)
|
|
535
|
+
});
|
|
536
|
+
}).pipe(effect.Effect.provide(OtelTracer__namespace.layerGlobalTracer))
|
|
537
|
+
);
|
|
492
538
|
function createEffectInstrumentation(options = {}) {
|
|
493
539
|
return effect.Layer.unwrapEffect(
|
|
494
540
|
effect.Effect.gen(function* () {
|
|
@@ -499,106 +545,228 @@ function createEffectInstrumentation(options = {}) {
|
|
|
499
545
|
message: error instanceof Error ? error.message : String(error)
|
|
500
546
|
})
|
|
501
547
|
});
|
|
548
|
+
const effectEnabled = process.env.OTEL_EFFECT_ENABLED !== "false" && (config.effect?.enabled ?? true);
|
|
549
|
+
if (!effectEnabled) {
|
|
550
|
+
logger.log("@atrim/instrumentation/effect: Effect tracing disabled via config");
|
|
551
|
+
return effect.Layer.empty;
|
|
552
|
+
}
|
|
502
553
|
yield* effect.Effect.sync(() => {
|
|
503
554
|
const loggingLevel = config.instrumentation.logging || "on";
|
|
504
555
|
logger.setLevel(loggingLevel);
|
|
505
556
|
});
|
|
506
557
|
yield* effect.Effect.sync(() => initializePatternMatcher(config));
|
|
507
|
-
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
508
558
|
const serviceName = options.serviceName || process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
509
559
|
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
|
-
|
|
560
|
+
const exporterMode = options.exporterMode ?? config.effect?.exporter ?? "unified";
|
|
561
|
+
const resourceAttributes = {
|
|
562
|
+
"platform.component": "effect",
|
|
563
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
564
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
565
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: exporterMode
|
|
566
|
+
};
|
|
567
|
+
if (exporterMode === "standalone") {
|
|
568
|
+
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
569
|
+
logger.log("Effect OpenTelemetry instrumentation (standalone)");
|
|
570
|
+
logger.log(` Service: ${serviceName}`);
|
|
571
|
+
logger.log(` Endpoint: ${otlpEndpoint}`);
|
|
572
|
+
logger.log(" WARNING: Standalone mode bypasses Node SDK filtering");
|
|
573
|
+
return Otlp__namespace.layer({
|
|
574
|
+
baseUrl: otlpEndpoint,
|
|
575
|
+
resource: {
|
|
576
|
+
serviceName,
|
|
577
|
+
serviceVersion,
|
|
578
|
+
attributes: resourceAttributes
|
|
579
|
+
},
|
|
580
|
+
// Bridge Effect context to OpenTelemetry global context
|
|
581
|
+
tracerContext: (f, span) => {
|
|
582
|
+
if (span._tag !== "Span") {
|
|
583
|
+
return f();
|
|
584
|
+
}
|
|
585
|
+
const spanContext = {
|
|
586
|
+
traceId: span.traceId,
|
|
587
|
+
spanId: span.spanId,
|
|
588
|
+
traceFlags: span.sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
|
|
589
|
+
};
|
|
590
|
+
const otelSpan = api.trace.wrapSpanContext(spanContext);
|
|
591
|
+
return api.context.with(api.trace.setSpan(api.context.active(), otelSpan), f);
|
|
533
592
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
593
|
+
}).pipe(effect.Layer.provide(platform.FetchHttpClient.layer));
|
|
594
|
+
} else {
|
|
595
|
+
logger.log("Effect OpenTelemetry instrumentation (unified)");
|
|
596
|
+
logger.log(` Service: ${serviceName}`);
|
|
597
|
+
logger.log(" Using global TracerProvider for span export");
|
|
598
|
+
return EffectAttributeTracerLayer.pipe(
|
|
599
|
+
effect.Layer.provide(
|
|
600
|
+
Resource__namespace.layer({
|
|
601
|
+
serviceName,
|
|
602
|
+
serviceVersion,
|
|
603
|
+
attributes: resourceAttributes
|
|
604
|
+
})
|
|
605
|
+
)
|
|
606
|
+
);
|
|
545
607
|
}
|
|
546
|
-
return otlpLayer;
|
|
547
608
|
})
|
|
548
609
|
).pipe(effect.Layer.orDie);
|
|
549
610
|
}
|
|
550
611
|
var EffectInstrumentationLive = effect.Effect.sync(() => {
|
|
551
|
-
const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
552
612
|
const serviceName = process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
553
613
|
const serviceVersion = process.env.npm_package_version || "1.0.0";
|
|
554
614
|
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));
|
|
615
|
+
logger.log("Effect OpenTelemetry tracer (unified)");
|
|
616
|
+
logger.log(` Service: ${serviceName}`);
|
|
617
|
+
return EffectAttributeTracerLayer.pipe(
|
|
618
|
+
effect.Layer.provide(
|
|
619
|
+
Resource__namespace.layer({
|
|
620
|
+
serviceName,
|
|
621
|
+
serviceVersion,
|
|
622
|
+
attributes: {
|
|
623
|
+
"platform.component": "effect",
|
|
624
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
625
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
626
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: "unified"
|
|
627
|
+
}
|
|
628
|
+
})
|
|
629
|
+
)
|
|
630
|
+
);
|
|
582
631
|
}).pipe(effect.Layer.unwrapEffect);
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
632
|
+
function annotateUser(userId, email, username) {
|
|
633
|
+
const attributes = {
|
|
634
|
+
"user.id": userId
|
|
635
|
+
};
|
|
636
|
+
if (email) attributes["user.email"] = email;
|
|
637
|
+
if (username) attributes["user.name"] = username;
|
|
638
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
586
639
|
}
|
|
587
|
-
function annotateDataSize(
|
|
640
|
+
function annotateDataSize(bytes, items, compressionRatio) {
|
|
641
|
+
const attributes = {
|
|
642
|
+
"data.size.bytes": bytes,
|
|
643
|
+
"data.size.items": items
|
|
644
|
+
};
|
|
645
|
+
if (compressionRatio !== void 0) {
|
|
646
|
+
attributes["data.compression.ratio"] = compressionRatio;
|
|
647
|
+
}
|
|
648
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
588
649
|
}
|
|
589
|
-
function annotateBatch(
|
|
650
|
+
function annotateBatch(totalItems, batchSize, successCount, failureCount) {
|
|
651
|
+
const attributes = {
|
|
652
|
+
"batch.size": batchSize,
|
|
653
|
+
"batch.total_items": totalItems,
|
|
654
|
+
"batch.count": Math.ceil(totalItems / batchSize)
|
|
655
|
+
};
|
|
656
|
+
if (successCount !== void 0) {
|
|
657
|
+
attributes["batch.success_count"] = successCount;
|
|
658
|
+
}
|
|
659
|
+
if (failureCount !== void 0) {
|
|
660
|
+
attributes["batch.failure_count"] = failureCount;
|
|
661
|
+
}
|
|
662
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
590
663
|
}
|
|
591
|
-
function annotateLLM(
|
|
664
|
+
function annotateLLM(model, provider, tokens) {
|
|
665
|
+
const attributes = {
|
|
666
|
+
"llm.model": model,
|
|
667
|
+
"llm.provider": provider
|
|
668
|
+
};
|
|
669
|
+
if (tokens) {
|
|
670
|
+
if (tokens.prompt !== void 0) attributes["llm.tokens.prompt"] = tokens.prompt;
|
|
671
|
+
if (tokens.completion !== void 0) attributes["llm.tokens.completion"] = tokens.completion;
|
|
672
|
+
if (tokens.total !== void 0) attributes["llm.tokens.total"] = tokens.total;
|
|
673
|
+
}
|
|
674
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
675
|
+
}
|
|
676
|
+
function annotateQuery(query, duration, rowCount, database) {
|
|
677
|
+
const attributes = {
|
|
678
|
+
"db.statement": query.length > 1e3 ? query.substring(0, 1e3) + "..." : query
|
|
679
|
+
};
|
|
680
|
+
if (duration !== void 0) attributes["db.duration.ms"] = duration;
|
|
681
|
+
if (rowCount !== void 0) attributes["db.row_count"] = rowCount;
|
|
682
|
+
if (database) attributes["db.name"] = database;
|
|
683
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
684
|
+
}
|
|
685
|
+
function annotateHttpRequest(method, url, statusCode, contentLength) {
|
|
686
|
+
const attributes = {
|
|
687
|
+
"http.method": method,
|
|
688
|
+
"http.url": url
|
|
689
|
+
};
|
|
690
|
+
if (statusCode !== void 0) attributes["http.status_code"] = statusCode;
|
|
691
|
+
if (contentLength !== void 0) attributes["http.response.content_length"] = contentLength;
|
|
692
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
693
|
+
}
|
|
694
|
+
function annotateError(error, recoverable, errorType) {
|
|
695
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
696
|
+
const errorStack = typeof error === "string" ? void 0 : error.stack;
|
|
697
|
+
const attributes = {
|
|
698
|
+
"error.message": errorMessage,
|
|
699
|
+
"error.recoverable": recoverable
|
|
700
|
+
};
|
|
701
|
+
if (errorType) attributes["error.type"] = errorType;
|
|
702
|
+
if (errorStack) attributes["error.stack"] = errorStack;
|
|
703
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
592
704
|
}
|
|
593
|
-
function
|
|
705
|
+
function annotatePriority(priority, reason) {
|
|
706
|
+
const attributes = {
|
|
707
|
+
"operation.priority": priority
|
|
708
|
+
};
|
|
709
|
+
if (reason) attributes["operation.priority.reason"] = reason;
|
|
710
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
594
711
|
}
|
|
595
|
-
function
|
|
712
|
+
function annotateCache(hit, key, ttl) {
|
|
713
|
+
const attributes = {
|
|
714
|
+
"cache.hit": hit,
|
|
715
|
+
"cache.key": key
|
|
716
|
+
};
|
|
717
|
+
if (ttl !== void 0) attributes["cache.ttl.seconds"] = ttl;
|
|
718
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
596
719
|
}
|
|
597
|
-
function
|
|
720
|
+
function extractEffectMetadata() {
|
|
721
|
+
return effect.Effect.gen(function* () {
|
|
722
|
+
const metadata = {};
|
|
723
|
+
const currentFiber = effect.Fiber.getCurrentFiber();
|
|
724
|
+
if (effect.Option.isSome(currentFiber)) {
|
|
725
|
+
const fiber = currentFiber.value;
|
|
726
|
+
const fiberId = fiber.id();
|
|
727
|
+
metadata["effect.fiber.id"] = effect.FiberId.threadName(fiberId);
|
|
728
|
+
const status = yield* effect.Fiber.status(fiber);
|
|
729
|
+
if (status._tag) {
|
|
730
|
+
metadata["effect.fiber.status"] = status._tag;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
const parentSpanResult = yield* effect.Effect.currentSpan.pipe(
|
|
734
|
+
effect.Effect.option
|
|
735
|
+
// Convert NoSuchElementException to Option
|
|
736
|
+
);
|
|
737
|
+
if (effect.Option.isSome(parentSpanResult)) {
|
|
738
|
+
const parentSpan = parentSpanResult.value;
|
|
739
|
+
metadata["effect.operation.nested"] = true;
|
|
740
|
+
metadata["effect.operation.root"] = false;
|
|
741
|
+
if (parentSpan.spanId) {
|
|
742
|
+
metadata["effect.parent.span.id"] = parentSpan.spanId;
|
|
743
|
+
}
|
|
744
|
+
if (parentSpan.name) {
|
|
745
|
+
metadata["effect.parent.span.name"] = parentSpan.name;
|
|
746
|
+
}
|
|
747
|
+
if (parentSpan.traceId) {
|
|
748
|
+
metadata["effect.parent.trace.id"] = parentSpan.traceId;
|
|
749
|
+
}
|
|
750
|
+
} else {
|
|
751
|
+
metadata["effect.operation.nested"] = false;
|
|
752
|
+
metadata["effect.operation.root"] = true;
|
|
753
|
+
}
|
|
754
|
+
return metadata;
|
|
755
|
+
});
|
|
598
756
|
}
|
|
599
|
-
function
|
|
757
|
+
function autoEnrichSpan() {
|
|
758
|
+
return effect.Effect.gen(function* () {
|
|
759
|
+
const metadata = yield* extractEffectMetadata();
|
|
760
|
+
yield* effect.Effect.annotateCurrentSpan(metadata);
|
|
761
|
+
});
|
|
600
762
|
}
|
|
601
|
-
function
|
|
763
|
+
function withAutoEnrichedSpan(spanName, options) {
|
|
764
|
+
return (self) => {
|
|
765
|
+
return effect.Effect.gen(function* () {
|
|
766
|
+
yield* autoEnrichSpan();
|
|
767
|
+
return yield* self;
|
|
768
|
+
}).pipe(effect.Effect.withSpan(spanName, options));
|
|
769
|
+
};
|
|
602
770
|
}
|
|
603
771
|
var createLogicalParentLink = (parentSpan, useSpanLinks) => {
|
|
604
772
|
if (!useSpanLinks) {
|
|
@@ -737,8 +905,11 @@ exports.annotatePriority = annotatePriority;
|
|
|
737
905
|
exports.annotateQuery = annotateQuery;
|
|
738
906
|
exports.annotateSpawnedTasks = annotateSpawnedTasks;
|
|
739
907
|
exports.annotateUser = annotateUser;
|
|
908
|
+
exports.autoEnrichSpan = autoEnrichSpan;
|
|
740
909
|
exports.createEffectInstrumentation = createEffectInstrumentation;
|
|
910
|
+
exports.extractEffectMetadata = extractEffectMetadata;
|
|
741
911
|
exports.runIsolated = runIsolated;
|
|
742
912
|
exports.runWithSpan = runWithSpan;
|
|
913
|
+
exports.withAutoEnrichedSpan = withAutoEnrichedSpan;
|
|
743
914
|
//# sourceMappingURL=index.cjs.map
|
|
744
915
|
//# sourceMappingURL=index.cjs.map
|