UNPKG

@sentry/node

Version:

Sentry Node SDK using OpenTelemetry for performance instrumentation

112 lines (109 loc) 4.39 kB
import { trace, propagation, context } from '@opentelemetry/api'; import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { debug, hasSpanStreamingEnabled } from '@sentry/core'; import { setupOpenTelemetryLogger, SentryContextManager, initializeEsmLoader } from '@sentry/node-core'; import { SentrySpanProcessor, SentrySampler, getSentryResource, SentryPropagator, SentryTracerProvider, setIsSetup, applyOtelSpanData, backfillStreamedSpanDataFromOtel } from '@sentry/opentelemetry'; import { DEBUG_BUILD } from '../debug-build.js'; import { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing/index.js'; const MAX_MAX_SPAN_WAIT_DURATION = 1e6; function initOpenTelemetry(client, options = {}) { if (client.getOptions().debug) { setupOpenTelemetryLogger(); } const [provider, asyncLocalStorageLookup] = setupOtel(client, options); client.traceProvider = provider; client.asyncLocalStorageLookup = asyncLocalStorageLookup; } function preloadOpenTelemetry(options = {}) { const { debug: debug$1 } = options; if (debug$1) { debug.enable(); } initializeEsmLoader(); getPreloadMethods(options.integrations).forEach((fn) => { fn(); if (debug$1) { debug.log(`[Sentry] Preloaded ${fn.id} instrumentation`); } }); } function getPreloadMethods(integrationNames) { const instruments = getOpenTelemetryInstrumentationToPreload(); if (!integrationNames) { return instruments; } return instruments.filter((instrumentation) => { const id = instrumentation.id; return integrationNames.some((integrationName) => id === integrationName || id.startsWith(`${integrationName}.`)); }); } function setupOtel(client, options = {}) { const shouldUseBasicTracerProvider = client.getOptions().openTelemetryBasicTracerProvider || !!options.spanProcessors?.length; if (!shouldUseBasicTracerProvider) { return setupSentryTracerProvider(client); } const provider = new BasicTracerProvider({ sampler: new SentrySampler(client), resource: getSentryResource("node"), forceFlushTimeoutMillis: 500, spanProcessors: [ new SentrySpanProcessor({ timeout: _clampSpanProcessorTimeout(client.getOptions().maxSpanWaitDuration), client }), ...options.spanProcessors || [] ] }); trace.setGlobalTracerProvider(provider); propagation.setGlobalPropagator(new SentryPropagator()); const ctxManager = new SentryContextManager(); context.setGlobalContextManager(ctxManager); return [provider, ctxManager.getAsyncLocalStorageLookup()]; } function setupSentryTracerProvider(client) { const provider = new SentryTracerProvider({ resource: getSentryResource("node") }); if (!trace.setGlobalTracerProvider(provider)) { DEBUG_BUILD && debug.warn( "Could not register SentryTracerProvider because another OpenTelemetry tracer provider is already registered." ); return [void 0, void 0]; } setIsSetup("SentryTracerProvider"); propagation.setGlobalPropagator(new SentryPropagator()); const ctxManager = new SentryContextManager(); context.setGlobalContextManager(ctxManager); client.on("spanEnd", (span) => { applyOtelSpanData(span, { finalizeStatus: true }); }); if (hasSpanStreamingEnabled(client)) { client.on("preprocessSpan", backfillStreamedSpanDataFromOtel); } client.on("preprocessEvent", (event) => { if (event.type !== "transaction") { return; } event.contexts = { ...event.contexts, otel: { resource: provider.resource?.attributes, ...event.contexts?.otel } }; }); return [provider, ctxManager.getAsyncLocalStorageLookup()]; } function _clampSpanProcessorTimeout(maxSpanWaitDuration) { if (maxSpanWaitDuration == null) { return void 0; } if (maxSpanWaitDuration > MAX_MAX_SPAN_WAIT_DURATION) { DEBUG_BUILD && debug.warn(`\`maxSpanWaitDuration\` is too high, using the maximum value of ${MAX_MAX_SPAN_WAIT_DURATION}`); return MAX_MAX_SPAN_WAIT_DURATION; } else if (maxSpanWaitDuration <= 0 || Number.isNaN(maxSpanWaitDuration)) { DEBUG_BUILD && debug.warn("`maxSpanWaitDuration` must be a positive number, using default value instead."); return void 0; } return maxSpanWaitDuration; } export { _clampSpanProcessorTimeout, initOpenTelemetry, preloadOpenTelemetry, setupOtel }; //# sourceMappingURL=initOtel.js.map