@atrim/instrument-node 0.7.1-dev.14fdea7.20260108220010 → 0.7.1-dev.14fdea7.20260108231232
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/package.json +1 -1
- package/target/dist/index.cjs +3 -0
- package/target/dist/index.cjs.map +1 -1
- package/target/dist/index.js +3 -0
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/auto/index.cjs +193 -121
- package/target/dist/integrations/effect/auto/index.cjs.map +1 -1
- package/target/dist/integrations/effect/auto/index.d.cts +79 -1
- package/target/dist/integrations/effect/auto/index.d.ts +79 -1
- package/target/dist/integrations/effect/auto/index.js +192 -122
- package/target/dist/integrations/effect/auto/index.js.map +1 -1
- package/target/dist/integrations/effect/index.cjs +3 -0
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.js +3 -0
- package/target/dist/integrations/effect/index.js.map +1 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var effect = require('effect');
|
|
4
|
-
var
|
|
4
|
+
var opentelemetry = require('@effect/opentelemetry');
|
|
5
5
|
var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
6
6
|
var exporterTraceOtlpHttp = require('@opentelemetry/exporter-trace-otlp-http');
|
|
7
|
-
var resources = require('@opentelemetry/resources');
|
|
8
|
-
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
9
7
|
var FileSystem = require('@effect/platform/FileSystem');
|
|
10
8
|
var HttpClient = require('@effect/platform/HttpClient');
|
|
11
9
|
var HttpClientRequest = require('@effect/platform/HttpClientRequest');
|
|
12
10
|
var yaml = require('yaml');
|
|
13
11
|
var zod = require('zod');
|
|
12
|
+
var OtelApi = require('@opentelemetry/api');
|
|
13
|
+
var resources = require('@opentelemetry/resources');
|
|
14
|
+
var semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
14
15
|
var path = require('path');
|
|
15
16
|
|
|
16
17
|
function _interopNamespace(e) {
|
|
@@ -31,9 +32,9 @@ function _interopNamespace(e) {
|
|
|
31
32
|
return Object.freeze(n);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
var OtelApi__namespace = /*#__PURE__*/_interopNamespace(OtelApi);
|
|
35
35
|
var HttpClient__namespace = /*#__PURE__*/_interopNamespace(HttpClient);
|
|
36
36
|
var HttpClientRequest__namespace = /*#__PURE__*/_interopNamespace(HttpClientRequest);
|
|
37
|
+
var OtelApi__namespace = /*#__PURE__*/_interopNamespace(OtelApi);
|
|
37
38
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
38
39
|
|
|
39
40
|
var __defProp = Object.defineProperty;
|
|
@@ -162,6 +163,9 @@ var ExporterConfigSchema = zod.z.object({
|
|
|
162
163
|
// OTLP endpoint URL (for type: otlp)
|
|
163
164
|
// Defaults to OTEL_EXPORTER_OTLP_ENDPOINT env var or http://localhost:4318
|
|
164
165
|
endpoint: zod.z.string().optional(),
|
|
166
|
+
// Custom headers to send with OTLP requests (for type: otlp)
|
|
167
|
+
// Useful for authentication (x-api-key, Authorization, etc.)
|
|
168
|
+
headers: zod.z.record(zod.z.string()).optional(),
|
|
165
169
|
// Span processor type
|
|
166
170
|
// - 'batch': Batch spans for export (production, lower overhead)
|
|
167
171
|
// - 'simple': Export immediately (development, no batching delay)
|
|
@@ -488,121 +492,6 @@ var Logger = class {
|
|
|
488
492
|
}
|
|
489
493
|
};
|
|
490
494
|
var logger = new Logger();
|
|
491
|
-
var compiledRulesCache = /* @__PURE__ */ new WeakMap();
|
|
492
|
-
function compileNamingRules(rules) {
|
|
493
|
-
const cached = compiledRulesCache.get(rules);
|
|
494
|
-
if (cached) return cached;
|
|
495
|
-
const compiled = rules.map((rule) => ({
|
|
496
|
-
original: rule,
|
|
497
|
-
filePattern: rule.match.file ? new RegExp(rule.match.file) : void 0,
|
|
498
|
-
functionPattern: rule.match.function ? new RegExp(rule.match.function) : void 0,
|
|
499
|
-
modulePattern: rule.match.module ? new RegExp(rule.match.module) : void 0
|
|
500
|
-
}));
|
|
501
|
-
compiledRulesCache.set(rules, compiled);
|
|
502
|
-
return compiled;
|
|
503
|
-
}
|
|
504
|
-
function extractModuleName(filePath) {
|
|
505
|
-
const basename2 = path__namespace.basename(filePath, path__namespace.extname(filePath));
|
|
506
|
-
return basename2.replace(/\.(service|controller|handler|util|helper|model|repo|repository)$/i, "").replace(/(Service|Controller|Handler|Util|Helper|Model|Repo|Repository)$/i, "");
|
|
507
|
-
}
|
|
508
|
-
function applyTemplate(template, variables, matchGroups) {
|
|
509
|
-
let result = template;
|
|
510
|
-
for (const [key, value] of Object.entries(variables)) {
|
|
511
|
-
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), value);
|
|
512
|
-
}
|
|
513
|
-
if (matchGroups) {
|
|
514
|
-
result = result.replace(
|
|
515
|
-
/\{match:(\w+):(\d+)\}/g,
|
|
516
|
-
(_fullMatch, field, index) => {
|
|
517
|
-
const groups = matchGroups.get(field);
|
|
518
|
-
const idx = parseInt(index, 10);
|
|
519
|
-
if (groups && groups[idx]) {
|
|
520
|
-
return groups[idx];
|
|
521
|
-
}
|
|
522
|
-
return "";
|
|
523
|
-
}
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
return result;
|
|
527
|
-
}
|
|
528
|
-
function findMatchingRule(sourceInfo, config) {
|
|
529
|
-
const rules = config.span_naming?.rules;
|
|
530
|
-
if (!rules || rules.length === 0) return void 0;
|
|
531
|
-
const compiledRules = compileNamingRules(rules);
|
|
532
|
-
for (const rule of compiledRules) {
|
|
533
|
-
const matchGroups = /* @__PURE__ */ new Map();
|
|
534
|
-
let allMatched = true;
|
|
535
|
-
if (rule.filePattern) {
|
|
536
|
-
if (sourceInfo?.file) {
|
|
537
|
-
const match = sourceInfo.file.match(rule.filePattern);
|
|
538
|
-
if (match) {
|
|
539
|
-
matchGroups.set("file", match.slice(1));
|
|
540
|
-
} else {
|
|
541
|
-
allMatched = false;
|
|
542
|
-
}
|
|
543
|
-
} else {
|
|
544
|
-
allMatched = false;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
if (rule.functionPattern && allMatched) {
|
|
548
|
-
if (sourceInfo?.function) {
|
|
549
|
-
const match = sourceInfo.function.match(rule.functionPattern);
|
|
550
|
-
if (match) {
|
|
551
|
-
matchGroups.set("function", match.slice(1));
|
|
552
|
-
} else {
|
|
553
|
-
allMatched = false;
|
|
554
|
-
}
|
|
555
|
-
} else {
|
|
556
|
-
allMatched = false;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (rule.modulePattern && allMatched) {
|
|
560
|
-
const moduleName = sourceInfo?.file ? extractModuleName(sourceInfo.file) : "";
|
|
561
|
-
if (moduleName) {
|
|
562
|
-
const match = moduleName.match(rule.modulePattern);
|
|
563
|
-
if (match) {
|
|
564
|
-
matchGroups.set("module", match.slice(1));
|
|
565
|
-
} else {
|
|
566
|
-
allMatched = false;
|
|
567
|
-
}
|
|
568
|
-
} else {
|
|
569
|
-
allMatched = false;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
if (allMatched) {
|
|
573
|
-
return { rule, matchGroups };
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
return void 0;
|
|
577
|
-
}
|
|
578
|
-
function inferSpanName(fiberId, sourceInfo, config) {
|
|
579
|
-
const variables = {
|
|
580
|
-
fiber_id: String(fiberId),
|
|
581
|
-
function: sourceInfo?.function || "anonymous",
|
|
582
|
-
module: sourceInfo?.file ? extractModuleName(sourceInfo.file) : "unknown",
|
|
583
|
-
file: sourceInfo?.file || "unknown",
|
|
584
|
-
line: sourceInfo?.line ? String(sourceInfo.line) : "0",
|
|
585
|
-
operator: "gen"
|
|
586
|
-
// Default operator, could be enhanced with more context
|
|
587
|
-
};
|
|
588
|
-
const match = findMatchingRule(sourceInfo, config);
|
|
589
|
-
if (match) {
|
|
590
|
-
return applyTemplate(match.rule.original.name, variables, match.matchGroups);
|
|
591
|
-
}
|
|
592
|
-
const defaultTemplate = config.span_naming?.default || "effect.fiber.{fiber_id}";
|
|
593
|
-
return applyTemplate(defaultTemplate, variables);
|
|
594
|
-
}
|
|
595
|
-
function sanitizeSpanName(name) {
|
|
596
|
-
if (!name) return "effect.fiber.unknown";
|
|
597
|
-
let sanitized = name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
598
|
-
sanitized = sanitized.replace(/_+/g, "_");
|
|
599
|
-
sanitized = sanitized.replace(/^_+|_+$/g, "");
|
|
600
|
-
if (!sanitized) return "effect.fiber.unknown";
|
|
601
|
-
if (sanitized.length > 256) {
|
|
602
|
-
sanitized = sanitized.substring(0, 256);
|
|
603
|
-
}
|
|
604
|
-
return sanitized;
|
|
605
|
-
}
|
|
606
495
|
async function loadFromFile(filePath) {
|
|
607
496
|
const { readFile } = await import('fs/promises');
|
|
608
497
|
const content = await readFile(filePath, "utf-8");
|
|
@@ -723,6 +612,182 @@ var loadFullConfig = (options) => effect.Effect.gen(function* () {
|
|
|
723
612
|
return config;
|
|
724
613
|
});
|
|
725
614
|
|
|
615
|
+
// src/integrations/effect/auto/effect-tracing.ts
|
|
616
|
+
var createEffectTracingLayer = () => {
|
|
617
|
+
return effect.Layer.unwrapEffect(
|
|
618
|
+
effect.Effect.gen(function* () {
|
|
619
|
+
const config = yield* loadFullConfig();
|
|
620
|
+
const serviceName = process.env.OTEL_SERVICE_NAME || "effect-service";
|
|
621
|
+
const serviceVersion = process.env.npm_package_version || "1.0.0";
|
|
622
|
+
const exporterConfig = config.effect?.exporter_config ?? {
|
|
623
|
+
type: "otlp",
|
|
624
|
+
processor: "batch"
|
|
625
|
+
};
|
|
626
|
+
logger.log("@atrim/auto-trace: Effect-native tracing enabled");
|
|
627
|
+
logger.log(` Service: ${serviceName}`);
|
|
628
|
+
logger.log(` Exporter: ${exporterConfig.type}`);
|
|
629
|
+
if (exporterConfig.type === "none") {
|
|
630
|
+
logger.log('@atrim/auto-trace: Exporter type is "none", using empty layer');
|
|
631
|
+
return effect.Layer.empty;
|
|
632
|
+
}
|
|
633
|
+
const createSpanProcessor = () => {
|
|
634
|
+
if (exporterConfig.type === "console") {
|
|
635
|
+
logger.log("@atrim/auto-trace: Using ConsoleSpanExporter with SimpleSpanProcessor");
|
|
636
|
+
return new sdkTraceBase.SimpleSpanProcessor(new sdkTraceBase.ConsoleSpanExporter());
|
|
637
|
+
}
|
|
638
|
+
const endpoint = exporterConfig.endpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
639
|
+
logger.log(`@atrim/auto-trace: Using OTLPTraceExporter (${endpoint})`);
|
|
640
|
+
const otlpConfig = {
|
|
641
|
+
url: `${endpoint}/v1/traces`
|
|
642
|
+
};
|
|
643
|
+
if (exporterConfig.headers) {
|
|
644
|
+
otlpConfig.headers = exporterConfig.headers;
|
|
645
|
+
logger.log(`@atrim/auto-trace: Using custom headers: ${Object.keys(exporterConfig.headers).join(", ")}`);
|
|
646
|
+
}
|
|
647
|
+
const exporter = new exporterTraceOtlpHttp.OTLPTraceExporter(otlpConfig);
|
|
648
|
+
if (exporterConfig.processor === "simple") {
|
|
649
|
+
logger.log("@atrim/auto-trace: Using SimpleSpanProcessor");
|
|
650
|
+
return new sdkTraceBase.SimpleSpanProcessor(exporter);
|
|
651
|
+
}
|
|
652
|
+
const batchConfig = exporterConfig.batch ?? {
|
|
653
|
+
scheduled_delay_millis: 1e3,
|
|
654
|
+
max_export_batch_size: 100
|
|
655
|
+
};
|
|
656
|
+
logger.log("@atrim/auto-trace: Using BatchSpanProcessor");
|
|
657
|
+
return new sdkTraceBase.BatchSpanProcessor(exporter, {
|
|
658
|
+
scheduledDelayMillis: batchConfig.scheduled_delay_millis,
|
|
659
|
+
maxExportBatchSize: batchConfig.max_export_batch_size
|
|
660
|
+
});
|
|
661
|
+
};
|
|
662
|
+
const sdkLayer = opentelemetry.NodeSdk.layer(() => ({
|
|
663
|
+
resource: {
|
|
664
|
+
serviceName,
|
|
665
|
+
serviceVersion
|
|
666
|
+
},
|
|
667
|
+
spanProcessor: createSpanProcessor()
|
|
668
|
+
}));
|
|
669
|
+
logger.log("@atrim/auto-trace: NodeSdk layer created - HTTP requests will be auto-traced");
|
|
670
|
+
return effect.Layer.discard(sdkLayer);
|
|
671
|
+
})
|
|
672
|
+
);
|
|
673
|
+
};
|
|
674
|
+
var EffectTracingLive = createEffectTracingLayer();
|
|
675
|
+
var compiledRulesCache = /* @__PURE__ */ new WeakMap();
|
|
676
|
+
function compileNamingRules(rules) {
|
|
677
|
+
const cached = compiledRulesCache.get(rules);
|
|
678
|
+
if (cached) return cached;
|
|
679
|
+
const compiled = rules.map((rule) => ({
|
|
680
|
+
original: rule,
|
|
681
|
+
filePattern: rule.match.file ? new RegExp(rule.match.file) : void 0,
|
|
682
|
+
functionPattern: rule.match.function ? new RegExp(rule.match.function) : void 0,
|
|
683
|
+
modulePattern: rule.match.module ? new RegExp(rule.match.module) : void 0
|
|
684
|
+
}));
|
|
685
|
+
compiledRulesCache.set(rules, compiled);
|
|
686
|
+
return compiled;
|
|
687
|
+
}
|
|
688
|
+
function extractModuleName(filePath) {
|
|
689
|
+
const basename2 = path__namespace.basename(filePath, path__namespace.extname(filePath));
|
|
690
|
+
return basename2.replace(/\.(service|controller|handler|util|helper|model|repo|repository)$/i, "").replace(/(Service|Controller|Handler|Util|Helper|Model|Repo|Repository)$/i, "");
|
|
691
|
+
}
|
|
692
|
+
function applyTemplate(template, variables, matchGroups) {
|
|
693
|
+
let result = template;
|
|
694
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
695
|
+
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), value);
|
|
696
|
+
}
|
|
697
|
+
if (matchGroups) {
|
|
698
|
+
result = result.replace(
|
|
699
|
+
/\{match:(\w+):(\d+)\}/g,
|
|
700
|
+
(_fullMatch, field, index) => {
|
|
701
|
+
const groups = matchGroups.get(field);
|
|
702
|
+
const idx = parseInt(index, 10);
|
|
703
|
+
if (groups && groups[idx]) {
|
|
704
|
+
return groups[idx];
|
|
705
|
+
}
|
|
706
|
+
return "";
|
|
707
|
+
}
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
return result;
|
|
711
|
+
}
|
|
712
|
+
function findMatchingRule(sourceInfo, config) {
|
|
713
|
+
const rules = config.span_naming?.rules;
|
|
714
|
+
if (!rules || rules.length === 0) return void 0;
|
|
715
|
+
const compiledRules = compileNamingRules(rules);
|
|
716
|
+
for (const rule of compiledRules) {
|
|
717
|
+
const matchGroups = /* @__PURE__ */ new Map();
|
|
718
|
+
let allMatched = true;
|
|
719
|
+
if (rule.filePattern) {
|
|
720
|
+
if (sourceInfo?.file) {
|
|
721
|
+
const match = sourceInfo.file.match(rule.filePattern);
|
|
722
|
+
if (match) {
|
|
723
|
+
matchGroups.set("file", match.slice(1));
|
|
724
|
+
} else {
|
|
725
|
+
allMatched = false;
|
|
726
|
+
}
|
|
727
|
+
} else {
|
|
728
|
+
allMatched = false;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
if (rule.functionPattern && allMatched) {
|
|
732
|
+
if (sourceInfo?.function) {
|
|
733
|
+
const match = sourceInfo.function.match(rule.functionPattern);
|
|
734
|
+
if (match) {
|
|
735
|
+
matchGroups.set("function", match.slice(1));
|
|
736
|
+
} else {
|
|
737
|
+
allMatched = false;
|
|
738
|
+
}
|
|
739
|
+
} else {
|
|
740
|
+
allMatched = false;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
if (rule.modulePattern && allMatched) {
|
|
744
|
+
const moduleName = sourceInfo?.file ? extractModuleName(sourceInfo.file) : "";
|
|
745
|
+
if (moduleName) {
|
|
746
|
+
const match = moduleName.match(rule.modulePattern);
|
|
747
|
+
if (match) {
|
|
748
|
+
matchGroups.set("module", match.slice(1));
|
|
749
|
+
} else {
|
|
750
|
+
allMatched = false;
|
|
751
|
+
}
|
|
752
|
+
} else {
|
|
753
|
+
allMatched = false;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (allMatched) {
|
|
757
|
+
return { rule, matchGroups };
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
return void 0;
|
|
761
|
+
}
|
|
762
|
+
function inferSpanName(fiberId, sourceInfo, config) {
|
|
763
|
+
const variables = {
|
|
764
|
+
fiber_id: String(fiberId),
|
|
765
|
+
function: sourceInfo?.function || "anonymous",
|
|
766
|
+
module: sourceInfo?.file ? extractModuleName(sourceInfo.file) : "unknown",
|
|
767
|
+
file: sourceInfo?.file || "unknown",
|
|
768
|
+
line: sourceInfo?.line ? String(sourceInfo.line) : "0",
|
|
769
|
+
operator: "gen"
|
|
770
|
+
// Default operator, could be enhanced with more context
|
|
771
|
+
};
|
|
772
|
+
const match = findMatchingRule(sourceInfo, config);
|
|
773
|
+
if (match) {
|
|
774
|
+
return applyTemplate(match.rule.original.name, variables, match.matchGroups);
|
|
775
|
+
}
|
|
776
|
+
const defaultTemplate = config.span_naming?.default || "effect.fiber.{fiber_id}";
|
|
777
|
+
return applyTemplate(defaultTemplate, variables);
|
|
778
|
+
}
|
|
779
|
+
function sanitizeSpanName(name) {
|
|
780
|
+
if (!name) return "effect.fiber.unknown";
|
|
781
|
+
let sanitized = name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
782
|
+
sanitized = sanitized.replace(/_+/g, "_");
|
|
783
|
+
sanitized = sanitized.replace(/^_+|_+$/g, "");
|
|
784
|
+
if (!sanitized) return "effect.fiber.unknown";
|
|
785
|
+
if (sanitized.length > 256) {
|
|
786
|
+
sanitized = sanitized.substring(0, 256);
|
|
787
|
+
}
|
|
788
|
+
return sanitized;
|
|
789
|
+
}
|
|
790
|
+
|
|
726
791
|
// src/integrations/effect/auto/supervisor.ts
|
|
727
792
|
var AutoTracingEnabled = effect.FiberRef.unsafeMake(true);
|
|
728
793
|
var AutoTracingSpanName = effect.FiberRef.unsafeMake(effect.Option.none());
|
|
@@ -1023,9 +1088,14 @@ var createExporterLayer = (exporterConfig, serviceName, serviceVersion) => {
|
|
|
1023
1088
|
}
|
|
1024
1089
|
const endpoint = config.endpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318";
|
|
1025
1090
|
logger.log(`@atrim/auto-trace: Using OTLPTraceExporter (${endpoint})`);
|
|
1026
|
-
|
|
1091
|
+
const exporterConfig2 = {
|
|
1027
1092
|
url: `${endpoint}/v1/traces`
|
|
1028
|
-
}
|
|
1093
|
+
};
|
|
1094
|
+
if (config.headers) {
|
|
1095
|
+
exporterConfig2.headers = config.headers;
|
|
1096
|
+
logger.log(`@atrim/auto-trace: Using custom headers: ${Object.keys(config.headers).join(", ")}`);
|
|
1097
|
+
}
|
|
1098
|
+
return new exporterTraceOtlpHttp.OTLPTraceExporter(exporterConfig2);
|
|
1029
1099
|
};
|
|
1030
1100
|
const createSpanProcessor = () => {
|
|
1031
1101
|
const exporter = createSpanExporter();
|
|
@@ -1093,9 +1163,11 @@ exports.AutoTracingEnabled = AutoTracingEnabled;
|
|
|
1093
1163
|
exports.AutoTracingLive = AutoTracingLive;
|
|
1094
1164
|
exports.AutoTracingSpanName = AutoTracingSpanName;
|
|
1095
1165
|
exports.AutoTracingSupervisor = AutoTracingSupervisor;
|
|
1166
|
+
exports.EffectTracingLive = EffectTracingLive;
|
|
1096
1167
|
exports.FullAutoTracingLive = FullAutoTracingLive;
|
|
1097
1168
|
exports.createAutoTracingLayer = createAutoTracingLayer;
|
|
1098
1169
|
exports.createAutoTracingSupervisor = createAutoTracingSupervisor;
|
|
1170
|
+
exports.createEffectTracingLayer = createEffectTracingLayer;
|
|
1099
1171
|
exports.createFullAutoTracingLayer = createFullAutoTracingLayer;
|
|
1100
1172
|
exports.defaultAutoTracingConfig = defaultAutoTracingConfig;
|
|
1101
1173
|
exports.inferSpanName = inferSpanName;
|