@atrim/instrument-node 0.5.0-c05e3a1-20251119131235 → 0.5.0

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.
@@ -1,4 +1,4 @@
1
- import { Data, Context, Effect, Layer, Deferred } from 'effect';
1
+ import { Data, Context, Effect, Layer } from 'effect';
2
2
  import { NodeSDK } from '@opentelemetry/sdk-node';
3
3
  import { SimpleSpanProcessor, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
4
4
  import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
@@ -59,20 +59,7 @@ var HttpFilteringConfigSchema = z.object({
59
59
  // Patterns to ignore for incoming HTTP requests (string patterns only in YAML)
60
60
  ignore_incoming_paths: z.array(z.string()).optional(),
61
61
  // Require parent span for outgoing requests (prevents root spans for HTTP calls)
62
- require_parent_for_outgoing_spans: z.boolean().optional(),
63
- // Trace context propagation configuration
64
- // Controls which cross-origin requests receive W3C Trace Context headers (traceparent, tracestate)
65
- propagate_trace_context: z.object({
66
- // Strategy for trace propagation
67
- // - "all": Propagate to all cross-origin requests (may cause CORS errors)
68
- // - "none": Never propagate trace headers
69
- // - "same-origin": Only propagate to same-origin requests (default, safe)
70
- // - "patterns": Propagate based on include_urls patterns
71
- strategy: z.enum(["all", "none", "same-origin", "patterns"]).default("same-origin"),
72
- // URL patterns to include when strategy is "patterns"
73
- // Supports regex patterns (e.g., "^https://api\\.myapp\\.com")
74
- include_urls: z.array(z.string()).optional()
75
- }).optional()
62
+ require_parent_for_outgoing_spans: z.boolean().optional()
76
63
  });
77
64
  var InstrumentationConfigSchema = z.object({
78
65
  version: z.string(),
@@ -683,6 +670,15 @@ var getServiceInfoWithFallback = detectServiceInfo.pipe(
683
670
  })
684
671
  )
685
672
  );
673
+ async function detectServiceInfoAsync() {
674
+ return Effect.runPromise(getServiceInfoWithFallback);
675
+ }
676
+ async function getServiceNameAsync() {
677
+ return Effect.runPromise(getServiceName);
678
+ }
679
+ async function getServiceVersionAsync() {
680
+ return Effect.runPromise(getServiceVersion);
681
+ }
686
682
  var NodeConfigLoaderLive = ConfigLoaderLive.pipe(
687
683
  Layer.provide(Layer.mergeAll(NodeContext.layer, FetchHttpClient.layer))
688
684
  );
@@ -764,7 +760,7 @@ async function loadConfigWithOptions(options = {}) {
764
760
 
765
761
  // src/core/sdk-initializer.ts
766
762
  var sdkInstance = null;
767
- var initializationDeferred = null;
763
+ var initializationPromise = null;
768
764
  function buildHttpInstrumentationConfig(options, config, _otlpEndpoint) {
769
765
  const httpConfig = { enabled: true };
770
766
  const programmaticPatterns = options.http?.ignoreOutgoingUrls || [];
@@ -880,38 +876,27 @@ function isTracingAlreadyInitialized() {
880
876
  return false;
881
877
  }
882
878
  }
883
- var initializeSdkEffect = (options = {}) => Effect.gen(function* () {
879
+ async function initializeSdk(options = {}) {
884
880
  if (sdkInstance) {
885
881
  logger.warn("@atrim/instrumentation: SDK already initialized. Returning existing instance.");
886
882
  return sdkInstance;
887
883
  }
888
- if (initializationDeferred) {
884
+ if (initializationPromise) {
889
885
  logger.log(
890
- "@atrim/instrumentation: SDK initialization in progress, waiting for completion..."
886
+ "@atrim/instrumentation: SDK already initialized, waiting for initialization to complete..."
891
887
  );
892
- return yield* Deferred.await(initializationDeferred);
893
- }
894
- const deferred = yield* Deferred.make();
895
- initializationDeferred = deferred;
896
- const result = yield* performInitializationEffect(options).pipe(
897
- Effect.tap((sdk) => Deferred.succeed(deferred, sdk)),
898
- Effect.tapError((error) => Deferred.fail(deferred, error)),
899
- Effect.ensuring(
900
- Effect.sync(() => {
901
- initializationDeferred = null;
902
- })
903
- )
904
- );
905
- return result;
906
- });
907
- var performInitializationEffect = (options) => Effect.gen(function* () {
908
- const config = yield* Effect.tryPromise({
909
- try: () => loadConfigWithOptions(options),
910
- catch: (error) => new InitializationError2({
911
- reason: "Failed to load configuration",
912
- cause: error
913
- })
914
- });
888
+ return initializationPromise;
889
+ }
890
+ initializationPromise = performInitialization(options);
891
+ try {
892
+ const result = await initializationPromise;
893
+ return result;
894
+ } finally {
895
+ initializationPromise = null;
896
+ }
897
+ }
898
+ async function performInitialization(options) {
899
+ const config = await loadConfigWithOptions(options);
915
900
  const loggingLevel = config.instrumentation.logging || "on";
916
901
  logger.setLevel(loggingLevel);
917
902
  const alreadyInitialized = isTracingAlreadyInitialized();
@@ -927,25 +912,14 @@ var performInitializationEffect = (options) => Effect.gen(function* () {
927
912
  logger.log("");
928
913
  return null;
929
914
  }
930
- const serviceInfo = yield* detectServiceInfo.pipe(
931
- Effect.catchAll(
932
- () => Effect.succeed({
933
- name: "unknown-service",
934
- version: void 0
935
- })
936
- )
937
- );
915
+ const serviceInfo = await detectServiceInfoAsync();
938
916
  const serviceName = options.serviceName || serviceInfo.name;
939
917
  const serviceVersion = options.serviceVersion || serviceInfo.version;
940
- const rawExporter = yield* Effect.sync(() => createOtlpExporter(options.otlp));
941
- const exporter = yield* Effect.sync(() => new SafeSpanExporter(rawExporter));
918
+ const rawExporter = createOtlpExporter(options.otlp);
919
+ const exporter = new SafeSpanExporter(rawExporter);
942
920
  const useSimpleProcessor = process.env.NODE_ENV === "test" || process.env.OTEL_USE_SIMPLE_PROCESSOR === "true";
943
- const baseProcessor = yield* Effect.sync(
944
- () => useSimpleProcessor ? new SimpleSpanProcessor(exporter) : new BatchSpanProcessor(exporter)
945
- );
946
- const patternProcessor = yield* Effect.sync(
947
- () => new PatternSpanProcessor(config, baseProcessor)
948
- );
921
+ const baseProcessor = useSimpleProcessor ? new SimpleSpanProcessor(exporter) : new BatchSpanProcessor(exporter);
922
+ const patternProcessor = new PatternSpanProcessor(config, baseProcessor);
949
923
  const instrumentations = [];
950
924
  const hasWebFramework = hasWebFrameworkInstalled();
951
925
  const enableAutoInstrumentation = shouldEnableAutoInstrumentation(
@@ -958,11 +932,15 @@ var performInitializationEffect = (options) => Effect.gen(function* () {
958
932
  const undiciConfig = buildUndiciInstrumentationConfig(options, config);
959
933
  instrumentations.push(
960
934
  ...getNodeAutoInstrumentations({
935
+ // Enable HTTP instrumentation with filtering (for http/https modules)
961
936
  "@opentelemetry/instrumentation-http": httpConfig,
937
+ // Enable undici instrumentation with filtering (for fetch API)
962
938
  "@opentelemetry/instrumentation-undici": undiciConfig,
939
+ // Enable web framework instrumentations
963
940
  "@opentelemetry/instrumentation-express": { enabled: true },
964
941
  "@opentelemetry/instrumentation-fastify": { enabled: true },
965
942
  "@opentelemetry/instrumentation-koa": { enabled: true },
943
+ // Disable noisy instrumentations by default
966
944
  "@opentelemetry/instrumentation-fs": { enabled: false },
967
945
  "@opentelemetry/instrumentation-dns": { enabled: false }
968
946
  })
@@ -990,20 +968,18 @@ var performInitializationEffect = (options) => Effect.gen(function* () {
990
968
  serviceName,
991
969
  ...serviceVersion && { serviceVersion },
992
970
  instrumentations,
971
+ // Allow advanced overrides
993
972
  ...options.sdk
994
973
  };
995
- const sdk = yield* Effect.sync(() => {
996
- const s = new NodeSDK(sdkConfig);
997
- s.start();
998
- return s;
999
- });
974
+ const sdk = new NodeSDK(sdkConfig);
975
+ sdk.start();
1000
976
  sdkInstance = sdk;
1001
977
  if (!options.disableAutoShutdown) {
1002
- yield* Effect.sync(() => registerShutdownHandlers(sdk));
978
+ registerShutdownHandlers(sdk);
1003
979
  }
1004
980
  logInitialization(config, serviceName, serviceVersion, options, enableAutoInstrumentation);
1005
981
  return sdk;
1006
- });
982
+ }
1007
983
  function getSdkInstance() {
1008
984
  return sdkInstance;
1009
985
  }
@@ -1016,7 +992,7 @@ async function shutdownSdk() {
1016
992
  }
1017
993
  function resetSdk() {
1018
994
  sdkInstance = null;
1019
- initializationDeferred = null;
995
+ initializationPromise = null;
1020
996
  }
1021
997
  function registerShutdownHandlers(sdk) {
1022
998
  const shutdown = async (signal) => {
@@ -1073,8 +1049,30 @@ function logInitialization(config, serviceName, serviceVersion, options, autoIns
1073
1049
  }
1074
1050
 
1075
1051
  // src/api.ts
1076
- var initializeInstrumentation = (options = {}) => Effect.gen(function* () {
1077
- const sdk = yield* initializeSdkEffect(options);
1052
+ async function initializeInstrumentation(options = {}) {
1053
+ const sdk = await initializeSdk(options);
1054
+ if (sdk) {
1055
+ const config = await loadConfigWithOptions(options);
1056
+ initializePatternMatcher(config);
1057
+ }
1058
+ return sdk;
1059
+ }
1060
+ async function initializePatternMatchingOnly(options = {}) {
1061
+ const config = await loadConfigWithOptions(options);
1062
+ initializePatternMatcher(config);
1063
+ logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
1064
+ logger.log(
1065
+ " Note: NodeSDK is not initialized. Use initializeInstrumentation() for complete setup."
1066
+ );
1067
+ }
1068
+ var initializeInstrumentationEffect = (options = {}) => Effect.gen(function* () {
1069
+ const sdk = yield* Effect.tryPromise({
1070
+ try: () => initializeSdk(options),
1071
+ catch: (error) => new InitializationError2({
1072
+ reason: "SDK initialization failed",
1073
+ cause: error
1074
+ })
1075
+ });
1078
1076
  if (sdk) {
1079
1077
  yield* Effect.tryPromise({
1080
1078
  try: () => loadConfigWithOptions(options),
@@ -1092,7 +1090,7 @@ var initializeInstrumentation = (options = {}) => Effect.gen(function* () {
1092
1090
  }
1093
1091
  return sdk;
1094
1092
  });
1095
- var initializePatternMatchingOnly = (options = {}) => Effect.gen(function* () {
1093
+ var initializePatternMatchingOnlyEffect = (options = {}) => Effect.gen(function* () {
1096
1094
  const config = yield* Effect.tryPromise({
1097
1095
  try: () => loadConfigWithOptions(options),
1098
1096
  catch: (error) => new ConfigError2({
@@ -1102,7 +1100,7 @@ var initializePatternMatchingOnly = (options = {}) => Effect.gen(function* () {
1102
1100
  });
1103
1101
  yield* Effect.sync(() => {
1104
1102
  initializePatternMatcher(config);
1105
- logger.log("@atrim/instrumentation: Pattern matching initialized (pattern-only mode)");
1103
+ logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
1106
1104
  logger.log(
1107
1105
  " Note: NodeSDK is not initialized. Use initializeInstrumentation() for complete setup."
1108
1106
  );
@@ -1203,6 +1201,6 @@ function suppressShutdownErrors() {
1203
1201
  });
1204
1202
  }
1205
1203
 
1206
- export { ConfigError2 as ConfigError, ConfigFileError2 as ConfigFileError, ConfigUrlError2 as ConfigUrlError, ConfigValidationError2 as ConfigValidationError, ExportError2 as ExportError, InitializationError2 as InitializationError, PatternMatcher, PatternSpanProcessor, ServiceDetectionError2 as ServiceDetectionError, ShutdownError2 as ShutdownError, annotateCacheOperation, annotateDbQuery, annotateHttpRequest, _resetConfigLoaderCache as clearConfigCache, createOtlpExporter, detectServiceInfo, getOtlpEndpoint, getPatternMatcher, getSdkInstance, getServiceInfoWithFallback, getServiceName, getServiceVersion, initializeInstrumentation, initializePatternMatchingOnly, loadConfig, loadConfigFromInline, loadConfigWithOptions, markSpanError, markSpanSuccess, recordException, resetSdk, setSpanAttributes, shouldInstrumentSpan, shutdownSdk, suppressShutdownErrors };
1204
+ export { ConfigError2 as ConfigError, ConfigFileError2 as ConfigFileError, ConfigUrlError2 as ConfigUrlError, ConfigValidationError2 as ConfigValidationError, ExportError2 as ExportError, InitializationError2 as InitializationError, PatternMatcher, PatternSpanProcessor, ServiceDetectionError2 as ServiceDetectionError, ShutdownError2 as ShutdownError, annotateCacheOperation, annotateDbQuery, annotateHttpRequest, _resetConfigLoaderCache as clearConfigCache, createOtlpExporter, detectServiceInfoAsync as detectServiceInfo, detectServiceInfo as detectServiceInfoEffect, getOtlpEndpoint, getPatternMatcher, getSdkInstance, getServiceInfoWithFallback, getServiceNameAsync as getServiceName, getServiceName as getServiceNameEffect, getServiceVersionAsync as getServiceVersion, getServiceVersion as getServiceVersionEffect, initializeInstrumentation, initializeInstrumentationEffect, initializePatternMatchingOnly, initializePatternMatchingOnlyEffect, loadConfig, loadConfigFromInline, loadConfigWithOptions, markSpanError, markSpanSuccess, recordException, resetSdk, setSpanAttributes, shouldInstrumentSpan, shutdownSdk, suppressShutdownErrors };
1207
1205
  //# sourceMappingURL=index.js.map
1208
1206
  //# sourceMappingURL=index.js.map