{"version":3,"file":"initOtel.js","sources":["../../../src/sdk/initOtel.ts"],"sourcesContent":["import { context, propagation, trace } from '@opentelemetry/api';\nimport { defaultResource, resourceFromAttributes } from '@opentelemetry/resources';\nimport type { SpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { BasicTracerProvider } from '@opentelemetry/sdk-trace-base';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n SEMRESATTRS_SERVICE_NAMESPACE,\n} from '@opentelemetry/semantic-conventions';\nimport { debug as coreDebug, SDK_VERSION } from '@sentry/core';\nimport {\n initializeEsmLoader,\n type NodeClient,\n SentryContextManager,\n setupOpenTelemetryLogger,\n} from '@sentry/node-core';\nimport {\n type AsyncLocalStorageLookup,\n SentryPropagator,\n SentrySampler,\n SentrySpanProcessor,\n} from '@sentry/opentelemetry';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing';\n\n// About 277h - this must fit into new Array(len)!\nconst MAX_MAX_SPAN_WAIT_DURATION = 1_000_000;\n\ninterface AdditionalOpenTelemetryOptions {\n /** Additional SpanProcessor instances that should be used. */\n spanProcessors?: SpanProcessor[];\n}\n\n/**\n * Initialize OpenTelemetry for Node.\n */\nexport function initOpenTelemetry(client: NodeClient, options: AdditionalOpenTelemetryOptions = {}): void {\n if (client.getOptions().debug) {\n setupOpenTelemetryLogger();\n }\n\n const [provider, asyncLocalStorageLookup] = setupOtel(client, options);\n client.traceProvider = provider;\n client.asyncLocalStorageLookup = asyncLocalStorageLookup;\n}\n\ninterface NodePreloadOptions {\n debug?: boolean;\n integrations?: string[];\n}\n\n/**\n * Preload OpenTelemetry for Node.\n * This can be used to preload instrumentation early, but set up Sentry later.\n * By preloading the OTEL instrumentation wrapping still happens early enough that everything works.\n */\nexport function preloadOpenTelemetry(options: NodePreloadOptions = {}): void {\n const { debug } = options;\n\n if (debug) {\n coreDebug.enable();\n }\n\n initializeEsmLoader();\n\n // These are all integrations that we need to pre-load to ensure they are set up before any other code runs\n getPreloadMethods(options.integrations).forEach(fn => {\n fn();\n\n if (debug) {\n coreDebug.log(`[Sentry] Preloaded ${fn.id} instrumentation`);\n }\n });\n}\n\nfunction getPreloadMethods(integrationNames?: string[]): ((() => void) & { id: string })[] {\n const instruments = getOpenTelemetryInstrumentationToPreload();\n\n if (!integrationNames) {\n return instruments;\n }\n\n // We match exact matches of instrumentation, but also match prefixes, e.g. \"Fastify.v5\" will match \"Fastify\"\n return instruments.filter(instrumentation => {\n const id = instrumentation.id;\n return integrationNames.some(integrationName => id === integrationName || id.startsWith(`${integrationName}.`));\n });\n}\n\n/** Just exported for tests. */\nexport function setupOtel(\n client: NodeClient,\n options: AdditionalOpenTelemetryOptions = {},\n): [BasicTracerProvider, AsyncLocalStorageLookup] {\n // Create and configure NodeTracerProvider\n const provider = new BasicTracerProvider({\n sampler: new SentrySampler(client),\n resource: defaultResource().merge(\n resourceFromAttributes({\n [ATTR_SERVICE_NAME]: 'node',\n // eslint-disable-next-line deprecation/deprecation\n [SEMRESATTRS_SERVICE_NAMESPACE]: 'sentry',\n [ATTR_SERVICE_VERSION]: SDK_VERSION,\n }),\n ),\n forceFlushTimeoutMillis: 500,\n spanProcessors: [\n new SentrySpanProcessor({\n timeout: _clampSpanProcessorTimeout(client.getOptions().maxSpanWaitDuration),\n }),\n ...(options.spanProcessors || []),\n ],\n });\n\n // Register as globals\n trace.setGlobalTracerProvider(provider);\n propagation.setGlobalPropagator(new SentryPropagator());\n\n const ctxManager = new SentryContextManager();\n context.setGlobalContextManager(ctxManager);\n\n return [provider, ctxManager.getAsyncLocalStorageLookup()];\n}\n\n/** Just exported for tests. */\nexport function _clampSpanProcessorTimeout(maxSpanWaitDuration: number | undefined): number | undefined {\n if (maxSpanWaitDuration == null) {\n return undefined;\n }\n\n // We guard for a max. value here, because we create an array with this length\n // So if this value is too large, this would fail\n if (maxSpanWaitDuration > MAX_MAX_SPAN_WAIT_DURATION) {\n DEBUG_BUILD &&\n coreDebug.warn(`\\`maxSpanWaitDuration\\` is too high, using the maximum value of ${MAX_MAX_SPAN_WAIT_DURATION}`);\n return MAX_MAX_SPAN_WAIT_DURATION;\n } else if (maxSpanWaitDuration <= 0 || Number.isNaN(maxSpanWaitDuration)) {\n DEBUG_BUILD && coreDebug.warn('`maxSpanWaitDuration` must be a positive number, using default value instead.');\n return undefined;\n }\n\n return maxSpanWaitDuration;\n}\n"],"names":["debug","coreDebug"],"mappings":";;;;;;;;;;AAyBA;AACA,MAAM,0BAAA,GAA6B,OAAS;;AAO5C;AACA;AACA;AACO,SAAS,iBAAiB,CAAC,MAAM,EAAc,OAAO,GAAmC,EAAE,EAAQ;AAC1G,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE;AACjC,IAAI,wBAAwB,EAAE;AAC9B,EAAE;;AAEF,EAAE,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAA,GAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;AACxE,EAAE,MAAM,CAAC,aAAA,GAAgB,QAAQ;AACjC,EAAE,MAAM,CAAC,uBAAA,GAA0B,uBAAuB;AAC1D;;AAOA;AACA;AACA;AACA;AACA;AACO,SAAS,oBAAoB,CAAC,OAAO,GAAuB,EAAE,EAAQ;AAC7E,EAAE,MAAM,SAAEA,OAAA,EAAM,GAAI,OAAO;;AAE3B,EAAE,IAAIA,OAAK,EAAE;AACb,IAAIC,KAAS,CAAC,MAAM,EAAE;AACtB,EAAE;;AAEF,EAAE,mBAAmB,EAAE;;AAEvB;AACA,EAAE,iBAAiB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAA,IAAM;AACxD,IAAI,EAAE,EAAE;;AAER,IAAI,IAAID,OAAK,EAAE;AACf,MAAMC,KAAS,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAClE,IAAI;AACJ,EAAE,CAAC,CAAC;AACJ;;AAEA,SAAS,iBAAiB,CAAC,gBAAgB,EAAgD;AAC3F,EAAE,MAAM,WAAA,GAAc,wCAAwC,EAAE;;AAEhE,EAAE,IAAI,CAAC,gBAAgB,EAAE;AACzB,IAAI,OAAO,WAAW;AACtB,EAAE;;AAEF;AACA,EAAE,OAAO,WAAW,CAAC,MAAM,CAAC,mBAAmB;AAC/C,IAAI,MAAM,EAAA,GAAK,eAAe,CAAC,EAAE;AACjC,IAAI,OAAO,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,EAAA,KAAO,eAAA,IAAmB,EAAE,CAAC,UAAU,CAAC,CAAC,EAAA,eAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AACA,EAAA,CAAA,CAAA;AACA;;AAEA;AACA,SAAA,SAAA;AACA,EAAA,MAAA;AACA,EAAA,OAAA,GAAA,EAAA;AACA,EAAA;AACA;AACA,EAAA,MAAA,QAAA,GAAA,IAAA,mBAAA,CAAA;AACA,IAAA,OAAA,EAAA,IAAA,aAAA,CAAA,MAAA,CAAA;AACA,IAAA,QAAA,EAAA,eAAA,EAAA,CAAA,KAAA;AACA,MAAA,sBAAA,CAAA;AACA,QAAA,CAAA,iBAAA,GAAA,MAAA;AACA;AACA,QAAA,CAAA,6BAAA,GAAA,QAAA;AACA,QAAA,CAAA,oBAAA,GAAA,WAAA;AACA,OAAA,CAAA;AACA,KAAA;AACA,IAAA,uBAAA,EAAA,GAAA;AACA,IAAA,cAAA,EAAA;AACA,MAAA,IAAA,mBAAA,CAAA;AACA,QAAA,OAAA,EAAA,0BAAA,CAAA,MAAA,CAAA,UAAA,EAAA,CAAA,mBAAA,CAAA;AACA,OAAA,CAAA;AACA,MAAA,IAAA,OAAA,CAAA,cAAA,IAAA,EAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;;AAEA;AACA,EAAA,KAAA,CAAA,uBAAA,CAAA,QAAA,CAAA;AACA,EAAA,WAAA,CAAA,mBAAA,CAAA,IAAA,gBAAA,EAAA,CAAA;;AAEA,EAAA,MAAA,UAAA,GAAA,IAAA,oBAAA,EAAA;AACA,EAAA,OAAA,CAAA,uBAAA,CAAA,UAAA,CAAA;;AAEA,EAAA,OAAA,CAAA,QAAA,EAAA,UAAA,CAAA,0BAAA,EAAA,CAAA;AACA;;AAEA;AACA,SAAA,0BAAA,CAAA,mBAAA,EAAA;AACA,EAAA,IAAA,mBAAA,IAAA,IAAA,EAAA;AACA,IAAA,OAAA,SAAA;AACA,EAAA;;AAEA;AACA;AACA,EAAA,IAAA,mBAAA,GAAA,0BAAA,EAAA;AACA,IAAA,WAAA;AACA,MAAAA,KAAA,CAAA,IAAA,CAAA,CAAA,gEAAA,EAAA,0BAAA,CAAA,CAAA,CAAA;AACA,IAAA,OAAA,0BAAA;AACA,EAAA,CAAA,MAAA,IAAA,mBAAA,IAAA,CAAA,IAAA,MAAA,CAAA,KAAA,CAAA,mBAAA,CAAA,EAAA;AACA,IAAA,WAAA,IAAAA,KAAA,CAAA,IAAA,CAAA,+EAAA,CAAA;AACA,IAAA,OAAA,SAAA;AACA,EAAA;;AAEA,EAAA,OAAA,mBAAA;AACA;;;;"}