@atrim/instrument-node 0.4.1 → 0.5.0-c05e3a1-20251119131235
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 +4 -4
- package/target/dist/index.cjs +72 -75
- package/target/dist/index.cjs.map +1 -1
- package/target/dist/index.d.cts +107 -140
- package/target/dist/index.d.ts +107 -140
- package/target/dist/index.js +71 -69
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/index.cjs +14 -1
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.js +14 -1
- package/target/dist/integrations/effect/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atrim/instrument-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-c05e3a1-20251119131235",
|
|
4
4
|
"description": "OpenTelemetry instrumentation for Node.js with centralized YAML configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"tsx": "^4.7.0",
|
|
83
83
|
"typescript": "^5.7.2",
|
|
84
84
|
"vitest": "^4.0.8",
|
|
85
|
-
"@atrim/instrument-core": "0.
|
|
85
|
+
"@atrim/instrument-core": "0.5.0"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"@effect/opentelemetry": ">=0.40.0",
|
|
@@ -122,10 +122,10 @@
|
|
|
122
122
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
123
123
|
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
124
124
|
"clean": "rm -rf target",
|
|
125
|
-
"publish:dev:version": "
|
|
125
|
+
"publish:dev:version": "pnpm version $(node -p \"require('./package.json').version\")-$(git rev-parse --short HEAD)-$(date -u +%Y%m%d%H%M%S) --no-git-tag-version",
|
|
126
126
|
"publish:dev:save": "node -p \"require('./package.json').version\" > .version",
|
|
127
127
|
"publish:dev:publish": "pnpm build && pnpm publish --tag dev --access public --no-git-checks",
|
|
128
|
-
"publish:dev:reset": "
|
|
128
|
+
"publish:dev:reset": "pnpm version 0.5.0 --no-git-tag-version",
|
|
129
129
|
"publish:dev": "pnpm publish:dev:version && pnpm publish:dev:save && pnpm publish:dev:publish && pnpm publish:dev:reset"
|
|
130
130
|
}
|
|
131
131
|
}
|
package/target/dist/index.cjs
CHANGED
|
@@ -82,7 +82,20 @@ var HttpFilteringConfigSchema = zod.z.object({
|
|
|
82
82
|
// Patterns to ignore for incoming HTTP requests (string patterns only in YAML)
|
|
83
83
|
ignore_incoming_paths: zod.z.array(zod.z.string()).optional(),
|
|
84
84
|
// Require parent span for outgoing requests (prevents root spans for HTTP calls)
|
|
85
|
-
require_parent_for_outgoing_spans: zod.z.boolean().optional()
|
|
85
|
+
require_parent_for_outgoing_spans: zod.z.boolean().optional(),
|
|
86
|
+
// Trace context propagation configuration
|
|
87
|
+
// Controls which cross-origin requests receive W3C Trace Context headers (traceparent, tracestate)
|
|
88
|
+
propagate_trace_context: zod.z.object({
|
|
89
|
+
// Strategy for trace propagation
|
|
90
|
+
// - "all": Propagate to all cross-origin requests (may cause CORS errors)
|
|
91
|
+
// - "none": Never propagate trace headers
|
|
92
|
+
// - "same-origin": Only propagate to same-origin requests (default, safe)
|
|
93
|
+
// - "patterns": Propagate based on include_urls patterns
|
|
94
|
+
strategy: zod.z.enum(["all", "none", "same-origin", "patterns"]).default("same-origin"),
|
|
95
|
+
// URL patterns to include when strategy is "patterns"
|
|
96
|
+
// Supports regex patterns (e.g., "^https://api\\.myapp\\.com")
|
|
97
|
+
include_urls: zod.z.array(zod.z.string()).optional()
|
|
98
|
+
}).optional()
|
|
86
99
|
});
|
|
87
100
|
var InstrumentationConfigSchema = zod.z.object({
|
|
88
101
|
version: zod.z.string(),
|
|
@@ -693,15 +706,6 @@ var getServiceInfoWithFallback = detectServiceInfo.pipe(
|
|
|
693
706
|
})
|
|
694
707
|
)
|
|
695
708
|
);
|
|
696
|
-
async function detectServiceInfoAsync() {
|
|
697
|
-
return effect.Effect.runPromise(getServiceInfoWithFallback);
|
|
698
|
-
}
|
|
699
|
-
async function getServiceNameAsync() {
|
|
700
|
-
return effect.Effect.runPromise(getServiceName);
|
|
701
|
-
}
|
|
702
|
-
async function getServiceVersionAsync() {
|
|
703
|
-
return effect.Effect.runPromise(getServiceVersion);
|
|
704
|
-
}
|
|
705
709
|
var NodeConfigLoaderLive = ConfigLoaderLive.pipe(
|
|
706
710
|
effect.Layer.provide(effect.Layer.mergeAll(platformNode.NodeContext.layer, platform.FetchHttpClient.layer))
|
|
707
711
|
);
|
|
@@ -783,7 +787,7 @@ async function loadConfigWithOptions(options = {}) {
|
|
|
783
787
|
|
|
784
788
|
// src/core/sdk-initializer.ts
|
|
785
789
|
var sdkInstance = null;
|
|
786
|
-
var
|
|
790
|
+
var initializationDeferred = null;
|
|
787
791
|
function buildHttpInstrumentationConfig(options, config, _otlpEndpoint) {
|
|
788
792
|
const httpConfig = { enabled: true };
|
|
789
793
|
const programmaticPatterns = options.http?.ignoreOutgoingUrls || [];
|
|
@@ -899,27 +903,38 @@ function isTracingAlreadyInitialized() {
|
|
|
899
903
|
return false;
|
|
900
904
|
}
|
|
901
905
|
}
|
|
902
|
-
|
|
906
|
+
var initializeSdkEffect = (options = {}) => effect.Effect.gen(function* () {
|
|
903
907
|
if (sdkInstance) {
|
|
904
908
|
logger.warn("@atrim/instrumentation: SDK already initialized. Returning existing instance.");
|
|
905
909
|
return sdkInstance;
|
|
906
910
|
}
|
|
907
|
-
if (
|
|
911
|
+
if (initializationDeferred) {
|
|
908
912
|
logger.log(
|
|
909
|
-
"@atrim/instrumentation: SDK
|
|
913
|
+
"@atrim/instrumentation: SDK initialization in progress, waiting for completion..."
|
|
910
914
|
);
|
|
911
|
-
return
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
915
|
+
return yield* effect.Deferred.await(initializationDeferred);
|
|
916
|
+
}
|
|
917
|
+
const deferred = yield* effect.Deferred.make();
|
|
918
|
+
initializationDeferred = deferred;
|
|
919
|
+
const result = yield* performInitializationEffect(options).pipe(
|
|
920
|
+
effect.Effect.tap((sdk) => effect.Deferred.succeed(deferred, sdk)),
|
|
921
|
+
effect.Effect.tapError((error) => effect.Deferred.fail(deferred, error)),
|
|
922
|
+
effect.Effect.ensuring(
|
|
923
|
+
effect.Effect.sync(() => {
|
|
924
|
+
initializationDeferred = null;
|
|
925
|
+
})
|
|
926
|
+
)
|
|
927
|
+
);
|
|
928
|
+
return result;
|
|
929
|
+
});
|
|
930
|
+
var performInitializationEffect = (options) => effect.Effect.gen(function* () {
|
|
931
|
+
const config = yield* effect.Effect.tryPromise({
|
|
932
|
+
try: () => loadConfigWithOptions(options),
|
|
933
|
+
catch: (error) => new InitializationError2({
|
|
934
|
+
reason: "Failed to load configuration",
|
|
935
|
+
cause: error
|
|
936
|
+
})
|
|
937
|
+
});
|
|
923
938
|
const loggingLevel = config.instrumentation.logging || "on";
|
|
924
939
|
logger.setLevel(loggingLevel);
|
|
925
940
|
const alreadyInitialized = isTracingAlreadyInitialized();
|
|
@@ -935,14 +950,25 @@ async function performInitialization(options) {
|
|
|
935
950
|
logger.log("");
|
|
936
951
|
return null;
|
|
937
952
|
}
|
|
938
|
-
const serviceInfo =
|
|
953
|
+
const serviceInfo = yield* detectServiceInfo.pipe(
|
|
954
|
+
effect.Effect.catchAll(
|
|
955
|
+
() => effect.Effect.succeed({
|
|
956
|
+
name: "unknown-service",
|
|
957
|
+
version: void 0
|
|
958
|
+
})
|
|
959
|
+
)
|
|
960
|
+
);
|
|
939
961
|
const serviceName = options.serviceName || serviceInfo.name;
|
|
940
962
|
const serviceVersion = options.serviceVersion || serviceInfo.version;
|
|
941
|
-
const rawExporter = createOtlpExporter(options.otlp);
|
|
942
|
-
const exporter = new SafeSpanExporter(rawExporter);
|
|
963
|
+
const rawExporter = yield* effect.Effect.sync(() => createOtlpExporter(options.otlp));
|
|
964
|
+
const exporter = yield* effect.Effect.sync(() => new SafeSpanExporter(rawExporter));
|
|
943
965
|
const useSimpleProcessor = process.env.NODE_ENV === "test" || process.env.OTEL_USE_SIMPLE_PROCESSOR === "true";
|
|
944
|
-
const baseProcessor =
|
|
945
|
-
|
|
966
|
+
const baseProcessor = yield* effect.Effect.sync(
|
|
967
|
+
() => useSimpleProcessor ? new sdkTraceBase.SimpleSpanProcessor(exporter) : new sdkTraceBase.BatchSpanProcessor(exporter)
|
|
968
|
+
);
|
|
969
|
+
const patternProcessor = yield* effect.Effect.sync(
|
|
970
|
+
() => new PatternSpanProcessor(config, baseProcessor)
|
|
971
|
+
);
|
|
946
972
|
const instrumentations = [];
|
|
947
973
|
const hasWebFramework = hasWebFrameworkInstalled();
|
|
948
974
|
const enableAutoInstrumentation = shouldEnableAutoInstrumentation(
|
|
@@ -955,15 +981,11 @@ async function performInitialization(options) {
|
|
|
955
981
|
const undiciConfig = buildUndiciInstrumentationConfig(options, config);
|
|
956
982
|
instrumentations.push(
|
|
957
983
|
...autoInstrumentationsNode.getNodeAutoInstrumentations({
|
|
958
|
-
// Enable HTTP instrumentation with filtering (for http/https modules)
|
|
959
984
|
"@opentelemetry/instrumentation-http": httpConfig,
|
|
960
|
-
// Enable undici instrumentation with filtering (for fetch API)
|
|
961
985
|
"@opentelemetry/instrumentation-undici": undiciConfig,
|
|
962
|
-
// Enable web framework instrumentations
|
|
963
986
|
"@opentelemetry/instrumentation-express": { enabled: true },
|
|
964
987
|
"@opentelemetry/instrumentation-fastify": { enabled: true },
|
|
965
988
|
"@opentelemetry/instrumentation-koa": { enabled: true },
|
|
966
|
-
// Disable noisy instrumentations by default
|
|
967
989
|
"@opentelemetry/instrumentation-fs": { enabled: false },
|
|
968
990
|
"@opentelemetry/instrumentation-dns": { enabled: false }
|
|
969
991
|
})
|
|
@@ -991,18 +1013,20 @@ async function performInitialization(options) {
|
|
|
991
1013
|
serviceName,
|
|
992
1014
|
...serviceVersion && { serviceVersion },
|
|
993
1015
|
instrumentations,
|
|
994
|
-
// Allow advanced overrides
|
|
995
1016
|
...options.sdk
|
|
996
1017
|
};
|
|
997
|
-
const sdk =
|
|
998
|
-
|
|
1018
|
+
const sdk = yield* effect.Effect.sync(() => {
|
|
1019
|
+
const s = new sdkNode.NodeSDK(sdkConfig);
|
|
1020
|
+
s.start();
|
|
1021
|
+
return s;
|
|
1022
|
+
});
|
|
999
1023
|
sdkInstance = sdk;
|
|
1000
1024
|
if (!options.disableAutoShutdown) {
|
|
1001
|
-
registerShutdownHandlers(sdk);
|
|
1025
|
+
yield* effect.Effect.sync(() => registerShutdownHandlers(sdk));
|
|
1002
1026
|
}
|
|
1003
1027
|
logInitialization(config, serviceName, serviceVersion, options, enableAutoInstrumentation);
|
|
1004
1028
|
return sdk;
|
|
1005
|
-
}
|
|
1029
|
+
});
|
|
1006
1030
|
function getSdkInstance() {
|
|
1007
1031
|
return sdkInstance;
|
|
1008
1032
|
}
|
|
@@ -1015,7 +1039,7 @@ async function shutdownSdk() {
|
|
|
1015
1039
|
}
|
|
1016
1040
|
function resetSdk() {
|
|
1017
1041
|
sdkInstance = null;
|
|
1018
|
-
|
|
1042
|
+
initializationDeferred = null;
|
|
1019
1043
|
}
|
|
1020
1044
|
function registerShutdownHandlers(sdk) {
|
|
1021
1045
|
const shutdown = async (signal) => {
|
|
@@ -1072,30 +1096,8 @@ function logInitialization(config, serviceName, serviceVersion, options, autoIns
|
|
|
1072
1096
|
}
|
|
1073
1097
|
|
|
1074
1098
|
// src/api.ts
|
|
1075
|
-
|
|
1076
|
-
const sdk =
|
|
1077
|
-
if (sdk) {
|
|
1078
|
-
const config = await loadConfigWithOptions(options);
|
|
1079
|
-
initializePatternMatcher(config);
|
|
1080
|
-
}
|
|
1081
|
-
return sdk;
|
|
1082
|
-
}
|
|
1083
|
-
async function initializePatternMatchingOnly(options = {}) {
|
|
1084
|
-
const config = await loadConfigWithOptions(options);
|
|
1085
|
-
initializePatternMatcher(config);
|
|
1086
|
-
logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
|
|
1087
|
-
logger.log(
|
|
1088
|
-
" Note: NodeSDK is not initialized. Use initializeInstrumentation() for complete setup."
|
|
1089
|
-
);
|
|
1090
|
-
}
|
|
1091
|
-
var initializeInstrumentationEffect = (options = {}) => effect.Effect.gen(function* () {
|
|
1092
|
-
const sdk = yield* effect.Effect.tryPromise({
|
|
1093
|
-
try: () => initializeSdk(options),
|
|
1094
|
-
catch: (error) => new InitializationError2({
|
|
1095
|
-
reason: "SDK initialization failed",
|
|
1096
|
-
cause: error
|
|
1097
|
-
})
|
|
1098
|
-
});
|
|
1099
|
+
var initializeInstrumentation = (options = {}) => effect.Effect.gen(function* () {
|
|
1100
|
+
const sdk = yield* initializeSdkEffect(options);
|
|
1099
1101
|
if (sdk) {
|
|
1100
1102
|
yield* effect.Effect.tryPromise({
|
|
1101
1103
|
try: () => loadConfigWithOptions(options),
|
|
@@ -1113,7 +1115,7 @@ var initializeInstrumentationEffect = (options = {}) => effect.Effect.gen(functi
|
|
|
1113
1115
|
}
|
|
1114
1116
|
return sdk;
|
|
1115
1117
|
});
|
|
1116
|
-
var
|
|
1118
|
+
var initializePatternMatchingOnly = (options = {}) => effect.Effect.gen(function* () {
|
|
1117
1119
|
const config = yield* effect.Effect.tryPromise({
|
|
1118
1120
|
try: () => loadConfigWithOptions(options),
|
|
1119
1121
|
catch: (error) => new ConfigError2({
|
|
@@ -1123,7 +1125,7 @@ var initializePatternMatchingOnlyEffect = (options = {}) => effect.Effect.gen(fu
|
|
|
1123
1125
|
});
|
|
1124
1126
|
yield* effect.Effect.sync(() => {
|
|
1125
1127
|
initializePatternMatcher(config);
|
|
1126
|
-
logger.log("@atrim/instrumentation: Pattern matching initialized (
|
|
1128
|
+
logger.log("@atrim/instrumentation: Pattern matching initialized (pattern-only mode)");
|
|
1127
1129
|
logger.log(
|
|
1128
1130
|
" Note: NodeSDK is not initialized. Use initializeInstrumentation() for complete setup."
|
|
1129
1131
|
);
|
|
@@ -1239,20 +1241,15 @@ exports.annotateDbQuery = annotateDbQuery;
|
|
|
1239
1241
|
exports.annotateHttpRequest = annotateHttpRequest;
|
|
1240
1242
|
exports.clearConfigCache = _resetConfigLoaderCache;
|
|
1241
1243
|
exports.createOtlpExporter = createOtlpExporter;
|
|
1242
|
-
exports.detectServiceInfo =
|
|
1243
|
-
exports.detectServiceInfoEffect = detectServiceInfo;
|
|
1244
|
+
exports.detectServiceInfo = detectServiceInfo;
|
|
1244
1245
|
exports.getOtlpEndpoint = getOtlpEndpoint;
|
|
1245
1246
|
exports.getPatternMatcher = getPatternMatcher;
|
|
1246
1247
|
exports.getSdkInstance = getSdkInstance;
|
|
1247
1248
|
exports.getServiceInfoWithFallback = getServiceInfoWithFallback;
|
|
1248
|
-
exports.getServiceName =
|
|
1249
|
-
exports.
|
|
1250
|
-
exports.getServiceVersion = getServiceVersionAsync;
|
|
1251
|
-
exports.getServiceVersionEffect = getServiceVersion;
|
|
1249
|
+
exports.getServiceName = getServiceName;
|
|
1250
|
+
exports.getServiceVersion = getServiceVersion;
|
|
1252
1251
|
exports.initializeInstrumentation = initializeInstrumentation;
|
|
1253
|
-
exports.initializeInstrumentationEffect = initializeInstrumentationEffect;
|
|
1254
1252
|
exports.initializePatternMatchingOnly = initializePatternMatchingOnly;
|
|
1255
|
-
exports.initializePatternMatchingOnlyEffect = initializePatternMatchingOnlyEffect;
|
|
1256
1253
|
exports.loadConfig = loadConfig;
|
|
1257
1254
|
exports.loadConfigFromInline = loadConfigFromInline;
|
|
1258
1255
|
exports.loadConfigWithOptions = loadConfigWithOptions;
|