@atrim/instrument-node 0.5.0 → 0.5.1-3a86b84-20260105170223
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 +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 +286 -130
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.d.cts +206 -36
- package/target/dist/integrations/effect/index.d.ts +206 -36
- package/target/dist/integrations/effect/index.js +285 -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,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,58 @@ 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";
|
|
492
523
|
function createEffectInstrumentation(options = {}) {
|
|
493
524
|
return effect.Layer.unwrapEffect(
|
|
494
525
|
effect.Effect.gen(function* () {
|
|
@@ -499,106 +530,228 @@ function createEffectInstrumentation(options = {}) {
|
|
|
499
530
|
message: error instanceof Error ? error.message : String(error)
|
|
500
531
|
})
|
|
501
532
|
});
|
|
533
|
+
const effectEnabled = process.env.OTEL_EFFECT_ENABLED !== "false" && (config.effect?.enabled ?? true);
|
|
534
|
+
if (!effectEnabled) {
|
|
535
|
+
logger.log("@atrim/instrumentation/effect: Effect tracing disabled via config");
|
|
536
|
+
return effect.Layer.empty;
|
|
537
|
+
}
|
|
502
538
|
yield* effect.Effect.sync(() => {
|
|
503
539
|
const loggingLevel = config.instrumentation.logging || "on";
|
|
504
540
|
logger.setLevel(loggingLevel);
|
|
505
541
|
});
|
|
506
542
|
yield* effect.Effect.sync(() => initializePatternMatcher(config));
|
|
507
|
-
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
508
543
|
const serviceName = options.serviceName || process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
509
544
|
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
|
-
|
|
545
|
+
const exporterMode = options.exporterMode ?? config.effect?.exporter ?? "unified";
|
|
546
|
+
const resourceAttributes = {
|
|
547
|
+
"platform.component": "effect",
|
|
548
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
549
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
550
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: exporterMode
|
|
551
|
+
};
|
|
552
|
+
if (exporterMode === "standalone") {
|
|
553
|
+
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
554
|
+
logger.log("Effect OpenTelemetry instrumentation (standalone)");
|
|
555
|
+
logger.log(` Service: ${serviceName}`);
|
|
556
|
+
logger.log(` Endpoint: ${otlpEndpoint}`);
|
|
557
|
+
logger.log(" WARNING: Standalone mode bypasses Node SDK filtering");
|
|
558
|
+
return Otlp__namespace.layer({
|
|
559
|
+
baseUrl: otlpEndpoint,
|
|
560
|
+
resource: {
|
|
561
|
+
serviceName,
|
|
562
|
+
serviceVersion,
|
|
563
|
+
attributes: resourceAttributes
|
|
564
|
+
},
|
|
565
|
+
// Bridge Effect context to OpenTelemetry global context
|
|
566
|
+
tracerContext: (f, span) => {
|
|
567
|
+
if (span._tag !== "Span") {
|
|
568
|
+
return f();
|
|
569
|
+
}
|
|
570
|
+
const spanContext = {
|
|
571
|
+
traceId: span.traceId,
|
|
572
|
+
spanId: span.spanId,
|
|
573
|
+
traceFlags: span.sampled ? api.TraceFlags.SAMPLED : api.TraceFlags.NONE
|
|
574
|
+
};
|
|
575
|
+
const otelSpan = api.trace.wrapSpanContext(spanContext);
|
|
576
|
+
return api.context.with(api.trace.setSpan(api.context.active(), otelSpan), f);
|
|
533
577
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
578
|
+
}).pipe(effect.Layer.provide(platform.FetchHttpClient.layer));
|
|
579
|
+
} else {
|
|
580
|
+
logger.log("Effect OpenTelemetry instrumentation (unified)");
|
|
581
|
+
logger.log(` Service: ${serviceName}`);
|
|
582
|
+
logger.log(" Using global TracerProvider for span export");
|
|
583
|
+
return Tracer__namespace.layerGlobal.pipe(
|
|
584
|
+
effect.Layer.provide(
|
|
585
|
+
Resource__namespace.layer({
|
|
586
|
+
serviceName,
|
|
587
|
+
serviceVersion,
|
|
588
|
+
attributes: resourceAttributes
|
|
589
|
+
})
|
|
590
|
+
)
|
|
591
|
+
);
|
|
545
592
|
}
|
|
546
|
-
return otlpLayer;
|
|
547
593
|
})
|
|
548
594
|
).pipe(effect.Layer.orDie);
|
|
549
595
|
}
|
|
550
596
|
var EffectInstrumentationLive = effect.Effect.sync(() => {
|
|
551
|
-
const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
552
597
|
const serviceName = process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
553
598
|
const serviceVersion = process.env.npm_package_version || "1.0.0";
|
|
554
599
|
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));
|
|
600
|
+
logger.log("Effect OpenTelemetry tracer (unified)");
|
|
601
|
+
logger.log(` Service: ${serviceName}`);
|
|
602
|
+
return Tracer__namespace.layerGlobal.pipe(
|
|
603
|
+
effect.Layer.provide(
|
|
604
|
+
Resource__namespace.layer({
|
|
605
|
+
serviceName,
|
|
606
|
+
serviceVersion,
|
|
607
|
+
attributes: {
|
|
608
|
+
"platform.component": "effect",
|
|
609
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_LANGUAGE]: semanticConventions.TELEMETRY_SDK_LANGUAGE_VALUE_NODEJS,
|
|
610
|
+
[semanticConventions.ATTR_TELEMETRY_SDK_NAME]: SDK_NAME,
|
|
611
|
+
[ATTR_TELEMETRY_EXPORTER_MODE]: "unified"
|
|
612
|
+
}
|
|
613
|
+
})
|
|
614
|
+
)
|
|
615
|
+
);
|
|
582
616
|
}).pipe(effect.Layer.unwrapEffect);
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
617
|
+
function annotateUser(userId, email, username) {
|
|
618
|
+
const attributes = {
|
|
619
|
+
"user.id": userId
|
|
620
|
+
};
|
|
621
|
+
if (email) attributes["user.email"] = email;
|
|
622
|
+
if (username) attributes["user.name"] = username;
|
|
623
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
586
624
|
}
|
|
587
|
-
function annotateDataSize(
|
|
625
|
+
function annotateDataSize(bytes, items, compressionRatio) {
|
|
626
|
+
const attributes = {
|
|
627
|
+
"data.size.bytes": bytes,
|
|
628
|
+
"data.size.items": items
|
|
629
|
+
};
|
|
630
|
+
if (compressionRatio !== void 0) {
|
|
631
|
+
attributes["data.compression.ratio"] = compressionRatio;
|
|
632
|
+
}
|
|
633
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
634
|
+
}
|
|
635
|
+
function annotateBatch(totalItems, batchSize, successCount, failureCount) {
|
|
636
|
+
const attributes = {
|
|
637
|
+
"batch.size": batchSize,
|
|
638
|
+
"batch.total_items": totalItems,
|
|
639
|
+
"batch.count": Math.ceil(totalItems / batchSize)
|
|
640
|
+
};
|
|
641
|
+
if (successCount !== void 0) {
|
|
642
|
+
attributes["batch.success_count"] = successCount;
|
|
643
|
+
}
|
|
644
|
+
if (failureCount !== void 0) {
|
|
645
|
+
attributes["batch.failure_count"] = failureCount;
|
|
646
|
+
}
|
|
647
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
648
|
+
}
|
|
649
|
+
function annotateLLM(model, provider, tokens) {
|
|
650
|
+
const attributes = {
|
|
651
|
+
"llm.model": model,
|
|
652
|
+
"llm.provider": provider
|
|
653
|
+
};
|
|
654
|
+
if (tokens) {
|
|
655
|
+
if (tokens.prompt !== void 0) attributes["llm.tokens.prompt"] = tokens.prompt;
|
|
656
|
+
if (tokens.completion !== void 0) attributes["llm.tokens.completion"] = tokens.completion;
|
|
657
|
+
if (tokens.total !== void 0) attributes["llm.tokens.total"] = tokens.total;
|
|
658
|
+
}
|
|
659
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
588
660
|
}
|
|
589
|
-
function
|
|
661
|
+
function annotateQuery(query, duration, rowCount, database) {
|
|
662
|
+
const attributes = {
|
|
663
|
+
"db.statement": query.length > 1e3 ? query.substring(0, 1e3) + "..." : query
|
|
664
|
+
};
|
|
665
|
+
if (duration !== void 0) attributes["db.duration.ms"] = duration;
|
|
666
|
+
if (rowCount !== void 0) attributes["db.row_count"] = rowCount;
|
|
667
|
+
if (database) attributes["db.name"] = database;
|
|
668
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
590
669
|
}
|
|
591
|
-
function
|
|
670
|
+
function annotateHttpRequest(method, url, statusCode, contentLength) {
|
|
671
|
+
const attributes = {
|
|
672
|
+
"http.method": method,
|
|
673
|
+
"http.url": url
|
|
674
|
+
};
|
|
675
|
+
if (statusCode !== void 0) attributes["http.status_code"] = statusCode;
|
|
676
|
+
if (contentLength !== void 0) attributes["http.response.content_length"] = contentLength;
|
|
677
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
592
678
|
}
|
|
593
|
-
function
|
|
679
|
+
function annotateError(error, recoverable, errorType) {
|
|
680
|
+
const errorMessage = typeof error === "string" ? error : error.message;
|
|
681
|
+
const errorStack = typeof error === "string" ? void 0 : error.stack;
|
|
682
|
+
const attributes = {
|
|
683
|
+
"error.message": errorMessage,
|
|
684
|
+
"error.recoverable": recoverable
|
|
685
|
+
};
|
|
686
|
+
if (errorType) attributes["error.type"] = errorType;
|
|
687
|
+
if (errorStack) attributes["error.stack"] = errorStack;
|
|
688
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
689
|
+
}
|
|
690
|
+
function annotatePriority(priority, reason) {
|
|
691
|
+
const attributes = {
|
|
692
|
+
"operation.priority": priority
|
|
693
|
+
};
|
|
694
|
+
if (reason) attributes["operation.priority.reason"] = reason;
|
|
695
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
594
696
|
}
|
|
595
|
-
function
|
|
697
|
+
function annotateCache(hit, key, ttl) {
|
|
698
|
+
const attributes = {
|
|
699
|
+
"cache.hit": hit,
|
|
700
|
+
"cache.key": key
|
|
701
|
+
};
|
|
702
|
+
if (ttl !== void 0) attributes["cache.ttl.seconds"] = ttl;
|
|
703
|
+
return effect.Effect.annotateCurrentSpan(attributes);
|
|
596
704
|
}
|
|
597
|
-
function
|
|
705
|
+
function extractEffectMetadata() {
|
|
706
|
+
return effect.Effect.gen(function* () {
|
|
707
|
+
const metadata = {};
|
|
708
|
+
const currentFiber = effect.Fiber.getCurrentFiber();
|
|
709
|
+
if (effect.Option.isSome(currentFiber)) {
|
|
710
|
+
const fiber = currentFiber.value;
|
|
711
|
+
const fiberId = fiber.id();
|
|
712
|
+
metadata["effect.fiber.id"] = effect.FiberId.threadName(fiberId);
|
|
713
|
+
const status = yield* effect.Fiber.status(fiber);
|
|
714
|
+
if (status._tag) {
|
|
715
|
+
metadata["effect.fiber.status"] = status._tag;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const parentSpanResult = yield* effect.Effect.currentSpan.pipe(
|
|
719
|
+
effect.Effect.option
|
|
720
|
+
// Convert NoSuchElementException to Option
|
|
721
|
+
);
|
|
722
|
+
if (effect.Option.isSome(parentSpanResult)) {
|
|
723
|
+
const parentSpan = parentSpanResult.value;
|
|
724
|
+
metadata["effect.operation.nested"] = true;
|
|
725
|
+
metadata["effect.operation.root"] = false;
|
|
726
|
+
if (parentSpan.spanId) {
|
|
727
|
+
metadata["effect.parent.span.id"] = parentSpan.spanId;
|
|
728
|
+
}
|
|
729
|
+
if (parentSpan.name) {
|
|
730
|
+
metadata["effect.parent.span.name"] = parentSpan.name;
|
|
731
|
+
}
|
|
732
|
+
if (parentSpan.traceId) {
|
|
733
|
+
metadata["effect.parent.trace.id"] = parentSpan.traceId;
|
|
734
|
+
}
|
|
735
|
+
} else {
|
|
736
|
+
metadata["effect.operation.nested"] = false;
|
|
737
|
+
metadata["effect.operation.root"] = true;
|
|
738
|
+
}
|
|
739
|
+
return metadata;
|
|
740
|
+
});
|
|
598
741
|
}
|
|
599
|
-
function
|
|
742
|
+
function autoEnrichSpan() {
|
|
743
|
+
return effect.Effect.gen(function* () {
|
|
744
|
+
const metadata = yield* extractEffectMetadata();
|
|
745
|
+
yield* effect.Effect.annotateCurrentSpan(metadata);
|
|
746
|
+
});
|
|
600
747
|
}
|
|
601
|
-
function
|
|
748
|
+
function withAutoEnrichedSpan(spanName, options) {
|
|
749
|
+
return (self) => {
|
|
750
|
+
return effect.Effect.gen(function* () {
|
|
751
|
+
yield* autoEnrichSpan();
|
|
752
|
+
return yield* self;
|
|
753
|
+
}).pipe(effect.Effect.withSpan(spanName, options));
|
|
754
|
+
};
|
|
602
755
|
}
|
|
603
756
|
var createLogicalParentLink = (parentSpan, useSpanLinks) => {
|
|
604
757
|
if (!useSpanLinks) {
|
|
@@ -737,8 +890,11 @@ exports.annotatePriority = annotatePriority;
|
|
|
737
890
|
exports.annotateQuery = annotateQuery;
|
|
738
891
|
exports.annotateSpawnedTasks = annotateSpawnedTasks;
|
|
739
892
|
exports.annotateUser = annotateUser;
|
|
893
|
+
exports.autoEnrichSpan = autoEnrichSpan;
|
|
740
894
|
exports.createEffectInstrumentation = createEffectInstrumentation;
|
|
895
|
+
exports.extractEffectMetadata = extractEffectMetadata;
|
|
741
896
|
exports.runIsolated = runIsolated;
|
|
742
897
|
exports.runWithSpan = runWithSpan;
|
|
898
|
+
exports.withAutoEnrichedSpan = withAutoEnrichedSpan;
|
|
743
899
|
//# sourceMappingURL=index.cjs.map
|
|
744
900
|
//# sourceMappingURL=index.cjs.map
|